summaryrefslogtreecommitdiff
path: root/vcl/source/opengl/OpenGLContext.cxx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2016-05-20 09:41:18 +0100
committerCaolán McNamara <caolanm@redhat.com>2016-05-21 10:04:15 +0100
commitb8d163f4334424e78290eae49713e6ba2405b30f (patch)
tree55e78506accb6fe4dbbc1ecb918e4ccc2f510254 /vcl/source/opengl/OpenGLContext.cxx
parentda03b62bb4d44ad1410a4dff15f97bacd55fb99b (diff)
Split OpenGLContext up into SalInstance specific classes
which, at least theoretically, allows there to be vclplug specific ones. i.e. a gtk3 specific one which doesn't assume gtk3 is running under X Change-Id: I6c007a87abbd3049b6fffc70d349e3b7ac445eec
Diffstat (limited to 'vcl/source/opengl/OpenGLContext.cxx')
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx1074
1 files changed, 41 insertions, 1033 deletions
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index f254974727c9..89ce97019be9 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -22,19 +22,9 @@
#include <osl/thread.hxx>
-#if defined(MACOSX)
-#include <premac.h>
-#include <AppKit/NSOpenGLView.h>
-#include <AppKit/NSOpenGL.h>
-#include <postmac.h>
-#endif
-
-#if defined(_WIN32)
-#include <win/saldata.hxx>
-#endif
-
#include "svdata.hxx"
#include "salgdi.hxx"
+#include "salinst.hxx"
#include <opengl/framebuffer.hxx>
#include <opengl/program.hxx>
@@ -47,13 +37,6 @@ using namespace com::sun::star;
#define MAX_FRAMEBUFFER_COUNT 30
-// TODO use rtl::Static instead of 'static'
-#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
-static std::vector<GLXContext> g_vShareList;
-#elif defined(WNT)
-static std::vector<HGLRC> g_vShareList;
-#endif
-
static sal_Int64 nBufferSwapCounter = 0;
GLWindow::~GLWindow()
@@ -63,6 +46,17 @@ GLWindow::~GLWindow()
#endif
}
+bool GLWindow::Synchronize(bool bOnoff) const
+{
+#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
+ XSynchronize(dpy, bOnoff);
+ return true;
+#else
+ (void)bOnoff;
+ return false;
+#endif
+}
+
OpenGLContext::OpenGLContext():
mpWindow(nullptr),
m_pChildWindow(nullptr),
@@ -128,7 +122,7 @@ void OpenGLContext::dispose()
rtl::Reference<OpenGLContext> OpenGLContext::Create()
{
- return rtl::Reference<OpenGLContext>(new OpenGLContext);
+ return rtl::Reference<OpenGLContext>(ImplGetSVData()->mpDefInst->CreateOpenGLContext());
}
void OpenGLContext::requestLegacyContext()
@@ -141,222 +135,6 @@ void OpenGLContext::requestSingleBufferedRendering()
mbUseDoubleBufferedRendering = false;
}
-#if defined( _WIN32 )
-static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch (message)
- {
- case WM_CREATE:
- return 0;
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
- case WM_DESTROY:
- return 0;
- case WM_KEYDOWN:
- switch(wParam)
- {
- case VK_ESCAPE:
- PostQuitMessage(0);
- return 0;
-
- case VK_SPACE:
- break;
- }
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
-}
-
-int InitTempWindow(HWND *hwnd, int width, int height, const PIXELFORMATDESCRIPTOR& inPfd, GLWindow& glWin)
-{
- OpenGLZone aZone;
-
- PIXELFORMATDESCRIPTOR pfd = inPfd;
- int pfmt;
- int ret;
- WNDCLASS wc;
- wc.style = 0;
- wc.lpfnWndProc = WndProc;
- wc.cbClsExtra = wc.cbWndExtra = 0;
- wc.hInstance = NULL;
- wc.hIcon = NULL;
- wc.hCursor = NULL;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = (LPCSTR)"GLRenderer";
- RegisterClass(&wc);
- *hwnd = CreateWindow(wc.lpszClassName, NULL, WS_DISABLED, 0, 0, width, height, NULL, NULL, wc.hInstance, NULL);
- glWin.hDC = GetDC(*hwnd);
- pfmt = ChoosePixelFormat(glWin.hDC, &pfd);
- if (!pfmt)
- {
- return -1;
- }
- ret = SetPixelFormat(glWin.hDC, pfmt, &pfd);
- if(!ret)
- {
- return -1;
- }
- glWin.hRC = wglCreateContext(glWin.hDC);
- if(!(glWin.hRC))
- {
- return -1;
- }
- ret = wglMakeCurrent(glWin.hDC, glWin.hRC);
- if(!ret)
- {
- return -1;
- }
-
- return 0;
-}
-
-bool WGLisExtensionSupported(const char *extension)
-{
- OpenGLZone aZone;
-
- const size_t extlen = strlen(extension);
- const char *supported = NULL;
-
- // Try to use wglGetExtensionStringARB on current DC, if possible
- PROC wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB");
-
- if (wglGetExtString)
- supported = ((char*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC());
- // If that failed, try standard OpenGL extensions string
- if (supported == NULL)
- supported = (char*)glGetString(GL_EXTENSIONS);
- // If that failed too, must be no extensions supported
- if (supported == NULL)
- return false;
-
- // Begin examination at start of string, increment by 1 on false match
- for (const char* p = supported; ; p++)
- {
- // Advance p up to the next possible match
- p = strstr(p, extension);
-
- if (p == NULL)
- return 0; // No Match
-
- // Make sure that match is at the start of the string or that
- // the previous char is a space, or else we could accidentally
- // match "wglFunkywglExtension" with "wglExtension"
-
- // Also, make sure that the following character is space or null
- // or else "wglExtensionTwo" might match "wglExtension"
- if ((p==supported || p[-1]==' ') && (p[extlen]=='\0' || p[extlen]==' '))
- return 1; // Match
- }
-}
-
-bool InitMultisample(const PIXELFORMATDESCRIPTOR& pfd, int& rPixelFormat,
- bool bUseDoubleBufferedRendering, bool bRequestVirtualDevice)
-{
- OpenGLZone aZone;
-
- HWND hWnd = NULL;
- GLWindow glWin;
- // Create a temp window to check whether support multi-sample, if support, get the format
- if (InitTempWindow(&hWnd, 1, 1, pfd, glWin) < 0)
- {
- SAL_WARN("vcl.opengl", "Can't create temp window to test");
- return false;
- }
-
- // See if the string exists in WGL
- if (!WGLisExtensionSupported("WGL_ARB_multisample"))
- {
- SAL_WARN("vcl.opengl", "Device doesn't support multisample");
- return false;
- }
- // Get our pixel format
- PFNWGLCHOOSEPIXELFORMATARBPROC fn_wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
- if (!fn_wglChoosePixelFormatARB)
- {
- return false;
- }
- // Get our current device context
- HDC hDC = GetDC(hWnd);
-
- int pixelFormat;
- int valid;
- UINT numFormats;
- float fAttributes[] = {0,0};
- // These attributes are the bits we want to test for in our sample.
- // Everything is pretty standard, the only one we want to
- // really focus on is the WGL_SAMPLE_BUFFERS_ARB and WGL_SAMPLES_ARB.
- // These two are going to do the main testing for whether or not
- // we support multisampling on this hardware.
- int iAttributes[] =
- {
- WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
- WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
- WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
- WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
- WGL_COLOR_BITS_ARB,24,
- WGL_ALPHA_BITS_ARB,8,
- WGL_DEPTH_BITS_ARB,24,
- WGL_STENCIL_BITS_ARB,0,
- WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
- WGL_SAMPLES_ARB,8,
- 0,0
- };
-
- if (!bUseDoubleBufferedRendering)
- {
- // Use asserts to make sure the iAttributes array is not changed without changing these ugly
- // hardcode indexes into it.
- assert(iAttributes[0] == WGL_DOUBLE_BUFFER_ARB);
- iAttributes[1] = GL_FALSE;
- }
-
- if (bRequestVirtualDevice)
- {
- assert(iAttributes[2] == WGL_DRAW_TO_WINDOW_ARB);
- iAttributes[2] = WGL_DRAW_TO_BITMAP_ARB;
- }
-
- bool bArbMultisampleSupported = false;
-
- // First we check to see if we can get a pixel format for 8 samples
- valid = fn_wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
- // If we returned true, and our format count is greater than 1
- if (valid && numFormats >= 1)
- {
- bArbMultisampleSupported = true;
- rPixelFormat = pixelFormat;
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(glWin.hRC);
- ReleaseDC(hWnd, glWin.hDC);
- DestroyWindow(hWnd);
- return bArbMultisampleSupported;
- }
- // Our pixel format with 8 samples failed, test for 2 samples
- assert(iAttributes[18] == WGL_SAMPLES_ARB);
- iAttributes[19] = 2;
- valid = fn_wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
- if (valid && numFormats >= 1)
- {
- bArbMultisampleSupported = true;
- rPixelFormat = pixelFormat;
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(glWin.hRC);
- ReleaseDC(hWnd, glWin.hDC);
- DestroyWindow(hWnd);
- return bArbMultisampleSupported;
- }
- // Return the valid format
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(glWin.hRC);
- ReleaseDC(hWnd, glWin.hDC);
- DestroyWindow(hWnd);
-
- return bArbMultisampleSupported;
-}
-#endif
-
#ifdef DBG_UTIL
namespace {
@@ -456,168 +234,6 @@ debug_callback(GLenum source, GLenum type, GLuint id,
#endif
-#if defined UNX && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
-
-namespace {
-
-#ifdef DBG_UTIL
-int unxErrorHandler(Display* dpy, XErrorEvent* event)
-{
- char err[256];
- char req[256];
- char minor[256];
- XGetErrorText(dpy, event->error_code, err, 256);
- XGetErrorText(dpy, event->request_code, req, 256);
- XGetErrorText(dpy, event->minor_code, minor, 256);
- SAL_WARN("vcl.opengl", "Error: " << err << ", Req: " << req << ", Minor: " << minor);
- return 0;
-}
-#endif
-
-typedef int (*errorHandler)(Display* /*dpy*/, XErrorEvent* /*evnt*/);
-
-class TempErrorHandler
-{
-private:
- errorHandler oldErrorHandler;
- Display* mdpy;
-
-public:
- TempErrorHandler(Display* dpy, errorHandler newErrorHandler)
- : oldErrorHandler(nullptr)
- , mdpy(dpy)
- {
- if (mdpy)
- {
- XLockDisplay(dpy);
- XSync(dpy, false);
- oldErrorHandler = XSetErrorHandler(newErrorHandler);
- }
- }
-
- ~TempErrorHandler()
- {
- if (mdpy)
- {
- // sync so that we possibly get an XError
- glXWaitGL();
- XSync(mdpy, false);
- XSetErrorHandler(oldErrorHandler);
- XUnlockDisplay(mdpy);
- }
- }
-};
-
-static bool errorTriggered;
-int oglErrorHandler( Display* /*dpy*/, XErrorEvent* /*evnt*/ )
-{
- errorTriggered = true;
-
- return 0;
-}
-
-GLXFBConfig* getFBConfig(Display* dpy, Window win, int& nBestFBC, bool bUseDoubleBufferedRendering, bool bWithSameVisualID)
-{
- OpenGLZone aZone;
-
- if( dpy == nullptr || !glXQueryExtension( dpy, nullptr, nullptr ) )
- return nullptr;
-
- VCL_GL_INFO("window: " << win);
-
- XWindowAttributes xattr;
- if( !XGetWindowAttributes( dpy, win, &xattr ) )
- {
- SAL_WARN("vcl.opengl", "Failed to get window attributes for fbconfig " << win);
- xattr.screen = nullptr;
- xattr.visual = nullptr;
- }
-
- int screen = XScreenNumberOfScreen( xattr.screen );
-
- // TODO: moggi: Select colour channel depth based on visual attributes, not hardcoded */
- static int visual_attribs[] =
- {
- GLX_DOUBLEBUFFER, True,
- GLX_X_RENDERABLE, True,
- GLX_RED_SIZE, 8,
- GLX_GREEN_SIZE, 8,
- GLX_BLUE_SIZE, 8,
- GLX_ALPHA_SIZE, 8,
- GLX_DEPTH_SIZE, 24,
- GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
- None
- };
-
- if (!bUseDoubleBufferedRendering)
- visual_attribs[1] = False;
-
- int fbCount = 0;
- GLXFBConfig* pFBC = glXChooseFBConfig( dpy,
- screen,
- visual_attribs, &fbCount );
-
- if(!pFBC)
- {
- SAL_WARN("vcl.opengl", "no suitable fb format found");
- return nullptr;
- }
-
- int best_num_samp = -1;
- for(int i = 0; i < fbCount; ++i)
- {
- XVisualInfo* pVi = glXGetVisualFromFBConfig( dpy, pFBC[i] );
- if(pVi && (!bWithSameVisualID || (xattr.visual && pVi->visualid == xattr.visual->visualid)) )
- {
- // pick the one with the most samples per pixel
- int nSampleBuf = 0;
- int nSamples = 0;
- glXGetFBConfigAttrib( dpy, pFBC[i], GLX_SAMPLE_BUFFERS, &nSampleBuf );
- glXGetFBConfigAttrib( dpy, pFBC[i], GLX_SAMPLES , &nSamples );
-
- if ( nBestFBC < 0 || (nSampleBuf && ( nSamples > best_num_samp )) )
- {
- nBestFBC = i;
- best_num_samp = nSamples;
- }
- }
- XFree( pVi );
- }
-
- return pFBC;
-}
-
-// we need them before glew can initialize them
-// glew needs an OpenGL context so we need to get the address manually
-void initOpenGLFunctionPointers()
-{
- glXChooseFBConfig = reinterpret_cast<GLXFBConfig*(*)(Display *dpy, int screen, const int *attrib_list, int *nelements)>(glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("glXChooseFBConfig")));
- glXGetVisualFromFBConfig = reinterpret_cast<XVisualInfo*(*)(Display *dpy, GLXFBConfig config)>(glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("glXGetVisualFromFBConfig"))); // try to find a visual for the current set of attributes
- glXGetFBConfigAttrib = reinterpret_cast<int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value)>(glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("glXGetFBConfigAttrib")));
- glXCreateContextAttribsARB = reinterpret_cast<GLXContext(*)(Display*, GLXFBConfig, GLXContext, Bool, const int*)>(glXGetProcAddressARB(reinterpret_cast<const GLubyte *>("glXCreateContextAttribsARB")));
- glXCreatePixmap = reinterpret_cast<GLXPixmap(*)(Display*, GLXFBConfig, Pixmap, const int*)>(glXGetProcAddressARB(reinterpret_cast<const GLubyte *>("glXCreatePixmap")));
-}
-
-Visual* getVisual(Display* dpy, Window win)
-{
- OpenGLZone aZone;
-
- initOpenGLFunctionPointers();
-
- XWindowAttributes xattr;
- if( !XGetWindowAttributes( dpy, win, &xattr ) )
- {
- SAL_WARN("vcl.opengl", "Failed to get window attributes for getVisual " << win);
- xattr.visual = nullptr;
- }
- VCL_GL_INFO("using VisualID " << xattr.visual);
- return xattr.visual;
-}
-
-}
-
-#endif
-
bool OpenGLContext::init( vcl::Window* pParent )
{
if(mbInitialized)
@@ -650,370 +266,12 @@ bool OpenGLContext::init(SystemChildWindow* pChildWindow)
return ImplInit();
}
-#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID && !defined(LIBO_HEADLESS)
-bool OpenGLContext::init(Display* dpy, Window win, int screen)
-{
- if(mbInitialized)
- return true;
-
- if (!dpy)
- return false;
-
- OpenGLZone aZone;
-
- m_aGLWin.dpy = dpy;
- m_aGLWin.win = win;
- m_aGLWin.screen = screen;
-
- Visual* pVisual = getVisual(dpy, win);
-
- initGLWindow(pVisual);
-
- return ImplInit();
-}
-
-// Copy of gluCheckExtension(), from the Apache-licensed
-// https://code.google.com/p/glues/source/browse/trunk/glues/source/glues_registry.c
-static GLboolean checkExtension(const GLubyte* extName, const GLubyte* extString)
-{
- GLboolean flag=GL_FALSE;
- char* word;
- char* lookHere;
- char* deleteThis;
-
- if (extString==nullptr)
- {
- return GL_FALSE;
- }
-
- deleteThis=lookHere=static_cast<char*>(malloc(strlen(reinterpret_cast<const char*>(extString))+1));
- if (lookHere==nullptr)
- {
- return GL_FALSE;
- }
-
- /* strtok() will modify string, so copy it somewhere */
- strcpy(lookHere, reinterpret_cast<const char*>(extString));
-
- while ((word=strtok(lookHere, " "))!=nullptr)
- {
- if (strcmp(word, reinterpret_cast<const char*>(extName))==0)
- {
- flag=GL_TRUE;
- break;
- }
- lookHere=nullptr; /* get next token */
- }
- free(static_cast<void*>(deleteThis));
-
- return flag;
-}
-
-bool GLWindow::HasGLXExtension( const char* name ) const
-{
- return checkExtension( reinterpret_cast<const GLubyte*>(name), reinterpret_cast<const GLubyte*>(GLXExtensions) );
-}
-
-bool OpenGLContext::ImplInit()
-{
- if (!m_aGLWin.dpy)
- return false;
-
- OpenGLZone aZone;
-
- GLXContext pSharedCtx( nullptr );
-#ifdef DBG_UTIL
- TempErrorHandler aErrorHandler(m_aGLWin.dpy, unxErrorHandler);
-#endif
-
- VCL_GL_INFO("OpenGLContext::ImplInit----start");
-
- if (!g_vShareList.empty())
- pSharedCtx = g_vShareList.front();
-
- if (glXCreateContextAttribsARB && !mbRequestLegacyContext)
- {
- int best_fbc = -1;
- GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering, false);
-
- if (pFBC && best_fbc != -1)
- {
- int pContextAttribs[] =
- {
-#if 0 // defined(DBG_UTIL)
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 2,
-#endif
- None
-
- };
- m_aGLWin.ctx = glXCreateContextAttribsARB(m_aGLWin.dpy, pFBC[best_fbc], pSharedCtx, /* direct, not via X */ GL_TRUE, pContextAttribs);
- SAL_INFO_IF(m_aGLWin.ctx, "vcl.opengl", "created a 3.2 core context");
- }
- else
- SAL_WARN("vcl.opengl", "unable to find correct FBC");
- }
-
- if (!m_aGLWin.ctx)
- {
- if (!m_aGLWin.vi)
- return false;
-
- SAL_WARN("vcl.opengl", "attempting to create a non-double-buffered "
- "visual matching the context");
-
- m_aGLWin.ctx = glXCreateContext(m_aGLWin.dpy,
- m_aGLWin.vi,
- pSharedCtx,
- GL_TRUE /* direct, not via X server */);
- }
-
- if( m_aGLWin.ctx )
- {
- g_vShareList.push_back( m_aGLWin.ctx );
- }
- else
- {
- SAL_WARN("vcl.opengl", "unable to create GLX context");
- return false;
- }
-
- if( !glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx ) )
- {
- SAL_WARN("vcl.opengl", "unable to select current GLX context");
- return false;
- }
-
- int glxMinor, glxMajor;
- double nGLXVersion = 0;
- if( glXQueryVersion( m_aGLWin.dpy, &glxMajor, &glxMinor ) )
- nGLXVersion = glxMajor + 0.1*glxMinor;
- SAL_INFO("vcl.opengl", "available GLX version: " << nGLXVersion);
-
- m_aGLWin.GLExtensions = glGetString( GL_EXTENSIONS );
- SAL_INFO("vcl.opengl", "available GL extensions: " << m_aGLWin.GLExtensions);
-
- XWindowAttributes aWinAttr;
- if( !XGetWindowAttributes( m_aGLWin.dpy, m_aGLWin.win, &aWinAttr ) )
- {
- SAL_WARN("vcl.opengl", "Failed to get window attributes on " << m_aGLWin.win);
- m_aGLWin.Width = 0;
- m_aGLWin.Height = 0;
- }
- else
- {
- m_aGLWin.Width = aWinAttr.width;
- m_aGLWin.Height = aWinAttr.height;
- }
-
- if( m_aGLWin.HasGLXExtension("GLX_SGI_swap_control" ) )
- {
- // enable vsync
- typedef GLint (*glXSwapIntervalProc)(GLint);
- glXSwapIntervalProc glXSwapInterval = reinterpret_cast<glXSwapIntervalProc>(glXGetProcAddress( reinterpret_cast<const GLubyte*>("glXSwapIntervalSGI") ));
- if( glXSwapInterval )
- {
- TempErrorHandler aLocalErrorHandler(m_aGLWin.dpy, oglErrorHandler);
-
- errorTriggered = false;
-
- glXSwapInterval( 1 );
-
- if( errorTriggered )
- SAL_WARN("vcl.opengl", "error when trying to set swap interval, NVIDIA or Mesa bug?");
- else
- VCL_GL_INFO("set swap interval to 1 (enable vsync)");
- }
- }
-
- bool bRet = InitGLEW();
- InitGLEWDebugging();
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
- registerAsCurrent();
-
- return bRet;
-}
-
-#elif defined( _WIN32 )
-
-bool OpenGLContext::init(HDC hDC, HWND hWnd)
-{
- if (mbInitialized)
- return false;
-
- m_aGLWin.hDC = hDC;
- m_aGLWin.hWnd = hWnd;
- return ImplInit();
-}
-
-bool OpenGLContext::ImplInit()
-{
- OpenGLZone aZone;
-
- VCL_GL_INFO("OpenGLContext::ImplInit----start");
- // PixelFormat tells Windows how we want things to be
- PIXELFORMATDESCRIPTOR PixelFormatFront =
- {
- sizeof(PIXELFORMATDESCRIPTOR),
- 1, // Version Number
- PFD_SUPPORT_OPENGL,
- PFD_TYPE_RGBA, // Request An RGBA Format
- (BYTE)32, // Select Our Color Depth
- 0, 0, 0, 0, 0, 0, // Color Bits Ignored
- 0, // No Alpha Buffer
- 0, // Shift Bit Ignored
- 0, // No Accumulation Buffer
- 0, 0, 0, 0, // Accumulation Bits Ignored
- 24, // 24 bit z-buffer
- 8, // stencil buffer
- 0, // No Auxiliary Buffer
- 0, // now ignored
- 0, // Reserved
- 0, 0, 0 // Layer Masks Ignored
- };
-
- if (mbUseDoubleBufferedRendering)
- PixelFormatFront.dwFlags |= PFD_DOUBLEBUFFER;
-
- PixelFormatFront.dwFlags |= PFD_DRAW_TO_WINDOW;
-
- // we must check whether can set the MSAA
- int WindowPix = 0;
- bool bMultiSampleSupport = InitMultisample(PixelFormatFront, WindowPix,
- mbUseDoubleBufferedRendering, false);
- if (bMultiSampleSupport && WindowPix != 0)
- {
- m_aGLWin.bMultiSampleSupported = true;
- }
- else
- {
- WindowPix = ChoosePixelFormat(m_aGLWin.hDC, &PixelFormatFront);
-#if OSL_DEBUG_LEVEL > 0
- PIXELFORMATDESCRIPTOR pfd;
- DescribePixelFormat(m_aGLWin.hDC, WindowPix, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- SAL_WARN("vcl.opengl", "Render Target: Window: " << (int) ((pfd.dwFlags & PFD_DRAW_TO_WINDOW) != 0) << ", Bitmap: " << (int) ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) != 0));
- SAL_WARN("vcl.opengl", "Supports OpenGL: " << (int) ((pfd.dwFlags & PFD_SUPPORT_OPENGL) != 0));
-#endif
- }
-
- if (WindowPix == 0)
- {
- SAL_WARN("vcl.opengl", "Invalid pixelformat");
- return false;
- }
-
- if (!SetPixelFormat(m_aGLWin.hDC, WindowPix, &PixelFormatFront))
- {
- ImplWriteLastError(GetLastError(), "SetPixelFormat in OpenGLContext::ImplInit");
- SAL_WARN("vcl.opengl", "SetPixelFormat failed");
- return false;
- }
-
- HGLRC hTempRC = wglCreateContext(m_aGLWin.hDC);
- if (hTempRC == NULL)
- {
- ImplWriteLastError(GetLastError(), "wglCreateContext in OpenGLContext::ImplInit");
- SAL_WARN("vcl.opengl", "wglCreateContext failed");
- return false;
- }
-
- if (!wglMakeCurrent(m_aGLWin.hDC, hTempRC))
- {
- ImplWriteLastError(GetLastError(), "wglMakeCurrent in OpenGLContext::ImplInit");
- SAL_WARN("vcl.opengl", "wglMakeCurrent failed");
- return false;
- }
-
- if (!InitGLEW())
- {
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hTempRC);
- return false;
- }
-
- HGLRC hSharedCtx = 0;
- if (!g_vShareList.empty())
- hSharedCtx = g_vShareList.front();
-
- if (!wglCreateContextAttribsARB)
- {
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hTempRC);
- return false;
- }
-
- // now setup the shared context; this needs a temporary context already
- // set up in order to work
- int attribs [] =
- {
-#ifdef DBG_UTIL
- WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
-#endif
- 0
- };
- m_aGLWin.hRC = wglCreateContextAttribsARB(m_aGLWin.hDC, hSharedCtx, attribs);
- if (m_aGLWin.hRC == 0)
- {
- ImplWriteLastError(GetLastError(), "wglCreateContextAttribsARB in OpenGLContext::ImplInit");
- SAL_WARN("vcl.opengl", "wglCreateContextAttribsARB failed");
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hTempRC);
- return false;
- }
-
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hTempRC);
-
- if (!wglMakeCurrent(m_aGLWin.hDC, m_aGLWin.hRC))
- {
- ImplWriteLastError(GetLastError(), "wglMakeCurrent (with shared context) in OpenGLContext::ImplInit");
- SAL_WARN("vcl.opengl", "wglMakeCurrent failed");
- return false;
- }
-
- InitGLEWDebugging();
-
- g_vShareList.push_back(m_aGLWin.hRC);
-
- RECT clientRect;
- GetClientRect(WindowFromDC(m_aGLWin.hDC), &clientRect);
- m_aGLWin.Width = clientRect.right - clientRect.left;
- m_aGLWin.Height = clientRect.bottom - clientRect.top;
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
- registerAsCurrent();
-
- return true;
-}
-
-#elif defined( MACOSX )
-
-bool OpenGLContext::ImplInit()
-{
- OpenGLZone aZone;
-
- VCL_GL_INFO("OpenGLContext::ImplInit----start");
- NSOpenGLView* pView = getOpenGLView();
- [[pView openGLContext] makeCurrentContext];
-
- bool bRet = InitGLEW();
- InitGLEWDebugging();
- return bRet;
-}
-
-#else
-
bool OpenGLContext::ImplInit()
{
VCL_GL_INFO("OpenGLContext not implemented for this platform");
return false;
}
-#endif
-
bool OpenGLContext::InitGLEW()
{
static bool bGlewInit = false;
@@ -1101,111 +359,16 @@ void OpenGLContext::InitChildWindow(SystemChildWindow *pChildWindow)
pChildWindow->SetControlBackground();
}
-#if defined(_WIN32)
-
-bool OpenGLContext::initWindow()
-{
- if( !m_pChildWindow )
- {
- SystemWindowData winData = generateWinData(mpWindow, false);
- m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
- }
-
- if (m_pChildWindow)
- {
- InitChildWindow(m_pChildWindow.get());
- const SystemEnvData* sysData(m_pChildWindow->GetSystemData());
- m_aGLWin.hWnd = sysData->hWnd;
- }
-
- m_aGLWin.hDC = GetDC(m_aGLWin.hWnd);
- return true;
-}
-
-#elif defined( MACOSX )
-
-bool OpenGLContext::initWindow()
-{
- if( !m_pChildWindow )
- {
- SystemWindowData winData = generateWinData(mpWindow, mbRequestLegacyContext);
- m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
- }
-
- if (m_pChildWindow)
- {
- InitChildWindow(m_pChildWindow.get());
- }
-
- return true;
-}
-
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
-
bool OpenGLContext::initWindow()
{
return false;
}
-#elif defined( UNX )
-
-bool OpenGLContext::initWindow()
+void OpenGLContext::destroyCurrentContext()
{
- const SystemEnvData* pChildSysData = nullptr;
- SystemWindowData winData = generateWinData(mpWindow, false);
- if( winData.pVisual )
- {
- if( !m_pChildWindow )
- {
- m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
- }
- pChildSysData = m_pChildWindow->GetSystemData();
- }
-
- if (!m_pChildWindow || !pChildSysData)
- return false;
-
- InitChildWindow(m_pChildWindow.get());
-
- m_aGLWin.dpy = static_cast<Display*>(pChildSysData->pDisplay);
- m_aGLWin.win = pChildSysData->aWindow;
- m_aGLWin.screen = pChildSysData->nScreen;
-
- Visual* pVisual = static_cast<Visual*>(pChildSysData->pVisual);
- initGLWindow(pVisual);
-
- return true;
-}
-
-void OpenGLContext::initGLWindow(Visual* pVisual)
-{
- OpenGLZone aZone;
-
- // Get visual info
- {
- XVisualInfo aTemplate;
- aTemplate.visualid = XVisualIDFromVisual( pVisual );
- int nVisuals = 0;
- XVisualInfo* pInfo = XGetVisualInfo( m_aGLWin.dpy, VisualIDMask, &aTemplate, &nVisuals );
- if( nVisuals != 1 )
- SAL_WARN( "vcl.opengl", "match count for visual id is not 1" );
- m_aGLWin.vi = pInfo;
- }
-
- // Check multisample support
- /* TODO: moggi: This is not necessarily correct in the DBG_UTIL path, as it picks
- * an FBConfig instead ... */
- int nSamples = 0;
- glXGetConfig(m_aGLWin.dpy, m_aGLWin.vi, GLX_SAMPLES, &nSamples);
- if( nSamples > 0 )
- m_aGLWin.bMultiSampleSupported = true;
-
- m_aGLWin.GLXExtensions = glXQueryExtensionsString( m_aGLWin.dpy, m_aGLWin.screen );
- SAL_INFO("vcl.opengl", "available GLX extensions: " << m_aGLWin.GLXExtensions);
+ //nothing by default
}
-#endif
-
void OpenGLContext::reset()
{
if( !mbInitialized )
@@ -1249,127 +412,46 @@ void OpenGLContext::reset()
mbInitialized = false;
// destroy the context itself
-#if defined(_WIN32)
- if (m_aGLWin.hRC)
- {
- std::vector<HGLRC>::iterator itr = std::remove(g_vShareList.begin(), g_vShareList.end(), m_aGLWin.hRC);
- if (itr != g_vShareList.end())
- g_vShareList.erase(itr);
-
- if (wglGetCurrentContext() != NULL)
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext( m_aGLWin.hRC );
- ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
- m_aGLWin.hRC = 0;
- }
-#elif defined( MACOSX )
- [NSOpenGLContext clearCurrentContext];
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
- // nothing
-#elif defined( UNX )
- if(m_aGLWin.ctx)
- {
- std::vector<GLXContext>::iterator itr = std::remove( g_vShareList.begin(), g_vShareList.end(), m_aGLWin.ctx );
- if (itr != g_vShareList.end())
- g_vShareList.erase(itr);
-
- glXMakeCurrent(m_aGLWin.dpy, None, nullptr);
- if( glGetError() != GL_NO_ERROR )
- {
- SAL_WARN("vcl.opengl", "glError: " << glGetError());
- }
- glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx);
- m_aGLWin.ctx = nullptr;
- }
-#endif
+ destroyCurrentContext();
}
-#if defined(_WIN32) || defined( MACOSX ) || defined( IOS ) || defined( ANDROID )
-
-SystemWindowData OpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool bRequestLegacyContext)
+SystemWindowData OpenGLContext::generateWinData(vcl::Window* /*pParent*/, bool /*bRequestLegacyContext*/)
{
- (void) bRequestLegacyContext;
SystemWindowData aWinData;
-#if defined(MACOSX)
- aWinData.bOpenGL = true;
- aWinData.bLegacy = bRequestLegacyContext;
-#endif
aWinData.nSize = sizeof(aWinData);
return aWinData;
}
-#elif defined( UNX )
-
-SystemWindowData OpenGLContext::generateWinData(vcl::Window* pParent, bool)
+bool OpenGLContext::isCurrent()
{
- OpenGLZone aZone;
-
- SystemWindowData aWinData;
- aWinData.nSize = sizeof(aWinData);
- aWinData.pVisual = nullptr;
-
-#if !defined(LIBO_HEADLESS)
- const SystemEnvData* sysData(pParent->GetSystemData());
-
- Display *dpy = static_cast<Display*>(sysData->pDisplay);
- Window win = sysData->aWindow;
-
- if( dpy == nullptr || !glXQueryExtension( dpy, nullptr, nullptr ) )
- return aWinData;
-
- initOpenGLFunctionPointers();
-
- int best_fbc = -1;
- GLXFBConfig* pFBC = getFBConfig(dpy, win, best_fbc, true, false);
+ (void) this; // loplugin:staticmethods
+ return false;
+}
- if (!pFBC)
- return aWinData;
+void OpenGLContext::makeCurrent()
+{
+ if (isCurrent())
+ return;
- XVisualInfo* vi = nullptr;
- if( best_fbc != -1 )
- vi = glXGetVisualFromFBConfig( dpy, pFBC[best_fbc] );
+ OpenGLZone aZone;
- XFree(pFBC);
+ clearCurrent();
- if( vi )
- {
- VCL_GL_INFO("using VisualID " << vi->visualid);
- aWinData.pVisual = static_cast<void*>(vi->visual);
- }
-#endif
+ // by default nothing else to do
- return aWinData;
+ registerAsCurrent();
}
-#endif
-
-bool OpenGLContext::isCurrent()
+bool OpenGLContext::isAnyCurrent()
{
- OpenGLZone aZone;
-
-#if defined(_WIN32)
- return wglGetCurrentContext() == m_aGLWin.hRC &&
- wglGetCurrentDC() == m_aGLWin.hDC;
-#elif defined( MACOSX )
- (void) this; // loplugin:staticmethods
- return false;
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
return false;
-#elif defined( UNX )
- return m_aGLWin.ctx && glXGetCurrentContext() == m_aGLWin.ctx &&
- glXGetCurrentDrawable() == m_aGLWin.win;
-#endif
}
bool OpenGLContext::hasCurrent()
{
-#if defined(_WIN32)
- return wglGetCurrentContext() != NULL;
-#elif defined( MACOSX ) || defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
- return false;
-#elif defined( UNX )
- return glXGetCurrentContext() != None;
-#endif
+ ImplSVData* pSVData = ImplGetSVData();
+ rtl::Reference<OpenGLContext> pCurrentCtx = pSVData->maGDIData.mpLastContext;
+ return pCurrentCtx.is() && pCurrentCtx->isAnyCurrent();
}
void OpenGLContext::clearCurrent()
@@ -1402,45 +484,6 @@ void OpenGLContext::prepareForYield()
assert (!hasCurrent());
}
-void OpenGLContext::makeCurrent()
-{
- if (isCurrent())
- return;
-
- OpenGLZone aZone;
-
- clearCurrent();
-
-#if defined(_WIN32)
- if (!wglMakeCurrent(m_aGLWin.hDC, m_aGLWin.hRC))
- {
- SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent(): wglMakeCurrent failed: " << GetLastError());
- return;
- }
-#elif defined( MACOSX )
- NSOpenGLView* pView = getOpenGLView();
- [[pView openGLContext] makeCurrentContext];
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
- // nothing
-#elif defined( UNX )
-#ifdef DBG_UTIL
- TempErrorHandler aErrorHandler(m_aGLWin.dpy, unxErrorHandler);
-#endif
-
- if (m_aGLWin.dpy)
- {
- if (!glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx ))
- {
- SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed "
- "on drawable " << m_aGLWin.win);
- return;
- }
- }
-#endif
-
- registerAsCurrent();
-}
-
rtl::Reference<OpenGLContext> OpenGLContext::getVCLContext(bool bMakeIfNecessary)
{
ImplSVData* pSVData = ImplGetSVData();
@@ -1503,37 +546,17 @@ void OpenGLContext::registerAsCurrent()
void OpenGLContext::resetCurrent()
{
clearCurrent();
-
- OpenGLZone aZone;
-
-#if defined(_WIN32)
- wglMakeCurrent(NULL, NULL);
-#elif defined( MACOSX )
- (void) this; // loplugin:staticmethods
- [NSOpenGLContext clearCurrentContext];
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
- // nothing
-#elif defined( UNX )
- if (m_aGLWin.dpy)
- glXMakeCurrent(m_aGLWin.dpy, None, nullptr);
-#endif
+ // by default nothing else to do
}
void OpenGLContext::swapBuffers()
{
- OpenGLZone aZone;
-
-#if defined(_WIN32)
- SwapBuffers(m_aGLWin.hDC);
-#elif defined( MACOSX )
- NSOpenGLView* pView = getOpenGLView();
- [[pView openGLContext] flushBuffer];
-#elif defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
- // nothing
-#elif defined( UNX )
- glXSwapBuffers(m_aGLWin.dpy, m_aGLWin.win);
-#endif
+ // by default nothing else to do
+ BuffersSwapped();
+}
+void OpenGLContext::BuffersSwapped()
+{
nBufferSwapCounter++;
static bool bSleep = getenv("SAL_GL_SLEEP_ON_SWAP");
@@ -1544,6 +567,7 @@ void OpenGLContext::swapBuffers()
}
}
+
sal_Int64 OpenGLWrapper::getBufferSwapCounter()
{
return nBufferSwapCounter;
@@ -1551,17 +575,8 @@ sal_Int64 OpenGLWrapper::getBufferSwapCounter()
void OpenGLContext::sync()
{
- OpenGLZone aZone;
-
-#if defined(_WIN32)
- // nothing
-#elif defined( MACOSX ) || defined( IOS ) || defined( ANDROID ) || defined(LIBO_HEADLESS)
+ // default is nothing
(void) this; // loplugin:staticmethods
- // nothing
-#elif defined( UNX )
- glXWaitGL();
- XSync(m_aGLWin.dpy, false);
-#endif
}
void OpenGLContext::show()
@@ -1587,13 +602,6 @@ bool OpenGLContext::supportMultiSampling() const
return m_aGLWin.bMultiSampleSupported;
}
-#if defined(MACOSX)
-NSOpenGLView* OpenGLContext::getOpenGLView()
-{
- return reinterpret_cast<NSOpenGLView*>(m_pChildWindow->GetSystemData()->mpNSView);
-}
-#endif
-
bool OpenGLContext::BindFramebuffer( OpenGLFramebuffer* pFramebuffer )
{
OpenGLZone aZone;