summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-12-04 01:50:05 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-12-04 01:57:01 +0000
commit717c023c984e7810395751d5b0e25e1356403142 (patch)
treed6bbc7c92997a18852e1029a4220b4ed7dfcf17b
parentRemove lots of paint debugging - squash me ... (diff)
downloadcore-private/mmeeks/opengl-backbuffer.tar.gz
core-private/mmeeks/opengl-backbuffer.zip
Implement idle GL flushing. private/mmeeks/opengl-backbuffer
Change-Id: I1d3102149cba902e640cbd9bbf47ca66deedbe00
-rw-r--r--vcl/inc/openglgdiimpl.hxx11
-rw-r--r--vcl/opengl/gdiimpl.cxx46
2 files changed, 49 insertions, 8 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index d28074364be1..fad5a07b6aef 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -52,6 +52,8 @@ struct TextureCombo
std::unique_ptr<OpenGLTexture> mpMask;
};
+class OpenGLFlushIdle;
+
class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
{
friend class OpenGLTests;
@@ -73,6 +75,9 @@ protected:
/// Is it someone else's context we shouldn't be fiddling with ?
static bool IsForeignContext(const rtl::Reference<OpenGLContext> &xContext);
+ /// This idle handler is used to swap buffers after rendering.
+ OpenGLFlushIdle *mpFlush;
+
// clipping
vcl::Region maClipRegion;
bool mbUseScissor;
@@ -347,8 +352,12 @@ public:
virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
- /// flush contents of the back-buffer to the screen & swap.
+ /// queue an idle flush of contents of the back-buffer to the screen
virtual void flush() override;
+
+public:
+ /// do flush of contents of the back-buffer to the screen & swap.
+ void doFlush();
};
#endif
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 31813fb7a0af..13ba0c89bb82 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -39,12 +39,33 @@
#include <stdlib.h>
+class OpenGLFlushIdle : public Idle
+{
+ OpenGLSalGraphicsImpl *m_pImpl;
+public:
+ OpenGLFlushIdle( OpenGLSalGraphicsImpl *pImpl )
+ : Idle( "gl idle swap" )
+ , m_pImpl( pImpl )
+ {
+ SetPriority( SchedulerPriority::HIGHEST );
+ }
+ ~OpenGLFlushIdle()
+ {
+ }
+ virtual void Invoke() override
+ {
+ m_pImpl->doFlush();
+ Stop();
+ }
+};
+
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider *pProvider)
: mpContext(nullptr)
, mrParent(rParent)
, mpProvider(pProvider)
, mpFramebuffer(nullptr)
, mpProgram(nullptr)
+ , mpFlush(new OpenGLFlushIdle(this))
, mbUseScissor(false)
, mbUseStencil(false)
, mnLineColor(SALCOLOR_NONE)
@@ -61,13 +82,10 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
{
-#ifdef DBG_UTIL
- if( !IsOffscreen() )
- {
- // Check that all SalGraphics have flushed before being destroyed
- assert( mnDrawCountAtFlush == mnDrawCount );
- }
-#endif
+ if( !IsOffscreen() && mnDrawCountAtFlush != mnDrawCount )
+ VCL_GL_INFO( "Destroying un-flushed on-screen graphics" );
+
+ delete mpFlush;
ReleaseContext();
}
@@ -1946,6 +1964,20 @@ void OpenGLSalGraphicsImpl::flush()
if( IsOffscreen() )
return;
+ // outside of the application's event loop (e.g. IntroWindow)
+ // nothing would trigger paint event handling
+ // => fall back to synchronous painting
+ if( ImplGetSVData()->maAppData.mnDispatchLevel <= 0 )
+ doFlush();
+ else if( !mpFlush->IsActive() )
+ mpFlush->Start();
+}
+
+void OpenGLSalGraphicsImpl::doFlush()
+{
+ if( IsOffscreen() )
+ return;
+
assert( mpWindowContext.is() );
if( !maOffscreenTex )