diff options
author | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-11-07 07:32:00 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-11-10 07:59:32 +0100 |
commit | 88cd7f366e35a731c780f94aa2f5435ef061f6a9 (patch) | |
tree | 99aa1e4be38dbc41748171791a5e1ef83c4655a1 | |
parent | e5890fcec5c7fabad07080f1ab2e97ee2526248c (diff) |
use GLXPixmap for VirtualDevice
Change-Id: I6397708f164be68bd6561a382115654f90ecd471
-rw-r--r-- | include/vcl/opengl/OpenGLContext.hxx | 13 | ||||
-rw-r--r-- | officecfg/registry/schema/org/openoffice/Office/Common.xcs | 2 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLContext.cxx | 94 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi.cxx | 18 |
4 files changed, 114 insertions, 13 deletions
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index b9c03c33afe8..5ca96020fb4d 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -102,14 +102,16 @@ struct GLWindow #elif defined( IOS ) #elif defined( ANDROID ) #elif defined( UNX ) - Display* dpy; - int screen; - Window win; + Display* dpy; + int screen; + Window win; + Pixmap pix; #if defined( GLX_EXT_texture_from_pixmap ) GLXFBConfig fbc; #endif XVisualInfo* vi; GLXContext ctx; + GLXPixmap glPix; bool HasGLXExtension( const char* name ) { return checkExtension( (const GLubyte*) name, (const GLubyte*) GLXExtensions ); } const char* GLXExtensions; @@ -135,6 +137,7 @@ struct GLWindow #endif vi(NULL), ctx(0), + glPix(0), GLXExtensions(NULL), #endif bpp(0), @@ -165,6 +168,7 @@ public: // only in vcl's platform code #if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID bool init(Display* dpy, Window win, int screen); + bool init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen); #elif defined( _WIN32 ) bool init( HDC hDC, HWND hWnd ); #endif @@ -214,6 +218,9 @@ private: bool mbRequestLegacyContext; bool mbUseDoubleBufferedRendering; bool mbRequestVirtualDevice; +#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID + bool mbPixmap; // is a pixmap instead of a window +#endif }; #endif diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index e19df23e094c..42cfaa024ba9 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -856,7 +856,7 @@ <desc>Specifies if OpenGL rendering should be used in VCL backends supporting it.</desc> </info> - <value>false</value> + <value>true</value> </prop> </group> <group oor:name="InternalMSExport"> diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index d499db123dd9..f4a00333e9da 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -42,7 +42,8 @@ OpenGLContext::OpenGLContext(): mbInitialized(false), mbRequestLegacyContext(false), mbUseDoubleBufferedRendering(true), - mbRequestVirtualDevice(false) + mbRequestVirtualDevice(false), + mbPixmap(false) { } @@ -70,6 +71,9 @@ OpenGLContext::~OpenGLContext() SAL_WARN("vcl.opengl", "glError: " << (char *)gluErrorString(glGetError())); } glXDestroyContext(m_aGLWin.dpy, m_aGLWin.ctx); + + if (mbPixmap) + glXDestroyGLXPixmap(m_aGLWin.dpy, m_aGLWin.glPix); } #endif } @@ -396,6 +400,54 @@ int oglErrorHandler( Display* /*dpy*/, XErrorEvent* /*evnt*/ ) return 0; } +GLXFBConfig* getFBConfigForPixmap(Display* dpy, int& nBestFBC, bool bUseDoubleBufferedRendering, int screen) +{ + 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 NULL; + } + + int best_num_samp = -1; + for(int i = 0; i < fbCount; ++i) + { + // 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; + } + } + + return pFBC; +} + #ifdef DBG_UTIL GLXFBConfig* getFBConfig(Display* dpy, Window win, int& nBestFBC, bool bUseDoubleBufferedRendering) { @@ -534,11 +586,40 @@ bool OpenGLContext::init(Display* dpy, Window win, int screen) return ImplInit(); } +bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned int height, int nScreen) +{ + if(mbInitialized) + return true; + + if (!dpy) + return false; + + SAL_INFO("vcl.opengl", "init with pixmap"); + m_aGLWin.dpy = dpy; + m_aGLWin.Width = width; + m_aGLWin.Height = height; + m_aGLWin.pix = pix; + const int attrib_list[] = {None}; + int best_fbc = -1; + GLXFBConfig* config = getFBConfigForPixmap(dpy, best_fbc, mbUseDoubleBufferedRendering, nScreen); + if (best_fbc == -1) + return false; + + m_aGLWin.vi = glXGetVisualFromFBConfig( dpy, config[best_fbc] ); + m_aGLWin.glPix = glXCreatePixmap(dpy, config[best_fbc], pix, attrib_list); + + mbPixmap = true; + + initOpenGLFunctionPointers(); + + return ImplInit(); +} + bool OpenGLContext::ImplInit() { SAL_INFO("vcl.opengl", "OpenGLContext::ImplInit----start"); #ifdef DBG_UTIL - if (glXCreateContextAttribsARB && !mbRequestLegacyContext) + if (!mbPixmap && glXCreateContextAttribsARB && !mbRequestLegacyContext) { int best_fbc = -1; GLXFBConfig* pFBC = getFBConfig(m_aGLWin.dpy, m_aGLWin.win, best_fbc, mbUseDoubleBufferedRendering); @@ -561,6 +642,7 @@ bool OpenGLContext::ImplInit() } #endif + if (!m_aGLWin.ctx) { GLXContext pSharedCtx( NULL ); @@ -579,13 +661,15 @@ bool OpenGLContext::ImplInit() if( m_aGLWin.ctx ) vShareList.push_back( m_aGLWin.ctx ); } + + if( m_aGLWin.ctx == NULL ) { SAL_WARN("vcl.opengl", "unable to create GLX context"); return false; } - if( !glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx ) ) + if( !glXMakeCurrent( m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win, m_aGLWin.ctx ) ) { SAL_WARN("vcl.opengl", "unable to select current GLX context"); return false; @@ -979,7 +1063,7 @@ void OpenGLContext::makeCurrent() #elif defined( IOS ) || defined( ANDROID ) // nothing #elif defined( UNX ) - if (!glXMakeCurrent( m_aGLWin.dpy, m_aGLWin.win, m_aGLWin.ctx )) + if (!glXMakeCurrent( m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win, m_aGLWin.ctx )) SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed"); #endif } @@ -1007,7 +1091,7 @@ void OpenGLContext::swapBuffers() #elif defined( IOS ) || defined( ANDROID ) // nothing #elif defined( UNX ) - glXSwapBuffers(m_aGLWin.dpy, m_aGLWin.win); + glXSwapBuffers(m_aGLWin.dpy, mbPixmap ? m_aGLWin.glPix : m_aGLWin.win); #endif } diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 2960b63fe3af..bce862562ae4 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -143,11 +143,21 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen ) if( hDrawable_ ) { OpenGLSalGraphicsImpl* pOpenGLImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get()); - if (pOpenGLImpl && m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame)) + if (pOpenGLImpl) { - Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window(); - pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), - aWin, m_nXScreen.getXScreen()); + if (m_pFrame && dynamic_cast<X11WindowProvider*>(m_pFrame)) + { + Window aWin = dynamic_cast<X11WindowProvider*>(m_pFrame)->GetX11Window(); + pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), + aWin, m_nXScreen.getXScreen()); + } + else if (m_pVDev) + { + pOpenGLImpl->GetOpenGLContext().init(GetXDisplay(), + m_pVDev->GetDrawable(), m_pVDev->GetWidth(), m_pVDev->GetHeight(), m_nXScreen.getXScreen()); + } + else + SAL_WARN("vcl.opengl", "what happened here?"); } mpImpl->Init( m_pFrame ); |