summaryrefslogtreecommitdiff
path: root/vcl/source/opengl/OpenGLContext.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/opengl/OpenGLContext.cxx')
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx124
1 files changed, 112 insertions, 12 deletions
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index caf3d3022293..3eb7d25462dd 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -29,6 +29,9 @@
#include "svdata.hxx"
+#include <opengl/framebuffer.hxx>
+#include <opengl/texture.hxx>
+
using namespace com::sun::star;
// TODO use rtl::Static instead of 'static'
@@ -53,6 +56,9 @@ OpenGLContext::OpenGLContext():
mbRequestLegacyContext(false),
mbUseDoubleBufferedRendering(true),
mbRequestVirtualDevice(false),
+ mpCurrentFramebuffer(NULL),
+ mpFirstFramebuffer(NULL),
+ mpLastFramebuffer(NULL),
mnPainting(0),
mpPrevContext(NULL),
mpNextContext(NULL)
@@ -74,15 +80,6 @@ OpenGLContext::OpenGLContext():
OpenGLContext::~OpenGLContext()
{
-#if defined( WNT )
- if (m_aGLWin.hRC)
- {
- vShareList.erase(std::remove(vShareList.begin(), vShareList.end(), m_aGLWin.hRC));
-
- wglMakeCurrent( m_aGLWin.hDC, 0 );
- wglDeleteContext( m_aGLWin.hRC );
- ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
- }
ImplSVData* pSVData = ImplGetSVData();
if( mpPrevContext )
mpPrevContext->mpNextContext = mpNextContext;
@@ -93,6 +90,15 @@ OpenGLContext::~OpenGLContext()
else
pSVData->maGDIData.mpLastContext = mpPrevContext;
+#if defined( WNT )
+ if (m_aGLWin.hRC)
+ {
+ vShareList.erase(std::remove(vShareList.begin(), vShareList.end(), m_aGLWin.hRC));
+
+ wglMakeCurrent( m_aGLWin.hDC, 0 );
+ wglDeleteContext( m_aGLWin.hRC );
+ ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
+ }
#elif defined( MACOSX )
OpenGLWrapper::resetCurrent();
#elif defined( IOS ) || defined( ANDROID )
@@ -579,6 +585,7 @@ void initOpenGLFunctionPointers()
glXGetVisualFromFBConfig = (XVisualInfo*(*)(Display *dpy, GLXFBConfig config))glXGetProcAddressARB((GLubyte*)"glXGetVisualFromFBConfig"); // try to find a visual for the current set of attributes
glXGetFBConfigAttrib = (int(*)(Display *dpy, GLXFBConfig config, int attribute, int* value))glXGetProcAddressARB((GLubyte*)"glXGetFBConfigAttrib");
glXCreateContextAttribsARB = (GLXContext(*) (Display*, GLXFBConfig, GLXContext, Bool, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");;
+ glXCreatePixmap = (GLXPixmap(*) (Display*, GLXFBConfig, Pixmap, const int*)) glXGetProcAddressARB((const GLubyte *) "glXCreatePixmap");;
}
Visual* getVisual(Display* dpy, Window win)
@@ -663,6 +670,8 @@ bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned
if (!dpy)
return false;
+ initOpenGLFunctionPointers();
+
SAL_INFO("vcl.opengl", "init with pixmap");
m_aGLWin.dpy = dpy;
m_aGLWin.Width = width;
@@ -681,8 +690,6 @@ bool OpenGLContext::init(Display* dpy, Pixmap pix, unsigned int width, unsigned
mbPixmap = true;
- initOpenGLFunctionPointers();
-
return ImplInit();
}
@@ -1203,13 +1210,32 @@ void OpenGLContext::makeCurrent()
// nothing
#elif defined( UNX )
GLXDrawable nDrawable = mbPixmap ? m_aGLWin.glPix : m_aGLWin.win;
+ static int nSwitch = 0;
if (glXGetCurrentContext() == m_aGLWin.ctx &&
glXGetCurrentDrawable() == nDrawable)
{
- SAL_INFO("vcl.opengl", "OpenGLContext::makeCurrent(): Avoid setting the same context");
+ ; // no-op
}
else if (!glXMakeCurrent( m_aGLWin.dpy, nDrawable, m_aGLWin.ctx ))
SAL_WARN("vcl.opengl", "OpenGLContext::makeCurrent failed on drawable " << nDrawable << " pixmap? " << mbPixmap);
+ else
+ {
+ SAL_INFO("vcl.opengl", "******* CONTEXT SWITCH " << ++nSwitch << " *********");
+ ImplSVData* pSVData = ImplGetSVData();
+ if( mpNextContext )
+ {
+ if( mpPrevContext )
+ mpPrevContext->mpNextContext = mpNextContext;
+ else
+ pSVData->maGDIData.mpFirstContext = mpNextContext;
+ mpNextContext->mpPrevContext = mpPrevContext;
+
+ mpPrevContext = pSVData->maGDIData.mpLastContext;
+ mpNextContext = NULL;
+ pSVData->maGDIData.mpLastContext->mpNextContext = this;
+ pSVData->maGDIData.mpLastContext = this;
+ }
+ }
#endif
}
@@ -1282,4 +1308,78 @@ NSOpenGLView* OpenGLContext::getOpenGLView()
}
#endif
+bool OpenGLContext::AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer )
+{
+ if( pFramebuffer != mpCurrentFramebuffer )
+ {
+ // release the attached texture so it's available from the other contexts
+ //if( mpCurrentFramebuffer )
+ // mpCurrentFramebuffer->DetachTexture();
+
+ if( pFramebuffer )
+ pFramebuffer->Bind();
+ else
+ mpCurrentFramebuffer->Unbind();
+ mpCurrentFramebuffer = pFramebuffer;
+ }
+
+ return true;
+}
+
+bool OpenGLContext::AcquireDefaultFramebuffer()
+{
+ return AcquireFramebuffer( NULL );
+}
+
+OpenGLFramebuffer* OpenGLContext::AcquireFramebuffer( const OpenGLTexture& rTexture )
+{
+ OpenGLFramebuffer* pFramebuffer = NULL;
+ OpenGLFramebuffer* pFreeFramebuffer = NULL;
+
+ // check if there is already a framebuffer attached to that texture
+ pFramebuffer = mpLastFramebuffer;
+ while( pFramebuffer )
+ {
+ if( pFramebuffer->IsAttached( rTexture ) )
+ break;
+ if( !pFreeFramebuffer && pFramebuffer->IsFree() )
+ pFreeFramebuffer = pFramebuffer;
+ pFramebuffer = pFramebuffer->mpPrevFramebuffer;
+ }
+
+ // else use the first free framebuffer
+ if( !pFramebuffer && pFreeFramebuffer )
+ pFramebuffer = pFreeFramebuffer;
+
+ // if there isn't any free one, create a new one
+ if( !pFramebuffer )
+ {
+ pFramebuffer = new OpenGLFramebuffer();
+ if( mpLastFramebuffer )
+ {
+ pFramebuffer->mpPrevFramebuffer = mpLastFramebuffer;
+ mpLastFramebuffer->mpNextFramebuffer = pFramebuffer;
+ mpLastFramebuffer = pFramebuffer;
+ }
+ else
+ {
+ mpFirstFramebuffer = pFramebuffer;
+ mpLastFramebuffer = pFramebuffer;
+ }
+ }
+
+ AcquireFramebuffer( pFramebuffer );
+ if( pFramebuffer->IsFree() )
+ pFramebuffer->AttachTexture( rTexture );
+ glViewport( 0, 0, rTexture.GetWidth(), rTexture.GetHeight() );
+
+ return pFramebuffer;
+}
+
+void OpenGLContext::ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer )
+{
+ if( pFramebuffer )
+ pFramebuffer->DetachTexture();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */