LCOV - code coverage report
Current view: top level - vcl/source/opengl - OpenGLContext.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 134 0.0 %
Date: 2014-04-14 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include <vcl/OpenGLContext.hxx>
      11             : #include <vcl/syschild.hxx>
      12             : #include <vcl/sysdata.hxx>
      13             : 
      14             : #include <boost/scoped_array.hpp>
      15             : #include <vcl/pngwrite.hxx>
      16             : #include <vcl/bmpacc.hxx>
      17             : #include <vcl/graph.hxx>
      18             : #include <vcl/bitmapex.hxx>
      19             : 
      20             : using namespace com::sun::star;
      21             : 
      22           0 : OpenGLContext::OpenGLContext():
      23             :     mpWindow(NULL),
      24           0 :     mbInitialized(false)
      25             : {
      26           0 : }
      27             : 
      28           0 : OpenGLContext::~OpenGLContext()
      29             : {
      30           0 : }
      31             : 
      32             : #if defined( _WIN32 )
      33             : static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
      34             : {
      35             :     switch (message)
      36             :     {
      37             :     case WM_CREATE:
      38             :         return 0;
      39             :     case WM_CLOSE:
      40             :         PostQuitMessage(0);
      41             :         return 0;
      42             :     case WM_DESTROY:
      43             :         return 0;
      44             :     case WM_KEYDOWN:
      45             :         switch(wParam)
      46             :         {
      47             :         case VK_ESCAPE:
      48             :             PostQuitMessage(0);
      49             :             return 0;
      50             : 
      51             :         case VK_SPACE:
      52             :             break;
      53             :         }
      54             :     default:
      55             :         return DefWindowProc(hwnd, message, wParam, lParam);
      56             :     }
      57             : }
      58             : 
      59             : int InitTempWindow(HWND *hwnd, int width, int height, PIXELFORMATDESCRIPTOR inPfd, GLWindow glWin)
      60             : {
      61             :     PIXELFORMATDESCRIPTOR  pfd = inPfd;
      62             :     int  pfmt;
      63             :     int ret;
      64             :     WNDCLASS wc;
      65             :     wc.style = 0;
      66             :     wc.lpfnWndProc = WndProc;
      67             :     wc.cbClsExtra = wc.cbWndExtra = 0;
      68             :     wc.hInstance = NULL;
      69             :     wc.hIcon = NULL;
      70             :     wc.hCursor = NULL;
      71             :     wc.hbrBackground = NULL;
      72             :     wc.lpszMenuName = NULL;
      73             :     wc.lpszClassName = (LPCSTR)"GLRenderer";
      74             :     RegisterClass(&wc);
      75             :     *hwnd = CreateWindow(wc.lpszClassName, NULL, WS_DISABLED, 0, 0, width, height, NULL, NULL, wc.hInstance, NULL);
      76             :     glWin.hDC = GetDC(*hwnd);
      77             :     pfmt = ChoosePixelFormat(glWin.hDC, &pfd);
      78             :     if (!pfmt)
      79             :     {
      80             :         return -1;
      81             :     }
      82             :     ret = SetPixelFormat(glWin.hDC, pfmt, &pfd);
      83             :     if(!ret)
      84             :     {
      85             :         return -1;
      86             :     }
      87             :     glWin.hRC = wglCreateContext(glWin.hDC);
      88             :     if(!(glWin.hRC))
      89             :     {
      90             :         return -1;
      91             :     }
      92             :     ret = wglMakeCurrent(glWin.hDC, glWin.hRC);
      93             :     if(!ret)
      94             :     {
      95             :         return -1;
      96             :     }
      97             :     return 0;
      98             : }
      99             : 
     100             : bool WGLisExtensionSupported(const char *extension)
     101             : {
     102             :     const size_t extlen = strlen(extension);
     103             :     const char *supported = NULL;
     104             : 
     105             :     // Try To Use wglGetExtensionStringARB On Current DC, If Possible
     106             :     PROC wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB");
     107             : 
     108             :     if (wglGetExtString)
     109             :         supported = ((char*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC());
     110             :     // If That Failed, Try Standard Opengl Extensions String
     111             :     if (supported == NULL)
     112             :         supported = (char*)glGetString(GL_EXTENSIONS);
     113             :     // If That Failed Too, Must Be No Extensions Supported
     114             :     if (supported == NULL)
     115             :         return 0;
     116             : 
     117             :     // Begin Examination At Start Of String, Increment By 1 On False Match
     118             :     for (const char* p = supported; ; p++)
     119             :     {
     120             :         // Advance p Up To The Next Possible Match
     121             :         p = strstr(p, extension);
     122             : 
     123             :         if (p == NULL)
     124             :             return 0; // No Match
     125             : 
     126             :         // Make Sure That Match Is At The Start Of The String Or That
     127             :         // The Previous Char Is A Space, Or Else We Could Accidentally
     128             :         // Match "wglFunkywglExtension" With "wglExtension"
     129             : 
     130             :         // Also, Make Sure That The Following Character Is Space Or NULL
     131             :         // Or Else "wglExtensionTwo" Might Match "wglExtension"
     132             :         if ((p==supported || p[-1]==' ') && (p[extlen]=='\0' || p[extlen]==' '))
     133             :             return 1; // Match
     134             :     }
     135             : }
     136             : 
     137             : bool InitMultisample(PIXELFORMATDESCRIPTOR pfd, int& rPixelFormat)
     138             : {
     139             :     HWND hWnd = NULL;
     140             :     GLWindow glWin;
     141             :     //create a temp windwo to check whether support multi-sample, if support, get the format
     142             :     if (InitTempWindow(&hWnd, 1, 1, pfd, glWin) < 0)
     143             :     {
     144             :         SAL_WARN("vcl.opengl", "Can't create temp window to test");
     145             :         return false;
     146             :     }
     147             : 
     148             :     // See If The String Exists In WGL!
     149             :     if (!WGLisExtensionSupported("WGL_ARB_multisample"))
     150             :     {
     151             :         SAL_WARN("vcl.opengl", "Device doesn't support multi sample");
     152             :         return false;
     153             :     }
     154             :     // Get Our Pixel Format
     155             :     PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
     156             :     if (!wglChoosePixelFormatARB)
     157             :     {
     158             :         return false;
     159             :     }
     160             :     // Get Our Current Device Context
     161             :     HDC hDC = GetDC(hWnd);
     162             : 
     163             :     int pixelFormat;
     164             :     int valid;
     165             :     UINT    numFormats;
     166             :     float   fAttributes[] = {0,0};
     167             :     // These Attributes Are The Bits We Want To Test For In Our Sample
     168             :     // Everything Is Pretty Standard, The Only One We Want To
     169             :     // Really Focus On Is The SAMPLE BUFFERS ARB And WGL SAMPLES
     170             :     // These Two Are Going To Do The Main Testing For Whether Or Not
     171             :     // We Support Multisampling On This Hardware.
     172             :     int iAttributes[] =
     173             :     {
     174             :         WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
     175             :         WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
     176             :         WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
     177             :         WGL_COLOR_BITS_ARB,24,
     178             :         WGL_ALPHA_BITS_ARB,8,
     179             :         WGL_DEPTH_BITS_ARB,16,
     180             :         WGL_STENCIL_BITS_ARB,0,
     181             :         WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
     182             :         WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
     183             :         WGL_SAMPLES_ARB,8,
     184             :         0,0
     185             :     };
     186             : 
     187             :     bool bArbMultisampleSupported = true;
     188             : 
     189             :     // First We Check To See If We Can Get A Pixel Format For 4 Samples
     190             :     valid = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
     191             :     // If We Returned True, And Our Format Count Is Greater Than 1
     192             :     if (valid && numFormats >= 1)
     193             :     {
     194             :         bArbMultisampleSupported = true;
     195             :         rPixelFormat = pixelFormat;
     196             :         wglMakeCurrent(NULL, NULL);
     197             :         wglDeleteContext(glWin.hRC);
     198             :         ReleaseDC(hWnd, glWin.hDC);
     199             :         DestroyWindow(hWnd);
     200             :         return bArbMultisampleSupported;
     201             :     }
     202             :     // Our Pixel Format With 4 Samples Failed, Test For 2 Samples
     203             :     iAttributes[19] = 2;
     204             :     valid = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
     205             :     if (valid && numFormats >= 1)
     206             :     {
     207             :         bArbMultisampleSupported = true;
     208             :         rPixelFormat = pixelFormat;
     209             :         wglMakeCurrent(NULL, NULL);
     210             :         wglDeleteContext(glWin.hRC);
     211             :         ReleaseDC(hWnd, glWin.hDC);
     212             :         DestroyWindow(hWnd);
     213             :         return bArbMultisampleSupported;
     214             :     }
     215             :     // Return The Valid Format
     216             :     wglMakeCurrent(NULL, NULL);
     217             :     wglDeleteContext(glWin.hRC);
     218             :     ReleaseDC(hWnd, glWin.hDC);
     219             :     DestroyWindow(hWnd);
     220             : 
     221             :     return  bArbMultisampleSupported;
     222             : }
     223             : #endif
     224             : 
     225             : #ifdef DBG_UTIL
     226             : 
     227             : namespace {
     228             : 
     229             : const char* getSeverityString(GLenum severity)
     230             : {
     231             :     switch(severity)
     232             :     {
     233             :         case GL_DEBUG_SEVERITY_LOW:
     234             :             return "low";
     235             :         case GL_DEBUG_SEVERITY_MEDIUM:
     236             :             return "medium";
     237             :         case GL_DEBUG_SEVERITY_HIGH:
     238             :             return "high";
     239             :         default:
     240             :             ;
     241             :     }
     242             : 
     243             :     return "unknown";
     244             : }
     245             : 
     246             : const char* getSourceString(GLenum source)
     247             : {
     248             :     switch(source)
     249             :     {
     250             :         case GL_DEBUG_SOURCE_API:
     251             :             return "API";
     252             :         case GL_DEBUG_SOURCE_SHADER_COMPILER:
     253             :             return "shader compiler";
     254             :         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
     255             :             return "window system";
     256             :         case GL_DEBUG_SOURCE_THIRD_PARTY:
     257             :             return "third party";
     258             :         case GL_DEBUG_SOURCE_APPLICATION:
     259             :             return "Libreoffice";
     260             :         case GL_DEBUG_SOURCE_OTHER:
     261             :             return "unknown";
     262             :         default:
     263             :             ;
     264             :     }
     265             : 
     266             :     return "unknown";
     267             : }
     268             : 
     269             : const char* getTypeString(GLenum type)
     270             : {
     271             :     switch(type)
     272             :     {
     273             :         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
     274             :             return "deprecated behavior";
     275             :         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
     276             :             return "undefined behavior";
     277             :         case GL_DEBUG_TYPE_PERFORMANCE:
     278             :             return "performance";
     279             :         case GL_DEBUG_TYPE_PORTABILITY:
     280             :             return "portability";
     281             :         case GL_DEBUG_TYPE_MARKER:
     282             :             return "marker";
     283             :         case GL_DEBUG_TYPE_PUSH_GROUP:
     284             :             return "push group";
     285             :         case GL_DEBUG_TYPE_POP_GROUP:
     286             :             return "pop group";
     287             :         case GL_DEBUG_TYPE_OTHER:
     288             :             return "other";
     289             :         default:
     290             :             ;
     291             :     }
     292             : 
     293             :     return "unkown";
     294             : }
     295             : 
     296             : extern "C" void
     297             : #if defined _WIN32
     298             : APIENTRY
     299             : #endif
     300             : debug_callback(GLenum source, GLenum type, GLuint id,
     301             :         GLenum severity, GLsizei , const GLchar* message, GLvoid* )
     302             : {
     303             :     SAL_WARN("vcl.opengl", "OpenGL debug message: source: " << getSourceString(source) << ", type: "
     304             :             << getTypeString(type) << ", id: " << id << ", severity: " << getSeverityString(severity) << " with message: " << message);
     305             : }
     306             : 
     307             : }
     308             : 
     309             : #endif
     310             : 
     311             : #if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID
     312             : 
     313             : namespace {
     314             : 
     315             : static bool errorTriggered;
     316           0 : int oglErrorHandler( Display* /*dpy*/, XErrorEvent* /*evnt*/ )
     317             : {
     318           0 :     errorTriggered = true;
     319             : 
     320           0 :     return 0;
     321             : }
     322             : 
     323             : }
     324             : 
     325             : #endif
     326             : 
     327           0 : bool OpenGLContext::init( Window* pParent )
     328             : {
     329           0 :     if(mbInitialized)
     330           0 :         return true;
     331             : 
     332           0 :     m_pWindow.reset(pParent ? NULL : new Window(0, WB_NOBORDER|WB_NODIALOGCONTROL));
     333           0 :     mpWindow = pParent ? pParent : m_pWindow.get();
     334             :     SAL_INFO("vcl.opengl", "OpenGLContext::OpenGLContext----start");
     335           0 :     initWindow();
     336           0 :     if(m_pWindow)
     337           0 :         m_pWindow->setPosSizePixel(0,0,0,0);
     338           0 :     m_aGLWin.Width = 0;
     339           0 :     m_aGLWin.Height = 0;
     340             : 
     341             : #if defined( WNT )
     342             :     m_aGLWin.hDC = GetDC(m_aGLWin.hWnd);
     343             : #elif defined( MACOSX )
     344             : 
     345             : #elif defined( IOS )
     346             : 
     347             : #elif defined( ANDROID )
     348             : 
     349             : #elif defined( UNX )
     350             :     m_aGLWin.ctx = glXCreateContext(m_aGLWin.dpy,
     351             :                                  m_aGLWin.vi,
     352             :                                  0,
     353           0 :                                  GL_TRUE);
     354           0 :     if( m_aGLWin.ctx == NULL )
     355             :     {
     356             :         SAL_INFO("vcl.opengl", "unable to create GLX context");
     357           0 :         return false;
     358             :     }
     359             : #endif
     360             : 
     361             : #if defined( WNT )
     362             :     PIXELFORMATDESCRIPTOR PixelFormatFront =                    // PixelFormat Tells Windows How We Want Things To Be
     363             :     {
     364             :         sizeof(PIXELFORMATDESCRIPTOR),
     365             :         1,                              // Version Number
     366             :         PFD_DRAW_TO_WINDOW |
     367             :         PFD_SUPPORT_OPENGL |
     368             :         PFD_DOUBLEBUFFER,
     369             :         PFD_TYPE_RGBA,                  // Request An RGBA Format
     370             :         (BYTE)32,                       // Select Our Color Depth
     371             :         0, 0, 0, 0, 0, 0,               // Color Bits Ignored
     372             :         0,                              // No Alpha Buffer
     373             :         0,                              // Shift Bit Ignored
     374             :         0,                              // No Accumulation Buffer
     375             :         0, 0, 0, 0,                     // Accumulation Bits Ignored
     376             :         64,                             // 32 bit Z-BUFFER
     377             :         0,                              // 0 bit stencil buffer
     378             :         0,                              // No Auxiliary Buffer
     379             :         0,                              // now ignored
     380             :         0,                              // Reserved
     381             :         0, 0, 0                         // Layer Masks Ignored
     382             :     };
     383             : 
     384             :     //  we must check whether can set the MSAA
     385             :     int WindowPix;
     386             :     bool bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix);
     387             :     if (bMultiSampleSupport)
     388             :     {
     389             :         m_aGLWin.bMultiSampleSupported = true;
     390             :     }
     391             :     else
     392             :     {
     393             :         WindowPix = ChoosePixelFormat(m_aGLWin.hDC,&PixelFormatFront);
     394             :     }
     395             :     SetPixelFormat(m_aGLWin.hDC,WindowPix,&PixelFormatFront);
     396             :     m_aGLWin.hRC  = wglCreateContext(m_aGLWin.hDC);
     397             :     wglMakeCurrent(m_aGLWin.hDC,m_aGLWin.hRC);
     398             : 
     399             : #elif defined( MACOSX )
     400             : 
     401             : #elif defined( IOS )
     402             : 
     403             : #elif defined( ANDROID )
     404             : 
     405             : #elif defined( UNX )
     406           0 :     if( !glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx ) )
     407             :     {
     408             :         SAL_INFO("vcl.opengl", "unable to select current GLX context");
     409           0 :         return false;
     410             :     }
     411             : 
     412             :     int glxMinor, glxMajor;
     413           0 :     double nGLXVersion = 0;
     414           0 :     if( glXQueryVersion( m_aGLWin.dpy, &glxMajor, &glxMinor ) )
     415           0 :       nGLXVersion = glxMajor + 0.1*glxMinor;
     416             :     SAL_INFO("vcl.opengl", "available GLX version: " << nGLXVersion);
     417             : 
     418           0 :     m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS );
     419             :     SAL_INFO("vcl.opengl", "available GL  extensions: " << m_aGLWin.GLExtensions);
     420             : 
     421           0 :     if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) )
     422             :     {
     423             :         // enable vsync
     424             :         typedef GLint (*glXSwapIntervalProc)(GLint);
     425           0 :         glXSwapIntervalProc glXSwapInterval = (glXSwapIntervalProc) glXGetProcAddress( (const GLubyte*) "glXSwapIntervalSGI" );
     426           0 :         if( glXSwapInterval ) {
     427             :         int (*oldHandler)(Display* /*dpy*/, XErrorEvent* /*evnt*/);
     428             : 
     429             :         // replace error handler temporarily
     430           0 :         oldHandler = XSetErrorHandler( oglErrorHandler );
     431             : 
     432           0 :         errorTriggered = false;
     433             : 
     434           0 :         glXSwapInterval( 1 );
     435             : 
     436             :         // sync so that we possibly get an XError
     437           0 :         glXWaitGL();
     438           0 :         XSync(m_aGLWin.dpy, false);
     439             : 
     440           0 :         if( errorTriggered )
     441             :             SAL_INFO("vcl.opengl", "error when trying to set swap interval, NVIDIA or Mesa bug?");
     442             :         else
     443             :             SAL_INFO("vcl.opengl", "set swap interval to 1 (enable vsync)");
     444             : 
     445             :         // restore the error handler
     446           0 :         XSetErrorHandler( oldHandler );
     447             :         }
     448             :     }
     449             : 
     450             : #endif
     451             : 
     452             :     //rGLRender.InitOpenGL(m_aGLWin);
     453             : 
     454             : #ifdef DBG_UTIL
     455             :     // only enable debug output in dbgutil build
     456             :     if( GLEW_ARB_debug_output )
     457             :     {
     458             :         glEnable(GL_DEBUG_OUTPUT);
     459             :         glDebugMessageCallback(&debug_callback, NULL);
     460             :     }
     461             : 
     462             : #endif
     463             : 
     464             :     static bool bGlewInit = false;
     465           0 :     if(!bGlewInit)
     466             :     {
     467           0 :         glewExperimental = GL_TRUE;
     468           0 :         if (glewInit() != GLEW_OK)
     469             :         {
     470             :             SAL_WARN("vcl.opengl", "Failed to initialize GLEW");
     471           0 :             return false;
     472             :         }
     473             :         else
     474           0 :             bGlewInit = true;
     475             :     }
     476             : 
     477             :     SAL_INFO("vcl.opengl", "OpenGLContext::init----end");
     478           0 :     mbInitialized = true;
     479           0 :     return true;
     480             : }
     481             : 
     482           0 : void OpenGLContext::setWinSize(const Size& rSize)
     483             : {
     484           0 :     if(m_pWindow)
     485           0 :         m_pWindow->SetSizePixel(rSize);
     486           0 :     m_pChildWindow->SetSizePixel(rSize);
     487             : 
     488           0 :     m_aGLWin.Width = rSize.Width();
     489           0 :     m_aGLWin.Height = rSize.Height();
     490           0 : }
     491             : 
     492           0 : GLWindow& OpenGLContext::getOpenGLWindow()
     493             : {
     494           0 :     return m_aGLWin;
     495             : }
     496             : 
     497           0 : void OpenGLContext::renderToFile()
     498             : {
     499           0 :     int iWidth = m_aGLWin.Width;
     500           0 :     int iHeight = m_aGLWin.Height;
     501           0 :     boost::scoped_array<sal_uInt8> buf(new sal_uInt8[iWidth * iHeight * 4]);
     502           0 :     glReadPixels(0, 0, iWidth, iHeight, GL_BGRA, GL_UNSIGNED_BYTE, buf.get());
     503             : 
     504           0 :     Bitmap aBitmap( Size(iWidth, iHeight), 24 );
     505           0 :     AlphaMask aAlpha( Size(iWidth, iHeight) );
     506             : 
     507             :     {
     508           0 :         Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
     509           0 :         AlphaMask::ScopedWriteAccess pAlphaWriteAccess( aAlpha );
     510             : 
     511           0 :         size_t nCurPos = 0;
     512           0 :         for( int y = 0; y < iHeight; ++y)
     513             :         {
     514           0 :             Scanline pScan = pWriteAccess->GetScanline(y);
     515           0 :             Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(y);
     516           0 :             for( int x = 0; x < iWidth; ++x )
     517             :             {
     518           0 :                 *pScan++ = buf[nCurPos];
     519           0 :                 *pScan++ = buf[nCurPos+1];
     520           0 :                 *pScan++ = buf[nCurPos+2];
     521             : 
     522           0 :                 nCurPos += 3;
     523           0 :                 *pAlphaScan++ = static_cast<sal_uInt8>( 255 - buf[nCurPos++] );
     524             :             }
     525           0 :         }
     526             :     }
     527             : 
     528           0 :     BitmapEx aBmp(aBitmap, aAlpha);
     529             :     static int nIdx = 0;
     530           0 :     OUString aName = OUString( "file:///home/moggi/Documents/work/text" ) + OUString::number( nIdx++ ) + ".png";
     531             :     try {
     532           0 :         vcl::PNGWriter aWriter( aBmp );
     533           0 :         SvFileStream sOutput( aName, STREAM_WRITE );
     534           0 :         aWriter.Write( sOutput );
     535           0 :         sOutput.Close();
     536           0 :     } catch (...) {
     537             :         SAL_WARN("chart2.opengl", "Error writing png to " << aName);
     538           0 :     }
     539           0 : }
     540             : 
     541             : #if defined( WNT )
     542             : 
     543             : bool OpenGLContext::initWindow()
     544             : {
     545             :     const SystemEnvData* sysData(mpWindow->GetSystemData());
     546             :     m_aGLWin.hWnd = sysData->hWnd;
     547             :     SystemWindowData winData;
     548             :     winData.nSize = sizeof(winData);
     549             :     m_pChildWindow.reset(new SystemChildWindow(mpWindow, 0, &winData, sal_False));
     550             : 
     551             :     if( m_pChildWindow )
     552             :     {
     553             :         m_pChildWindow->SetMouseTransparent( sal_True );
     554             :         m_pChildWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
     555             :         m_pChildWindow->EnableEraseBackground( sal_False );
     556             :         m_pChildWindow->SetControlForeground();
     557             :         m_pChildWindow->SetControlBackground();
     558             :         m_pChildWindow->EnablePaint(sal_False);
     559             :         m_aGLWin.hWnd = sysData->hWnd;
     560             :     }
     561             : 
     562             :     return true;
     563             : }
     564             : 
     565             : #elif defined( MACOSX ) || defined( IOS) || defined( ANDROID )
     566             : 
     567             : bool OpenGLContext::initWindow()
     568             : {
     569             :     return false;
     570             : }
     571             : 
     572             : #elif defined( UNX )
     573             : 
     574             : namespace {
     575             : 
     576             : // we need them before glew can initialize them
     577             : // glew needs an OpenGL context so we need to get the address manually
     578           0 : void initOpenGLFunctionPointers()
     579             : {
     580           0 :     glXChooseFBConfig = (GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements))glXGetProcAddressARB((GLubyte*)"glXChooseFBConfig");
     581           0 :     glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig");    // try to find a visual for the current set of attributes
     582           0 :     glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
     583           0 : }
     584             : 
     585             : }
     586             : 
     587           0 : bool OpenGLContext::initWindow()
     588             : {
     589           0 :     const SystemEnvData* sysData(mpWindow->GetSystemData());
     590             : 
     591           0 :     m_aGLWin.dpy = reinterpret_cast<Display*>(sysData->pDisplay);
     592             : 
     593           0 :     if( !glXQueryExtension( m_aGLWin.dpy, NULL, NULL ) )
     594           0 :         return false;
     595             : 
     596           0 :     m_aGLWin.win = sysData->aWindow;
     597             : 
     598             :     SAL_INFO("vcl.opengl", "parent window: " << m_aGLWin.win);
     599             : 
     600             :     XWindowAttributes xattr;
     601           0 :     XGetWindowAttributes( m_aGLWin.dpy, m_aGLWin.win, &xattr );
     602             : 
     603           0 :     m_aGLWin.screen = XScreenNumberOfScreen( xattr.screen );
     604             : 
     605             :     static int visual_attribs[] =
     606             :     {
     607             :         GLX_RED_SIZE,           8,
     608             :         GLX_GREEN_SIZE,         8,
     609             :         GLX_BLUE_SIZE,          8,
     610             :         GLX_ALPHA_SIZE,         8,
     611             :         GLX_DEPTH_SIZE,         24,
     612             :         GLX_X_VISUAL_TYPE,      GLX_TRUE_COLOR,
     613             :         None
     614             :     };
     615             : 
     616           0 :     const SystemEnvData* pChildSysData = NULL;
     617           0 :     m_pChildWindow.reset();
     618             : 
     619           0 :     initOpenGLFunctionPointers();
     620             : 
     621           0 :     int fbCount = 0;
     622             :     GLXFBConfig* pFBC = glXChooseFBConfig( m_aGLWin.dpy,
     623             :             m_aGLWin.screen,
     624           0 :             visual_attribs, &fbCount );
     625             : 
     626           0 :     if(!pFBC)
     627             :     {
     628             :         SAL_WARN("vcl.opengl", "no suitable fb format found");
     629           0 :         return false;
     630             :     }
     631             : 
     632           0 :     int best_fbc = -1, best_num_samp = -1;
     633           0 :     for(int i = 0; i < fbCount; ++i)
     634             :     {
     635           0 :         XVisualInfo* pVi = glXGetVisualFromFBConfig( m_aGLWin.dpy, pFBC[i] );
     636           0 :         if(pVi)
     637             :         {
     638             :             // pick the one with the most samples per pixel
     639           0 :             int nSampleBuf = 0;
     640           0 :             int nSamples = 0;
     641           0 :             glXGetFBConfigAttrib( m_aGLWin.dpy, pFBC[i], GLX_SAMPLE_BUFFERS, &nSampleBuf );
     642           0 :             glXGetFBConfigAttrib( m_aGLWin.dpy, pFBC[i], GLX_SAMPLES       , &nSamples  );
     643             : 
     644           0 :             if ( best_fbc < 0 || (nSampleBuf && ( nSamples > best_num_samp )) )
     645             :             {
     646           0 :                 best_fbc = i;
     647           0 :                 best_num_samp = nSamples;
     648             :             }
     649             :         }
     650           0 :         XFree( pVi );
     651             :     }
     652             : 
     653           0 :     if(best_num_samp > 0)
     654           0 :         m_aGLWin.bMultiSampleSupported = true;
     655             : 
     656           0 :     XVisualInfo* vi = glXGetVisualFromFBConfig( m_aGLWin.dpy, pFBC[best_fbc] );
     657           0 :     if( vi )
     658             :     {
     659             :         SystemWindowData winData;
     660           0 :         winData.nSize = sizeof(winData);
     661             :         SAL_INFO("vcl.opengl", "using VisualID " << vi->visualid);
     662           0 :         winData.pVisual = (void*)(vi->visual);
     663           0 :         m_pChildWindow.reset(new SystemChildWindow(mpWindow, 0, &winData, false));
     664           0 :         pChildSysData = m_pChildWindow->GetSystemData();
     665             :     }
     666             : 
     667           0 :     if (!m_pChildWindow || !pChildSysData)
     668           0 :         return false;
     669             : 
     670           0 :     m_pChildWindow->SetMouseTransparent( true );
     671           0 :     m_pChildWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP );
     672           0 :     m_pChildWindow->EnableEraseBackground( false );
     673           0 :     m_pChildWindow->SetControlForeground();
     674           0 :     m_pChildWindow->SetControlBackground();
     675             : 
     676           0 :     m_aGLWin.dpy = reinterpret_cast<Display*>(pChildSysData->pDisplay);
     677           0 :     m_aGLWin.win = pChildSysData->aWindow;
     678           0 :     m_aGLWin.vi = vi;
     679           0 :     m_aGLWin.GLXExtensions = glXQueryExtensionsString( m_aGLWin.dpy, m_aGLWin.screen );
     680             :     SAL_INFO("vcl.opengl", "available GLX extensions: " << m_aGLWin.GLXExtensions);
     681             : 
     682           0 :     return true;
     683             : }
     684             : 
     685             : #endif
     686             : 
     687             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10