1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2008 Renato Araujo Oliveira Filho <renatox@gmail.com> 8 Copyright (c) 2000-2014 Torus Knot Software Ltd 9 10 Permission is hereby granted, free of charge, to any person obtaining a copy 11 of this software and associated documentation files (the "Software"), to deal 12 in the Software without restriction, including without limitation the rights 13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 copies of the Software, and to permit persons to whom the Software is 15 furnished to do so, subject to the following conditions: 16 17 The above copyright notice and this permission notice shall be included in 18 all copies or substantial portions of the Software. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 THE SOFTWARE. 27 ----------------------------------------------------------------------------- 28 */ 29 30 #include "OgreException.h" 31 #include "OgreLogManager.h" 32 #include "OgreStringConverter.h" 33 #include "OgreRoot.h" 34 35 #include "OgreX11EGLSupport.h" 36 #include "OgreX11EGLWindow.h" 37 #include "OgreX11EGLRenderTexture.h" 38 39 #include "OgreGLUtil.h" 40 41 #include <X11/extensions/Xrandr.h> 42 43 namespace Ogre { getGLSupport(int profile)44 GLNativeSupport* getGLSupport(int profile) 45 { 46 return new X11EGLSupport(profile); 47 } 48 X11EGLSupport(int profile)49 X11EGLSupport::X11EGLSupport(int profile) : EGLSupport(profile) 50 { 51 // A connection that might be shared with the application for GL rendering: 52 mGLDisplay = getGLDisplay(); 53 54 // A connection that is NOT shared to enable independent event processing: 55 mNativeDisplay = getNativeDisplay(); 56 57 int dummy; 58 59 if (XQueryExtension(mNativeDisplay, "RANDR", &dummy, &dummy, &dummy)) 60 { 61 XRRScreenConfiguration *screenConfig; 62 63 screenConfig = XRRGetScreenInfo(mNativeDisplay, DefaultRootWindow(mNativeDisplay)); 64 65 if (screenConfig) 66 { 67 XRRScreenSize *screenSizes; 68 int nSizes = 0; 69 Rotation currentRotation; 70 int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation); 71 72 screenSizes = XRRConfigSizes(screenConfig, &nSizes); 73 74 mCurrentMode.width = screenSizes[currentSizeID].width; 75 mCurrentMode.height = screenSizes[currentSizeID].height; 76 mCurrentMode.refreshRate = XRRConfigCurrentRate(screenConfig); 77 78 mOriginalMode = mCurrentMode; 79 80 for (int sizeID = 0; sizeID < nSizes; sizeID++) 81 { 82 short *rates; 83 int nRates = 0; 84 85 rates = XRRConfigRates(screenConfig, sizeID, &nRates); 86 87 for (int rate = 0; rate < nRates; rate++) 88 { 89 VideoMode mode; 90 91 mode.width = screenSizes[sizeID].width; 92 mode.height = screenSizes[sizeID].height; 93 mode.refreshRate = rates[rate]; 94 95 mVideoModes.push_back(mode); 96 } 97 } 98 XRRFreeScreenConfigInfo(screenConfig); 99 } 100 } else 101 { 102 mCurrentMode.width = DisplayWidth(mNativeDisplay, DefaultScreen(mNativeDisplay)); 103 mCurrentMode.height = DisplayHeight(mNativeDisplay, DefaultScreen(mNativeDisplay)); 104 mCurrentMode.refreshRate = 0; 105 106 mOriginalMode = mCurrentMode; 107 108 mVideoModes.push_back(mCurrentMode); 109 } 110 111 EGLConfig *glConfigs; 112 int config, nConfigs = 0; 113 114 glConfigs = chooseGLConfig(NULL, &nConfigs); 115 116 for (config = 0; config < nConfigs; config++) 117 { 118 int caveat, samples; 119 120 getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); 121 122 if (caveat != EGL_SLOW_CONFIG) 123 { 124 getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); 125 mFSAALevels.push_back(samples); 126 } 127 } 128 129 free(glConfigs); 130 } 131 ~X11EGLSupport()132 X11EGLSupport::~X11EGLSupport() 133 { 134 if (mNativeDisplay) 135 { 136 XCloseDisplay((Display*)mNativeDisplay); 137 } 138 139 if (mGLDisplay) 140 { 141 eglTerminate(mGLDisplay); 142 } 143 } 144 getNativeDisplay()145 NativeDisplayType X11EGLSupport::getNativeDisplay() 146 { 147 if (!mNativeDisplay) 148 { 149 mNativeDisplay = (NativeDisplayType)XOpenDisplay(NULL); 150 151 if (!mNativeDisplay) 152 { 153 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 154 "Couldn`t open X display", 155 "X11EGLSupport::getXDisplay"); 156 } 157 158 mAtomDeleteWindow = XInternAtom((Display*)mNativeDisplay, "WM_DELETE_WINDOW", True); 159 mAtomFullScreen = XInternAtom((Display*)mNativeDisplay, "_NET_WM_STATE_FULLSCREEN", True); 160 mAtomState = XInternAtom((Display*)mNativeDisplay, "_NET_WM_STATE", True); 161 } 162 163 return mNativeDisplay; 164 } 165 getDisplayName(void)166 String X11EGLSupport::getDisplayName(void) 167 { 168 return String((const char*)XDisplayName(DisplayString(mNativeDisplay))); 169 } 170 171 switchMode(uint & width,uint & height,short & frequency)172 void X11EGLSupport::switchMode(uint& width, uint& height, short& frequency) 173 { 174 int size = 0; 175 176 EGLVideoModes eglVideoModes(mVideoModes.begin(), mVideoModes.end()); 177 EGLVideoModes::iterator mode; 178 EGLVideoModes::iterator end = eglVideoModes.end(); 179 EGLVideoMode *newMode = 0; 180 181 for(mode = eglVideoModes.begin(); mode != end; size++) 182 { 183 if (mode->first.first >= width && 184 mode->first.second >= height) 185 { 186 if (!newMode || 187 mode->first.first < newMode->first.first || 188 mode->first.second < newMode->first.second) 189 { 190 newMode = &(*mode); 191 } 192 } 193 194 EGLVideoMode* lastMode = &(*mode); 195 196 while (++mode != end && mode->first == lastMode->first) 197 { 198 if (lastMode == newMode && mode->second == frequency) 199 { 200 newMode = &(*mode); 201 } 202 } 203 } 204 205 if (newMode && *newMode != mCurrentMode) 206 { 207 newMode->first.first = DisplayWidth(mNativeDisplay, 0); 208 newMode->first.second = DisplayHeight(mNativeDisplay, 0); 209 newMode->second = 0; // TODO: Hardcoding refresh rate for LCD's 210 mCurrentMode = {newMode->first.first, newMode->first.second, newMode->second}; 211 } 212 } 213 getVisualFromFBConfig(::EGLConfig glConfig)214 XVisualInfo *X11EGLSupport::getVisualFromFBConfig(::EGLConfig glConfig) 215 { 216 XVisualInfo *vi, tmp; 217 int vid, n; 218 ::EGLDisplay glDisplay; 219 220 glDisplay = getGLDisplay(); 221 mNativeDisplay = getNativeDisplay(); 222 223 if (eglGetConfigAttrib(glDisplay, glConfig, EGL_NATIVE_VISUAL_ID, &vid) == EGL_FALSE) 224 { 225 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get VISUAL_ID from glConfig"); 226 return 0; 227 } 228 EGL_CHECK_ERROR 229 230 if (vid == 0) 231 { 232 const int screen_number = DefaultScreen(mNativeDisplay); 233 Visual *v = DefaultVisual((Display*)mNativeDisplay, screen_number); 234 vid = XVisualIDFromVisual(v); 235 } 236 237 tmp.visualid = vid; 238 vi = 0; 239 vi = XGetVisualInfo((Display*)mNativeDisplay, 240 VisualIDMask, 241 &tmp, &n); 242 if (vi == 0) 243 { 244 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get X11 VISUAL"); 245 return 0; 246 } 247 248 return vi; 249 } 250 newWindow(const String & name,unsigned int width,unsigned int height,bool fullScreen,const NameValuePairList * miscParams)251 RenderWindow* X11EGLSupport::newWindow(const String &name, 252 unsigned int width, unsigned int height, 253 bool fullScreen, 254 const NameValuePairList *miscParams) 255 { 256 EGLWindow* window = new X11EGLWindow(this); 257 window->create(name, width, height, fullScreen, miscParams); 258 259 return window; 260 } 261 262 //X11EGLSupport::getGLDisplay sets up the native variable 263 //then calls EGLSupport::getGLDisplay getGLDisplay()264 EGLDisplay X11EGLSupport::getGLDisplay() 265 { 266 if (!mGLDisplay) 267 { 268 if(!mNativeDisplay) 269 mNativeDisplay = getNativeDisplay(); 270 return EGLSupport::getGLDisplay(); 271 } 272 return mGLDisplay; 273 } 274 275 } 276 277