summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-11-07 07:32:00 +0100
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-11-10 07:59:32 +0100
commit88cd7f366e35a731c780f94aa2f5435ef061f6a9 (patch)
tree99aa1e4be38dbc41748171791a5e1ef83c4655a1
parente5890fcec5c7fabad07080f1ab2e97ee2526248c (diff)
use GLXPixmap for VirtualDevice
Change-Id: I6397708f164be68bd6561a382115654f90ecd471
-rw-r--r--include/vcl/opengl/OpenGLContext.hxx13
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Common.xcs2
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx94
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx18
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 );