summaryrefslogtreecommitdiff
path: root/vcl/inc
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-11-13 12:00:59 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-12-11 22:53:52 +0000
commite614a1e88b13a8069ea3cf32eb04be7d43bfb335 (patch)
treee8108b1aadf0a1c15b05614a7b24bf295f1fb666 /vcl/inc
parent382eafb5f350111a430318f49594e6162ad49495 (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.hxx8
-rw-r--r--vcl/inc/opengl/win/gdiimpl.hxx1
-rw-r--r--vcl/inc/opengl/x11/gdiimpl.hxx1
-rw-r--r--vcl/inc/openglgdiimpl.hxx44
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