From 619981fc160a121f11bc95dd1d1eeb13488d2c7f Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Fri, 13 Nov 2015 14:31:09 +0000 Subject: [PATCH] Stage #3 - first cut at flushing the whole buffer across ... --- vcl/inc/openglgdiimpl.hxx | 4 ++ vcl/inc/salgdi.hxx | 1 + vcl/inc/salgdiimpl.hxx | 1 + vcl/opengl/gdiimpl.cxx | 85 +++++++++++++++++++++++++++--- vcl/source/opengl/OpenGLHelper.cxx | 7 +++ 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 2c3c3dc6ca32b..3c24d6defffbd 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -160,6 +160,9 @@ protected: /// retrieve the default context for offscreen rendering static rtl::Reference GetDefaultContext(); + /// flush contents of the back-buffer to the screen & swap. + void FlushAndSwap(); + /// create a new context for rendering to the underlying window virtual rtl::Reference CreateWinContext() = 0; @@ -346,6 +349,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; virtual OpenGLContext *beginPaint() override; + virtual void endPaint() override; private: }; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index edf8875f4ba85..3af0c095958f3 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -439,6 +439,7 @@ public: const OutputDevice *pOutDev ); virtual OpenGLContext *BeginPaint() { return nullptr; } + virtual void EndPaint() { } virtual SystemGraphicsData GetGraphicsData() const = 0; diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index 406f0ce15ba19..4cdf1b3bb8408 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -213,6 +213,7 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) = 0; virtual OpenGLContext *beginPaint() { return nullptr; } + virtual OpenGLContext *endPaint() { } }; #endif diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index ff86249f12171..2d20427f25d24 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -133,6 +133,10 @@ void OpenGLSalGraphicsImpl::Init() } maOffscreenTex = OpenGLTexture(); } + + if( mpWindowContext.is() ) + mpWindowContext.reset(); + mpWindowContext = CreateWinContext(); } // Currently only used to get windows ordering right. @@ -172,12 +176,6 @@ void OpenGLSalGraphicsImpl::PreDraw() void OpenGLSalGraphicsImpl::PostDraw() { - if( mpContext->mnPainting == 0 ) - { - if (!IsOffscreen()) ... -#warning "Trigger re-rendering of the window if we have one" - glFlush(); - } if( mbUseScissor ) glDisable( GL_SCISSOR_TEST ); if( mbUseStencil ) @@ -191,6 +189,15 @@ void OpenGLSalGraphicsImpl::PostDraw() #endif } + if( mpContext->mnPainting == 0 ) + { + if (!IsOffscreen()) + { + SAL_DEBUG("PostDraw flush ?"); + FlushAndSwap(); + } + } + CHECK_GL_ERROR(); OpenGLZone::leave(); } @@ -1848,10 +1855,76 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, OpenGLContext *OpenGLSalGraphicsImpl::beginPaint() { + SAL_DEBUG( "want to rid ourselves of this method" ); AcquireContext(); return mpContext.get(); } +void OpenGLSalGraphicsImpl::FlushAndSwap() +{ + assert( !IsOffscreen() ); + assert( mpContext.is() ); + + OpenGLZone aZone; + +// glFlush(); - not needed + mpWindowContext->makeCurrent(); + CHECK_GL_ERROR(); + + mpWindowContext->AcquireDefaultFramebuffer(); + CHECK_GL_ERROR(); + + glViewport( 0, 0, GetWidth(), GetHeight() ); + ImplInitClipRegion(); + CHECK_GL_ERROR(); + + SalTwoRect aPosAry(0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), + 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight()); + + OpenGLProgram *pProgram = + mpContext->UseProgram( "textureVertexShader", "textureFragmentShader", "" ); + + pProgram->SetTexture( "sampler", maOffscreenTex ); + + GLfloat aTexCoord[8]; + maOffscreenTex.GetCoord( aTexCoord, rPosAry, false ); + pProgram->SetTextureCoord( aTexCoord ); + + long nX1( rPosAry.mnDestX ); + long nY1( rPosAry.mnDestY ); + long nX2( nX1 + rPosAry.mnDestWidth ); + long nY2( nY1 + rPosAry.mnDestHeight ); + const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 }, + { nX2, nY1 }, { nX2, nY2 }}; + + std::vector aVertices(nPoints * 2); + sal_uInt32 i, j; + + for( i = 0, j = 0; i < 4; i++, j += 2 ) + { + aVertices[j] = GLfloat(aPoints[i].mnX); + aVertices[j+1] = GLfloat(aPoints[i].mnY); + } + + pProgram->ApplyMatrix(GetWidth(), GetHeight(), 0.0); + pProgram->SetVertices( &aVertices[0] ); + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + + pProgram->Clean(); + + mpContext->swapBuffers(); +} + +void OpenGLSalGraphicsImpl::endPaint() +{ + assert( !IsOffscreen() ); + + AcquireContext(); + if( mpContext.is() && + mpContext->mnPainting == 0 ) + FlushAndSwap(); +} + bool OpenGLSalGraphicsImpl::IsForeignContext(const rtl::Reference &xContext) { // so far a blunt heuristic: vcl uses shiny new contexts. diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 79833d7de8f1c..f3c7acbcc8a92 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -1086,6 +1086,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) if( pDev->mpGraphics || pDev->AcquireGraphics() ) { OpenGLContext *pContext = pDev->mpGraphics->BeginPaint(); +/* if( pContext ) { assert( pContext->mnPainting >= 0 ); @@ -1093,6 +1094,7 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) pContext->acquire(); pHandle = static_cast( pContext ); } +*/ } } @@ -1101,6 +1103,10 @@ OutputDevice::PaintScope::PaintScope(OutputDevice *pDev) */ void OutputDevice::PaintScope::flush() { + if( pDev->mpGraphics || pDev->AcquireGraphics() ) + pDev->mpGraphics->EndPaint(); + +#if 0 if( pHandle ) { OpenGLContext *pContext = static_cast( pHandle ); @@ -1117,6 +1123,7 @@ void OutputDevice::PaintScope::flush() } pContext->release(); } +#endif } OutputDevice::PaintScope::~PaintScope()