diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-11-13 12:00:59 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-12-11 22:53:52 +0000 |
commit | e614a1e88b13a8069ea3cf32eb04be7d43bfb335 (patch) | |
tree | e8108b1aadf0a1c15b05614a7b24bf295f1fb666 /vcl/inc | |
parent | 382eafb5f350111a430318f49594e6162ad49495 (diff) |
tdf#93529 - move to a Mac-like double-buffered OpenGL model.
This moves us to always rendering to an off-screen texture, and then
(at idle) blitting this to the screen & swapping buffers. Ideally we
should never see any rendering, or flicker again with this approach.
Several fixes are included:
+ avoid multiple OpenGL contexts being created for the same window,
created excessive flicker problems.
+ de-virtualize UseContext - which context we use is less critical.
+ kill 'mbOffscreen' distinction - all VCL rendering is offscreen.
+ implement 'doFlush' and high priority idle flushing.
+ bind stencil buffer for clipping vs. textures - fixing complex
clopping when rendering to virtual-devices, and off-screen.
+ document environment. variables.
+ use white as default background glClear color, but red or
random color for DBGUTIL.
Change-Id: I6be08595b6c8deb7e6db0dbd81308b2c97d2b4ff
Diffstat (limited to 'vcl/inc')
-rw-r--r-- | vcl/inc/opengl/texture.hxx | 8 | ||||
-rw-r--r-- | vcl/inc/opengl/win/gdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/opengl/x11/gdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 44 |
4 files changed, 43 insertions, 11 deletions
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx index f67b3348d14d..e57aa9e32306 100644 --- a/vcl/inc/opengl/texture.hxx +++ b/vcl/inc/opengl/texture.hxx @@ -37,6 +37,8 @@ public: int mnWidth; int mnHeight; GLenum mnFilter; + GLuint mnOptStencil; + bool mbHasOptStencil; std::unique_ptr<std::vector<int>> mpSlotReferences; int mnFreeSlots; @@ -76,7 +78,8 @@ public: } bool InitializeSlots(int nSlotSize); - int FindFreeSlot(); + int FindFreeSlot(); + GLuint AddStencil(); }; class VCL_DLLPUBLIC OpenGLTexture @@ -110,6 +113,9 @@ public: void Bind(); void Unbind(); void Read( GLenum nFormat, GLenum nType, sal_uInt8* pData ); + GLuint AddStencil(); + bool HasStencil() const; + GLuint StencilId() const; void SaveToFile(const OUString& rFileName); diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx index ecefede6e7ea..8102d2ef5c07 100644 --- a/vcl/inc/opengl/win/gdiimpl.hxx +++ b/vcl/inc/opengl/win/gdiimpl.hxx @@ -31,7 +31,6 @@ public: protected: virtual rtl::Reference<OpenGLContext> CreateWinContext() override; - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override; bool RenderTextureCombo(TextureCombo& rCombo, int nX, int nY); diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx index f07468d6a135..eccd0ef06ae9 100644 --- a/vcl/inc/opengl/x11/gdiimpl.hxx +++ b/vcl/inc/opengl/x11/gdiimpl.hxx @@ -29,7 +29,6 @@ public: protected: virtual rtl::Reference<OpenGLContext> CreateWinContext() override; - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) override; bool RenderPixmap(X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY, TextureCombo& rCombo); diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 667b2ec095f0..a1c2a2539352 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -52,12 +52,20 @@ struct TextureCombo std::unique_ptr<OpenGLTexture> mpMask; }; +class OpenGLFlushIdle; + class VCL_DLLPUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl { friend class OpenGLTests; protected: + /// This context is solely for blitting @maOffscreenTex + rtl::Reference<OpenGLContext> mpWindowContext; + + /// This context is whatever is most convenient to render + /// to @maOffscreenTex with. rtl::Reference<OpenGLContext> mpContext; + SalGraphics& mrParent; /// Pointer to the SalFrame or SalVirtualDevice SalGeometryProvider* mpProvider; @@ -67,12 +75,19 @@ 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; bool mbUseStencil; - bool mbOffscreen; + /** + * All rendering happens to this off-screen texture. For + * non-virtual devices, ie. windows - we will blit it and + * swapBuffers later. + */ OpenGLTexture maOffscreenTex; SalColor mnLineColor; @@ -80,6 +95,8 @@ protected: #ifdef DBG_UTIL bool mProgramIsSolidColor; #endif + sal_uInt32 mnDrawCount; + sal_uInt32 mnDrawCountAtFlush; SalColor mProgramSolidColor; double mProgramSolidTransparency; @@ -131,7 +148,10 @@ public: // get the height of the device GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; } - // check whether this instance is used for offscreen rendering + /** + * check whether this instance is used for offscreen (Virtual Device) + * rendering ie. does it need its own context. + */ bool IsOffscreen() const { return mpProvider == nullptr || mpProvider->IsOffScreen(); } // operations to do before painting @@ -144,14 +164,18 @@ protected: bool AcquireContext(); bool ReleaseContext(); - // retrieve the default context for offscreen rendering + /// retrieve the default context for offscreen rendering static rtl::Reference<OpenGLContext> GetDefaultContext(); - // create a new context for window rendering + /// create a new context for rendering to the underlying window virtual rtl::Reference<OpenGLContext> CreateWinContext() = 0; - // check whether the given context can be used by this instance - virtual bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) = 0; + /// check whether the given context can be used for off-screen rendering + bool UseContext( const rtl::Reference<OpenGLContext> &pContext ) + { + return pContext->isInitialized() && // not released by the OS etc. + IsForeignContext( pContext ); // a genuine VCL context. + } public: OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider); @@ -328,8 +352,12 @@ public: virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override; - virtual OpenGLContext *beginPaint() override; -private: + /// queue an idle flush of contents of the back-buffer to the screen + void flush(); + +public: + /// do flush of contents of the back-buffer to the screen & swap. + void doFlush(); }; #endif |