[Libreoffice-commits] core.git: Branch 'feature/lfrb-vcl-opengl' - 1874 commits - accessibility/source android/experimental animations/source apple_remote/source autogen.sh avmedia/Library_avmediagst.mk avmedia/Library_avmedia.mk avmedia/Library_avmediaogl.mk avmedia/Module_avmedia.mk avmedia/source basctl/Module_basctl.mk basctl/source basegfx/source basic/inc basic/Library_sb.mk basic/Module_basic.mk basic/qa basic/source bean/com binaryurp/source bin/check-merged.sh bin/findunusedcode bin/lo-all-static-libs bin/lolcat bin/parse-perfcheck.py bin/refcount_leak.py bin/run bridges/source bridges/test canvas/Library_oglcanvas.mk canvas/source chart2/CppunitTest_chart2_export.mk chart2/CppunitTest_chart2_import.mk chart2/CppunitTest_chart2_xshape.mk chart2/inc chart2/Library_chartcontroller.mk chart2/Library_chartcore.mk chart2/Library_chartopengl.mk chart2/opengl chart2/qa chart2/source chart2/uiconfig cli_ure/source codemaker/source comphelper/Library_comphelper.mk comphelper/qa comphelper/source compilerplugins/clang config_host/config_features.h.in config_host.mk.in configmgr/CppunitTest_configmgr_unit.mk configmgr/qa configmgr/source configure.ac connectivity/com connectivity/CppunitTest_connectivity_commontools.mk connectivity/inc connectivity/qa connectivity/source cppcanvas/CppunitTest_cppcanvas_emfplus.mk cppcanvas/qa cppcanvas/source cppuhelper/qa cppuhelper/source cppuhelper/test cppu/qa cppu/source cpputools/source crashrep/source cui/Library_cui.mk cui/source cui/uiconfig dbaccess/qa dbaccess/source dbaccess/uiconfig desktop/Module_desktop.mk desktop/Package_sbase_sh.mk desktop/Package_scalc_sh.mk desktop/Package_scripts.mk desktop/Package_sdraw_sh.mk desktop/Package_simpress_sh.mk desktop/Package_smath_sh.mk desktop/Package_swriter_sh.mk desktop/source desktop/test desktop/uiconfig desktop/unx desktop/win32 distro-configs/LibreOfficeAndroidAarch64.conf distro-configs/LibreOfficeAndroid.conf distro-configs/LibreOfficeAndroidX86.conf distro-configs/LibreOfficeLinux .conf drawinglayer/source dtrans/source dtrans/test editeng/CppunitTest_editeng_core.mk editeng/CustomTarget_generated.mk editeng/Library_editeng.mk editeng/Module_editeng.mk editeng/source embeddedobj/source embeddedobj/test embedserv/source eventattacher/source extensions/Executable_pluginapp.bin.mk extensions/Library_scn.mk extensions/qa extensions/source extensions/test extensions/uiconfig extensions/workben external/apache-commons external/boost external/cppunit external/firebird external/glm external/icu external/languagetool external/lcms2 external/libabw external/libcdr external/libebook external/libetonyek external/libexttextcat external/libfreehand external/libgltf external/liblangtag external/libmspub external/libmwaw external/libodfgen external/liborcus external/libpagemaker external/librevenge external/libvisio external/libwpd external/libwpg external/libwps external/lpsolve external/Module_external.mk external/mysqlcppconn external/nss external/poppler external/python3 filter/Configuration_filter.mk filter/CppunitTest_filter_eps_test.mk filter/CppunitTest_filter_pcd_test.mk filter/Module_filter.mk filter/qa filter/source filter/uiconfig forms/qa forms/source formula/source fpicker/source framework/inc framework/qa framework/source .gitignore helpcontent2 hwpfilter/source i18nlangtag/source i18npool/source icon-themes/crystal icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/industrial icon-themes/oxygen icon-themes/sifr icon-themes/tango icon-themes/tango_testing idlc/source idl/inc idl/source include/basebmp include/basic include/canvas include/com include/comphelper include/cppuhelper include/drawinglayer include/editeng include/filter include/formula include/jvmfwk include/LibreOfficeKit include/o3tl include/oox include/osl include/package include/rsc include/rtl include/sal include/sax include/sfx2 include/svl include/svtools include/svx include/test include/toolkit include/tools include/ucbhelper include/unotools includ e/vbahelper include/vcl include/xmloff include/xmlreader instsetoo_native/inc_ooohelppack instsetoo_native/inc_openoffice instsetoo_native/inc_sdkoo ios/Executable_LibreOffice.mk ios/experimental io/source io/test javaunohelper/com javaunohelper/source jurt/com jurt/test jvmfwk/plugins jvmfwk/source l10ntools/source librelogo/CustomTarget_librelogo.mk librelogo/Module_librelogo.mk libreofficekit/qa lingucomponent/source linguistic/source linguistic/workben lotuswordpro/source Makefile.fetch Makefile.in mysqlc/source nlpsolver/src nlpsolver/ThirdParty o3tl/qa odk/examples odk/qa offapi/com offapi/UnoApi_offapi.mk officecfg/Configuration_officecfg.mk officecfg/registry oox/source package/inc package/Library_package2.mk package/source postprocess/CustomTarget_registry.mk postprocess/Rdb_services.mk pyuno/CustomTarget_python_shell.mk pyuno/demo pyuno/inc pyuno/source pyuno/zipcore qadevOOo/runner qadevOOo/tests readlicense_oo/docs readlicense_oo/license README.cross registry/source regi stry/tools remotebridges/examples reportbuilder/java reportdesign/inc reportdesign/qa reportdesign/source reportdesign/uiconfig RepositoryExternal.mk Repository.mk RepositoryModule_host.mk ridljar/com rsc/inc rsc/source sal/cppunittester sal/Library_sal.mk sal/osl sal/qa sal/rtl sal/test sal/workben sax/Library_expwrap.mk sax/source sax/test scaddins/source sc/CppunitTest_sc_annotationobj.mk sc/CppunitTest_sc_annotationshapeobj.mk sc/CppunitTest_sc_annotationsobj.mk sc/CppunitTest_sc_cellrangeobj.mk sc/CppunitTest_sc_chart_regression_test.mk sc/CppunitTest_sc_datapilotfieldobj.mk sc/CppunitTest_sc_datapilottableobj.mk sc/CppunitTest_sc_editfieldobj_cell.mk sc/CppunitTest_sc_editfieldobj_header.mk sc/CppunitTest_sc_html_export_test.mk sc/CppunitTest_sc_macros_test.mk sc/CppunitTest_sc_modelobj.mk sc/CppunitTest_sc_namedrangeobj.mk sc/CppunitTest_sc_namedrangesobj.mk sc/CppunitTest_sc_opencl_test.mk sc/CppunitTest_sc_outlineobj.mk sc/CppunitTest_sc_perfobj.mk sc/CppunitTest_sc_rangels t_test.mk sc/CppunitTest_sc_styleloaderobj.mk sc/CppunitTest_sc_subsequent_export_test.mk sc/CppunitTest_sc_tablesheetobj.mk sc/CppunitTest_sc_tablesheetsobj.mk sc/CppunitTest_sc_ucalc.mk sc/inc sc/Library_scfilt.mk sc/Library_sc.mk sc/Library_scopencl.mk sc/Module_sc.mk scp2/AutoInstall.mk scp2/inc scp2/InstallModule_base.mk scp2/InstallModule_calc.mk scp2/InstallModule_crashrep.mk scp2/InstallModule_draw.mk scp2/InstallModule_impress.mk scp2/InstallModule_math.mk scp2/InstallModule_ooo.mk scp2/InstallModule_quickstart.mk scp2/InstallModule_writer.mk scp2/source sc/qa scripting/examples scripting/java scripting/Module_scripting.mk scripting/source sc/source sc/uiconfig sc/workben sd/CppunitTest_sd_export_tests.mk sdext/source sd/inc sd/qa sd/README_REMOTE sd/source sd/uiconfig setup_native/scripts sfx2/inc sfx2/qa sfx2/sdi sfx2/source sfx2/uiconfig shell/Module_shell.mk shell/source slideshow/Library_OGLTrans.mk slideshow/Library_slideshow.mk slideshow/source slideshow/test smokete st/data smoketest/libtest.cxx solenv/bin solenv/doc solenv/gbuild solenv/gcc-wrappers solenv/gdb solenv/inc soltools/cpp soltools/mkdepend sot/source starmath/inc starmath/source starmath/uiconfig stoc/source stoc/test store/source svgio/CppunitTest_svgio.mk svgio/inc svgio/source svl/Library_svl.mk svl/source svtools/langsupport svtools/README svtools/source svtools/uiconfig svx/inc svx/Library_svxcore.mk svx/Library_svx.mk svx/sdi svx/source svx/uiconfig svx/UIConfig_svx.mk svx/util svx/workben sw/AllLangResTarget_sw.mk sw/CppunitTest_sw_filters_test.mk sw/CppunitTest_sw_globalfilter.mk sw/CppunitTest_sw_rtfexport.mk sw/CppunitTest_sw_tox.mk sw/CppunitTest_sw_uiwriter.mk sw/CppunitTest_sw_uwriter.mk swext/mediawiki sw/inc sw/Library_sw.mk sw/Module_sw.mk sw/qa sw/README sw/sdi sw/source sw/uiconfig sysui/CustomTarget_solaris.mk test/Library_test.mk test/source toolkit/qa toolkit/source toolkit/test tools/CppunitTest_tools_test.mk tools/Library_tl.mk tools/qa tools/source touch/Lib rary_libotouch.mk touch/source translations tubes/source ucbhelper/source ucb/source udkapi/com UnoControls/source unodevtools/source unoidl/source unotest/source unotools/CppunitTest_unotools_fontdefs.mk unotools/qa unotools/source unoxml/Library_unoxml.mk unoxml/source unusedcode.easy uui/source vbahelper/Module_vbahelper.mk vbahelper/source vcl/android vcl/Executable_icontest.mk vcl/Executable_outdevgrind.mk vcl/Executable_vcldemo.mk vcl/generic vcl/headless vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Library_vclopengl.mk vcl/Library_vclplug_gen.mk vcl/Library_vclplug_gtk3.mk vcl/Library_vclplug_gtk.mk vcl/Library_vclplug_kde4.mk vcl/Library_vclplug_kde.mk vcl/Module_vcl.mk vcl/opengl vcl/osx vcl/Package_fontunxppds.mk vcl/Package_opengl.mk vcl/qa vcl/quartz vcl/source vcl/unx vcl/win vcl/workben winaccessibility/source wizards/com wizards/source writerfilter/inc writerfilter/qa writerfilter/source writerperfect/Library_wpftdraw.mk writerperfect/Library_wpftimpress.mk writerperfect/Li brary_wpftwriter.mk writerperfect/qa writerperfect/source xmerge/source xmlhelp/source xmloff/dtd xmloff/inc xmloff/source xmlscript/source xmlscript/test xmlsecurity/source xmlsecurity/test_docs
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Wed Nov 26 06:28:05 PST 2014
Rebased ref, commits from common ancestor:
commit 88001441d3c3e7182caad3b557992371ca1dffe1
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Wed Nov 26 09:22:25 2014 -0500
vcl: Use the current OpenGL context for VirtualDevice and Bitmap if possible
Change-Id: I17f6ce66fb8b5bc027d35b4016ae56c24ee0a738
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 9be9c59..1b21851 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -55,6 +55,9 @@ class NSOpenGLView;
#include <tools/gen.hxx>
#include <vcl/syschild.hxx>
+class OpenGLFramebuffer;
+class OpenGLTexture;
+
/// Holds the information of our new child window
struct GLWindow
{
@@ -177,6 +180,13 @@ public:
void AddRef();
void DeRef();
+ // use these methods right after setting a context to make sure drawing happens
+ // in the right FBO (default one is for onscreen painting)
+ bool AcquireDefaultFramebuffer();
+ bool AcquireFramebuffer( OpenGLFramebuffer* pFramebuffer );
+ OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
+ void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
+
void makeCurrent();
void resetCurrent();
void swapBuffers();
@@ -229,6 +239,11 @@ private:
bool mbPixmap; // is a pixmap instead of a window
#endif
+ int mnFramebufferCount;
+ OpenGLFramebuffer* mpCurrentFramebuffer;
+ OpenGLFramebuffer* mpFirstFramebuffer;
+ OpenGLFramebuffer* mpLastFramebuffer;
+
public:
vcl::Region maClipRegion;
int mnPainting;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 81f774a..a231dae 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -125,6 +125,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/gdiimpl \
vcl/opengl/salbmp \
vcl/opengl/scale \
+ vcl/opengl/framebuffer \
vcl/opengl/texture \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 76be2c1..29695e9 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -107,6 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/x11/x11sys \
vcl/unx/x11/xlimits \
vcl/opengl/x11/gdiimpl \
+ vcl/opengl/x11/salvd \
))
# ultimately we want to split the x11 dependencies out
diff --git a/vcl/inc/opengl/framebuffer.hxx b/vcl/inc/opengl/framebuffer.hxx
new file mode 100644
index 0000000..4ccc1c5
--- /dev/null
+++ b/vcl/inc/opengl/framebuffer.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+#define INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+
+#include <GL/glew.h>
+#include <vcl/dllapi.h>
+
+#include <opengl/texture.hxx>
+
+class VCL_PLUGIN_PUBLIC OpenGLFramebuffer
+{
+private:
+ GLuint mnId;
+ OpenGLTexture maAttachedTexture;
+
+public:
+ OpenGLFramebuffer();
+ virtual ~OpenGLFramebuffer();
+
+ GLuint Id() const { return mnId; };
+
+ void Bind();
+ void Unbind();
+
+ bool IsFree() const;
+ bool IsAttached( const OpenGLTexture& rTexture ) const;
+ void AttachTexture( const OpenGLTexture& rTexture );
+ void DetachTexture();
+
+public:
+ OpenGLFramebuffer* mpPrevFramebuffer;
+ OpenGLFramebuffer* mpNextFramebuffer;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_FRAMEBUFFER_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 972fee0..7efa94b 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -39,6 +39,7 @@ class BitmapPalette;
class VCL_PLUGIN_PUBLIC OpenGLSalBitmap : public SalBitmap
{
private:
+ OpenGLContext* mpContext;
OpenGLTexture maTexture;
bool mbDirtyTexture;
BitmapPalette maPalette;
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index eb003cf..ad4738a 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -22,6 +22,9 @@
#include <GL/glew.h>
#include <vcl/dllapi.h>
+#include <vcl/salgtype.hxx>
+
+#include <tools/gen.hxx>
class ImplOpenGLTexture
{
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index f5e5bfb..53ebe5b 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -31,8 +31,8 @@ protected:
bool IsOffscreen() const SAL_OVERRIDE;
virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
- virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
+ virtual bool UseContext( OpenGLContext* pContext ) SAL_OVERRIDE;
public:
// implementation of X11GraphicsImpl
diff --git a/vcl/inc/opengl/x11/salvd.hxx b/vcl/inc/opengl/x11/salvd.hxx
new file mode 100644
index 0000000..0d7143b
--- /dev/null
+++ b/vcl/inc/opengl/x11/salvd.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+#define INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+
+#include <prex.h>
+#include <postx.h>
+
+#include <unx/saltype.h>
+#include <salvd.hxx>
+
+class SalDisplay;
+class X11OpenGLSalGraphics;
+
+class X11OpenGLSalVirtualDevice : public SalVirtualDevice
+{
+ SalDisplay *mpDisplay;
+ X11SalGraphics *mpGraphics;
+ bool mbGraphics; // is Graphics used
+ SalX11Screen mnXScreen;
+ int mnWidth;
+ int mnHeight;
+ sal_uInt16 mnDepth;
+
+public:
+ X11OpenGLSalVirtualDevice( SalGraphics *pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData );
+ virtual ~X11OpenGLSalVirtualDevice();
+
+ SalDisplay * GetDisplay() const { return mpDisplay; }
+ sal_uInt16 GetDepth() const { return mnDepth; }
+ int GetWidth() const { return mnWidth; }
+ int GetHeight() const { return mnHeight; }
+ SalX11Screen GetXScreenNumber() const { return mnXScreen; }
+
+ virtual SalGraphics* AcquireGraphics() SAL_OVERRIDE;
+ virtual void ReleaseGraphics( SalGraphics* pGraphics ) SAL_OVERRIDE;
+
+ // Set new size, without saving the old contents
+ virtual bool SetSize( long nNewDX, long nNewDY ) SAL_OVERRIDE;
+ virtual void GetSize( long& rWidth, long& rHeight ) SAL_OVERRIDE;
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_X11_SALVD_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index ee7889e..90edf5f 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -23,6 +23,7 @@
#include "salgdiimpl.hxx"
#include <vcl/dllapi.h>
+#include "opengl/framebuffer.hxx"
#include "opengl/texture.hxx"
#include "regionband.hxx"
@@ -37,6 +38,7 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
protected:
OpenGLContext* mpContext;
+ OpenGLFramebuffer* mpFramebuffer;
// clipping
vcl::Region maClipRegion;
@@ -156,23 +158,23 @@ public:
virtual void PostDraw();
protected:
- bool AcquireContext( bool bOffscreen );
+ bool AcquireContext();
bool ReleaseContext();
// create a new context for window rendering
virtual OpenGLContext* CreateWinContext() = 0;
- // check whether the given context can be used by this instance
- virtual bool CompareWinContext( OpenGLContext* pContext ) = 0;
-
- // create a new context for window rendering
+ // create a new context for offscreen rendering
virtual OpenGLContext* CreatePixmapContext() = 0;
+ // check whether the given context can be used by this instance
+ virtual bool UseContext( OpenGLContext* pContext ) = 0;
+
public:
OpenGLSalGraphicsImpl();
virtual ~OpenGLSalGraphicsImpl ();
- OpenGLContext& GetOpenGLContext() { return *mpContext; }
+ OpenGLContext* GetOpenGLContext();
virtual void Init() SAL_OVERRIDE;
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 8ef42ba..edf47b1 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -46,6 +46,7 @@ class X11Pixmap;
class X11SalVirtualDevice;
class X11SalGraphicsImpl;
class X11OpenGLSalGraphicsImpl;
+class X11OpenGLSalVirtualDevice;
class PspSalPrinter;
class PspSalInfoPrinter;
class ServerFont;
@@ -73,7 +74,7 @@ private:
protected:
SalFrame* m_pFrame; // the SalFrame which created this Graphics or NULL
- X11SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
+ SalVirtualDevice* m_pVDev; // the SalVirtualDevice which created this Graphics or NULL
const SalColormap* m_pColormap;
SalColormap *m_pDeleteColormap;
@@ -123,6 +124,7 @@ public:
void Init( SalFrame *pFrame, Drawable aDrawable, SalX11Screen nXScreen );
void Init( X11SalVirtualDevice *pVirtualDevice, SalColormap* pColormap = NULL, bool bDeleteColormap = false );
+ void Init( X11OpenGLSalVirtualDevice *pVirtualDevice );
void Init( class ImplSalPrinterData *pPrinter );
void DeInit();
diff --git a/vcl/inc/unx/salvd.h b/vcl/inc/unx/salvd.h
index dd84c35..b1caa68 100644
--- a/vcl/inc/unx/salvd.h
+++ b/vcl/inc/unx/salvd.h
@@ -44,19 +44,12 @@ class X11SalVirtualDevice : public SalVirtualDevice
bool bExternPixmap_;
public:
- X11SalVirtualDevice();
+ X11SalVirtualDevice( SalGraphics *pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData );
virtual ~X11SalVirtualDevice();
- bool Init( SalDisplay *pDisplay,
- long nDX, long nDY,
- sal_uInt16 nBitCount,
- SalX11Screen nXScreen,
- Pixmap hDrawable = None,
- XRenderPictFormat* pXRenderFormat = NULL );
- void InitGraphics( X11SalVirtualDevice *pVD )
- {
- pGraphics_->Init( pVD );
- }
Display *GetXDisplay() const
{
return pDisplay_->GetDisplay();
diff --git a/vcl/opengl/framebuffer.cxx b/vcl/opengl/framebuffer.cxx
new file mode 100644
index 0000000..29f9a78
--- /dev/null
+++ b/vcl/opengl/framebuffer.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/log.hxx>
+
+#include <opengl/framebuffer.hxx>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+OpenGLFramebuffer::OpenGLFramebuffer() :
+ mnId( 0 ),
+ mpPrevFramebuffer( NULL ),
+ mpNextFramebuffer( NULL )
+{
+ glGenFramebuffers( 1, &mnId );
+ SAL_INFO( "vcl.opengl", "Created framebuffer " << (int)mnId );
+}
+
+OpenGLFramebuffer::~OpenGLFramebuffer()
+{
+ glDeleteFramebuffers( 1, &mnId );
+}
+
+void OpenGLFramebuffer::Bind()
+{
+ glBindFramebuffer( GL_FRAMEBUFFER, mnId );
+ SAL_INFO( "vcl.opengl", "Binding framebuffer " << (int)mnId );
+ CHECK_GL_ERROR();
+}
+
+void OpenGLFramebuffer::Unbind()
+{
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ SAL_INFO( "vcl.opengl", "Binding default framebuffer" );
+ CHECK_GL_ERROR();
+}
+
+bool OpenGLFramebuffer::IsFree() const
+{
+ return (!maAttachedTexture);
+}
+
+bool OpenGLFramebuffer::IsAttached( const OpenGLTexture& rTexture ) const
+{
+ return ( maAttachedTexture == rTexture );
+}
+
+void OpenGLFramebuffer::AttachTexture( const OpenGLTexture& rTexture )
+{
+ SAL_INFO( "vcl.opengl", "Attaching texture " << rTexture.Id() << " to framebuffer " << (int)mnId );
+ maAttachedTexture = rTexture;
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ maAttachedTexture.Id(), 0 );
+ CHECK_GL_ERROR();
+}
+
+void OpenGLFramebuffer::DetachTexture()
+{
+ maAttachedTexture = OpenGLTexture();
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 );
+ CHECK_GL_ERROR();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 8f4c6c4..28f7959 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -65,10 +65,10 @@
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
: mpContext(0)
+ , mpFramebuffer(NULL)
, mbUseScissor(false)
, mbUseStencil(false)
, mbOffscreen(false)
- , mnFramebufferId(0)
, mnLineColor(SALCOLOR_NONE)
, mnFillColor(SALCOLOR_NONE)
, mnSolidProgram(0)
@@ -112,24 +112,25 @@ OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
ReleaseContext();
}
-bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
+OpenGLContext* OpenGLSalGraphicsImpl::GetOpenGLContext()
+{
+ if( !mpContext )
+ AcquireContext();
+ return mpContext;
+}
+
+bool OpenGLSalGraphicsImpl::AcquireContext( )
{
ImplSVData* pSVData = ImplGetSVData();
if( mpContext )
mpContext->DeRef();
- if( bOffscreen )
- {
- mpContext = CreatePixmapContext();
- return (mpContext != NULL);
- }
-
OpenGLContext* pContext = pSVData->maGDIData.mpLastContext;
while( pContext )
{
// check if this context can be used by this SalGraphicsImpl instance
- if( CompareWinContext( pContext ) )
+ if( UseContext( pContext ) )
break;
pContext = pContext->mpPrevContext;
}
@@ -137,7 +138,7 @@ bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
if( pContext )
pContext->AddRef();
else
- pContext = CreateWinContext();
+ pContext = mbOffscreen ? CreatePixmapContext() : CreateWinContext();
mpContext = pContext;
return (mpContext != NULL);
@@ -153,68 +154,41 @@ bool OpenGLSalGraphicsImpl::ReleaseContext()
void OpenGLSalGraphicsImpl::Init()
{
- const bool bOffscreen = IsOffscreen();
+ mbOffscreen = IsOffscreen();
// check if we can simply re-use the same context
if( mpContext )
{
- if( bOffscreen != mbOffscreen || ( !mbOffscreen && CompareWinContext( mpContext ) ) )
+ if( !UseContext( mpContext ) )
ReleaseContext();
}
- if( !mpContext && !AcquireContext( bOffscreen ) )
+ // reset the offscreen texture
+ if( !mbOffscreen ||
+ maOffscreenTex.GetWidth() != GetWidth() ||
+ maOffscreenTex.GetHeight() != GetHeight() )
{
- SAL_WARN( "vcl.opengl", "Couldn't acquire context for SalGraphics" );
- return;
- }
-
- mpContext->makeCurrent();
-
- if( mbOffscreen == bOffscreen )
- {
- // Nothing more to do for onscreen case
- if( !mbOffscreen )
- return;
-
- // Already enabled and same size
- if( maOffscreenTex.GetWidth() == GetWidth() &&
- maOffscreenTex.GetHeight() == GetHeight() )
- return;
- }
- else
- {
- mbOffscreen = bOffscreen;
- if( bOffscreen )
- glGenFramebuffers( 1, &mnFramebufferId );
- else
- glDeleteFramebuffers( 1, &mnFramebufferId );
- }
-
- // Create/update attached offscreen texture
- if( mbOffscreen )
- {
- glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
- maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
- GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
- if( nStatus != GL_FRAMEBUFFER_COMPLETE )
- SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- CHECK_GL_ERROR();
+ maOffscreenTex = OpenGLTexture();
}
}
void OpenGLSalGraphicsImpl::PreDraw()
{
- assert( mpContext && mpContext->isInitialized() );
+ if( !mpContext && !AcquireContext() )
+ {
+ SAL_WARN( "vcl.opengl", "Couldn't acquire context" );
+ return;
+ }
mpContext->makeCurrent();
- // TODO: lfrb: make sure the render target has the right size
- if( mbOffscreen )
- CheckOffscreenTexture();
+ CHECK_GL_ERROR();
+
+ if( !mbOffscreen )
+ mpContext->AcquireDefaultFramebuffer();
else
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ CheckOffscreenTexture();
CHECK_GL_ERROR();
+
glViewport( 0, 0, GetWidth(), GetHeight() );
ImplInitClipRegion();
@@ -223,15 +197,16 @@ void OpenGLSalGraphicsImpl::PreDraw()
void OpenGLSalGraphicsImpl::PostDraw()
{
- if( mbOffscreen )
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- else if( mpContext->mnPainting == 0 )
+ if( !mbOffscreen && mpContext->mnPainting == 0 )
glFlush();
if( mbUseScissor )
glDisable( GL_SCISSOR_TEST );
if( mbUseStencil )
glDisable( GL_STENCIL_TEST );
+ mpContext->ReleaseFramebuffer( mpFramebuffer );
+ mpFramebuffer = NULL;
+
CHECK_GL_ERROR();
}
@@ -287,6 +262,8 @@ void OpenGLSalGraphicsImpl::ImplInitClipRegion()
glStencilFunc( GL_EQUAL, 1, 0x1 );
glEnable( GL_STENCIL_TEST );
}
+
+ CHECK_GL_ERROR();
}
bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
@@ -379,28 +356,27 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
{
- glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
+ if( !maOffscreenTex )
+ maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
- if( maOffscreenTex.IsUnique() )
+ if( !maOffscreenTex.IsUnique() )
{
- GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
- if( nStatus != GL_FRAMEBUFFER_COMPLETE )
- SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
- return true;
- }
+ SalTwoRect aPosAry;
+ aPosAry.mnSrcX = aPosAry.mnDestX = 0;
+ aPosAry.mnSrcY = aPosAry.mnDestY = 0;
+ aPosAry.mnSrcWidth = aPosAry.mnDestWidth = GetWidth();
+ aPosAry.mnSrcHeight = aPosAry.mnDestHeight = GetHeight();
- SalTwoRect aPosAry;
- aPosAry.mnSrcX = aPosAry.mnDestX = 0;
- aPosAry.mnSrcY = aPosAry.mnDestY = 0;
- aPosAry.mnSrcWidth = aPosAry.mnDestWidth = GetWidth();
- aPosAry.mnSrcHeight = aPosAry.mnDestHeight = GetHeight();
-
- // TODO: lfrb: User GL_ARB_copy_image?
- OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
- glViewport( 0, 0, GetWidth(), GetHeight() );
- DrawTexture( maOffscreenTex, aPosAry );
- maOffscreenTex = aNewTex;
+ // TODO: lfrb: User GL_ARB_copy_image?
+ OpenGLTexture aNewTex = OpenGLTexture( GetWidth(), GetHeight() );
+ mpFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
+ DrawTexture( maOffscreenTex, aPosAry );
+ maOffscreenTex = aNewTex;
+ }
+ else
+ {
+ mpFramebuffer = mpContext->AcquireFramebuffer( maOffscreenTex );
+ }
CHECK_GL_ERROR();
return true;
@@ -1916,13 +1892,17 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
void OpenGLSalGraphicsImpl::beginPaint()
{
- SAL_INFO( "vcl.opengl", "BEGIN PAINT " << this );
+ if( !mpContext && !AcquireContext() )
+ return;
+
mpContext->mnPainting++;
}
void OpenGLSalGraphicsImpl::endPaint()
{
- SAL_INFO( "vcl.opengl", "END PAINT " << this );
+ if( !mpContext && !AcquireContext() )
+ return;
+
mpContext->mnPainting--;
assert( mpContext->mnPainting >= 0 );
if( mpContext->mnPainting == 0 && !mbOffscreen )
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 155757a..127df89 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -35,7 +35,8 @@ static bool isValidBitCount( sal_uInt16 nBitCount )
}
OpenGLSalBitmap::OpenGLSalBitmap()
-: mbDirtyTexture(true)
+: mpContext(NULL)
+, mbDirtyTexture(true)
, mnBits(0)
, mnBytesPerRow(0)
, mnWidth(0)
@@ -472,10 +473,14 @@ OpenGLContext* OpenGLSalBitmap::GetBitmapContext() const
void OpenGLSalBitmap::makeCurrent()
{
- // Always use the default window's context for bitmap
- OpenGLContext* pContext = GetBitmapContext();
- assert(pContext && "Couldn't get default OpenGL context provider");
- pContext->makeCurrent();
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // TODO: make sure we can really use the last used context
+ mpContext = pSVData->maGDIData.mpLastContext;
+ if( !mpContext )
+ mpContext = GetBitmapContext();
+ assert(mpContext && "Couldn't get an OpenGL context");
+ mpContext->makeCurrent();
}
BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
@@ -490,8 +495,6 @@ BitmapBuffer* OpenGLSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
if( !maPendingOps.empty() )
{
- makeCurrent();
-
SAL_INFO( "vcl.opengl", "** Creating texture and reading it back immediatly" );
if( !CreateTexture() || !AllocateUserData() || !ReadTexture() )
return NULL;
diff --git a/vcl/opengl/salvd.cxx b/vcl/opengl/salvd.cxx
new file mode 100644
index 0000000..5e55f35
--- /dev/null
+++ b/vcl/opengl/salvd.cxx
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+void X11SalGraphics::Init( X11OpenGLSalVirtualDevice *pDevice )
+{
+ SalColormap *pOrigDeleteColormap = m_pDeleteColormap;
+
+ SalDisplay *pDisplay = pDevice->GetDisplay();
+ m_nXScreen = pDevice->GetXScreenNumber();
+
+ int nVisualDepth = pDisplay->GetVisual( m_nXScreen ).GetDepth();
+ int nDeviceDepth = pDevice->GetDepth();
+
+ if( pColormap )
+ {
+ m_pColormap = pColormap;
+ if( bDeleteColormap )
+ m_pDeleteColormap = pColormap;
+ }
+ else if( nDeviceDepth == nVisualDepth )
+ m_pColormap = &pDisplay->GetColormap( m_nXScreen );
+ else if( nDeviceDepth == 1 )
+ m_pColormap = m_pDeleteColormap = new SalColormap();
+
+ if (m_pDeleteColormap != pOrigDeleteColormap)
+ delete pOrigDeleteColormap;
+
+ m_pVDev = pDevice;
+ m_pFrame = NULL;
+
+ bWindow_ = pDisplay->IsDisplay();
+ bVirDev_ = true;
+
+ const Drawable aVdevDrawable = pDevice->GetDrawable();
+ SetDrawable( aVdevDrawable, m_nXScreen );
+ mpImpl->Init();
+}
+
+bool X11OpenGLSalVirtualDevice::Init( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData )
+{
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+
+ // TODO Check where a VirtualDevice is created from SystemGraphicsData
+ assert( pData == NULL );
+
+ mpDisplay = GetGenericData()->GetSalDisplay();
+ nDepth_ = nBitCount;
+ mnXScreen = pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
+ GetGenericData()->GetSalDisplay()->GetDefaultXScreen();
+ mnWidth = nDX;
+ mnHeight = nDY;
+ mpGraphics = new X11SalGraphics();
+ mpGraphics->SetLayout( 0 );
+ mpGraphics->Init( this );
+
+ return true;
+}
+
+SalGraphics* X11OpenGLSalVirtualDevice::AcquireGraphics()
+{
+ if( mbGraphics )
+ return NULL;
+
+ if( mpGraphics )
+ mbGraphics = true;
+
+ return mpGraphics;
+}
+
+void X11OpenGLSalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ mbGraphics = false;
+}
+
+bool X11OpenGLSalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ mnWidth = nDX;
+ mnHeigth = nDY;
+ mpGraphics->Init( this );
+}
+
+long X11OpenGLSalVirtualDevice::GetWidth() const
+{
+ return mnWidth;
+}
+
+long X11OpenGLSalVirtualDevice::GetHeight() const
+{
+ return mnHeight;
+}
+
+void X11OpenGLSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
+{
+ rWidth = mnWidth;
+ rHeight = mnHeight;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index 9c52cc2..d396652 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -86,8 +86,8 @@ bool OpenGLSalBitmap::ImplScaleFilter(
const double& rScaleY,
GLenum nFilter )
{
+ OpenGLFramebuffer* pFramebuffer;
GLuint nProgram;
- GLuint nFramebufferId;
GLenum nOldFilter;
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
@@ -96,15 +96,13 @@ bool OpenGLSalBitmap::ImplScaleFilter(
if( nProgram == 0 )
return false;
- glGenFramebuffers( 1, &nFramebufferId );
- glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
- glUseProgram( nProgram );
- glUniform1i( mnTexSamplerUniform, 0 );
-
OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aNewTex.Id(), 0 );
+ pFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
- glViewport( 0, 0, nNewWidth, nNewHeight );
+ glUseProgram( nProgram );
+ glUniform1i( mnTexSamplerUniform, 0 );
+ glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
+ glClear( GL_COLOR_BUFFER_BIT );
maTexture.Bind();
nOldFilter = maTexture.GetFilter();
maTexture.SetFilter( nFilter );
@@ -113,8 +111,7 @@ bool OpenGLSalBitmap::ImplScaleFilter(
maTexture.Unbind();
glUseProgram( 0 );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glDeleteFramebuffers( 1, &nFramebufferId );
+ mpContext->ReleaseFramebuffer( pFramebuffer );
mnWidth = nNewWidth;
mnHeight = nNewHeight;
@@ -167,8 +164,8 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
const double& rScaleY,
const Kernel& aKernel )
{
+ OpenGLFramebuffer* pFramebuffer;
GLfloat* pWeights( 0 );
- GLuint nFramebufferId;
GLuint nProgram;
sal_uInt32 nKernelSize;
GLfloat aOffsets[32];
@@ -181,8 +178,6 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
if( nProgram == 0 )
return false;
- glGenFramebuffers( 1, &nFramebufferId );
- glBindFramebuffer( GL_FRAMEBUFFER, nFramebufferId );
glUseProgram( nProgram );
glUniform1i( mnConvSamplerUniform, 0 );
CHECK_GL_ERROR();
@@ -191,8 +186,7 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
if( mnWidth != nNewWidth )
{
OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, mnHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 );
- CHECK_GL_ERROR();
+ pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
@@ -205,19 +199,19 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
CHECK_GL_ERROR();
- glViewport( 0, 0, nNewWidth, mnHeight );
maTexture.Bind();
maTexture.Draw();
maTexture.Unbind();
maTexture = aScratchTex;
+ mpContext->ReleaseFramebuffer( pFramebuffer );
}
// vertical scaling in final texture
if( mnHeight != nNewHeight )
{
OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, nNewHeight );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, aScratchTex.Id(), 0 );
+ pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex );
for( sal_uInt32 i = 0; i < 16; i++ )
{
@@ -229,17 +223,15 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
CHECK_GL_ERROR();
- glViewport( 0, 0, nNewWidth, nNewHeight );
maTexture.Bind();
maTexture.Draw();
maTexture.Unbind();
maTexture = aScratchTex;
+ mpContext->ReleaseFramebuffer( pFramebuffer );
}
glUseProgram( 0 );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- glDeleteFramebuffers( 1, &nFramebufferId );
mnWidth = nNewWidth;
mnHeight = nNewHeight;
@@ -314,7 +306,8 @@ bool OpenGLSalBitmap::Scale( const double& rScaleX, const double& rScaleY, sal_u
nScaleFlag == BMP_SCALE_LANCZOS )
{
//TODO maUserBuffer.reset();
- if( GetBitmapContext() == NULL )
+ makeCurrent();
+ if( mpContext == NULL )
{
SAL_INFO( "vcl.opengl", "Add ScaleOp to pending operations" );
maPendingOps.push_back( new ScaleOp( this, rScaleX, rScaleY, nScaleFlag ) );
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 605cbd5..73d0943 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -17,6 +17,7 @@
#include "opengl/texture.hxx"
#include "opengl/x11/gdiimpl.hxx"
+#include "opengl/x11/salvd.hxx"
#include <vcl/opengl/OpenGLContext.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
@@ -36,12 +37,7 @@ GLfloat X11OpenGLSalGraphicsImpl::GetWidth() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nWidth;
else if( mrParent.m_pVDev )
- {
- long nWidth = 0;
- long nHeight = 0;
- mrParent.m_pVDev->GetSize( nWidth, nHeight );
- return nWidth;
- }
+ return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetWidth();
return 1;
}
@@ -50,12 +46,7 @@ GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nHeight;
else if( mrParent.m_pVDev )
- {
- long nWidth = 0;
- long nHeight = 0;
- mrParent.m_pVDev->GetSize( nWidth, nHeight );
- return nHeight;
- }
+ return static_cast< X11OpenGLSalVirtualDevice* >(mrParent.m_pVDev)->GetHeight();
return 1;
}
@@ -86,24 +77,29 @@ OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext()
return pContext;
}
-bool X11OpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
-{
- X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
-
- if( !pProvider || !pContext->isInitialized() )
- return false;
- return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
-}
-
OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
{
if( mrParent.m_pVDev == NULL )
return NULL;
- OpenGLContext* pContext = new OpenGLContext();
+ /*OpenGLContext* pContext = new OpenGLContext();
pContext->init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
- mrParent.m_nXScreen.getXScreen() );
- return pContext;
+ mrParent.m_nXScreen.getXScreen() );*/
+ // TODO Create a X11 Pixmap and create a context from it
+ return NULL;
+}
+
+bool X11OpenGLSalGraphicsImpl::UseContext( OpenGLContext* pContext )
+{
+ X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+ if( !pContext->isInitialized() )
+ return false;
+
+ if( !pProvider )
+ return true;
+ else
+ return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
}
void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
diff --git a/vcl/opengl/x11/salvd.cxx b/vcl/opengl/x11/salvd.cxx
new file mode 100644
index 0000000..0ea5a75
--- /dev/null
+++ b/vcl/opengl/x11/salvd.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <vcl/sysdata.hxx>
+
+#include <unx/salunx.h>
+#include <unx/saldata.hxx>
+#include <unx/saldisp.hxx>
+#include <unx/salgdi.h>
+#include <unx/salvd.h>
+
+#include <opengl/x11/salvd.hxx>
+
+void X11SalGraphics::Init( X11OpenGLSalVirtualDevice *pDevice )
+{
+ SalDisplay *pDisplay = pDevice->GetDisplay();
+
+ m_nXScreen = pDevice->GetXScreenNumber();
+ m_pColormap = &pDisplay->GetColormap( m_nXScreen );
+
+ m_pVDev = pDevice;
+ m_pFrame = NULL;
+
+ bWindow_ = pDisplay->IsDisplay();
+ bVirDev_ = true;
+
+ mpImpl->Init();
+}
+
+X11OpenGLSalVirtualDevice::X11OpenGLSalVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData ) :
+ mnXScreen( 0 )
+{
+ // TODO Do we really need the requested bit count?
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+
+ // TODO Check where a VirtualDevice is created from SystemGraphicsData
+ assert( pData == NULL );
+
+ mpDisplay = GetGenericData()->GetSalDisplay();
+ mnDepth = nBitCount;
+ mnXScreen = pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
+ GetGenericData()->GetSalDisplay()->GetDefaultXScreen();
+ mnWidth = nDX;
+ mnHeight = nDY;
+ mpGraphics = new X11SalGraphics();
+ mpGraphics->SetLayout( 0 );
+ mpGraphics->Init( this );
+}
+
+X11OpenGLSalVirtualDevice::~X11OpenGLSalVirtualDevice()
+{
+ if( mpGraphics )
+ delete mpGraphics;
+}
+
+SalGraphics* X11OpenGLSalVirtualDevice::AcquireGraphics()
+{
+ if( mbGraphics )
+ return NULL;
+
+ if( mpGraphics )
+ mbGraphics = true;
+
+ return mpGraphics;
+}
+
+void X11OpenGLSalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ mbGraphics = false;
+}
+
+bool X11OpenGLSalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ mnWidth = nDX;
+ mnHeight = nDY;
+ mpGraphics->Init( this );
+ return true;
+}
+
+void X11OpenGLSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
+{
+ rWidth = mnWidth;
+ rHeight = mnHeight;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx
index a075b4d..6a85e59 100644
--- a/vcl/source/gdi/salgdilayout.cxx
+++ b/vcl/source/gdi/salgdilayout.cxx
@@ -81,7 +81,7 @@ OpenGLContext* SalGraphics::GetOpenGLContext() const
{
OpenGLSalGraphicsImpl *pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(GetImpl());
if (pImpl)
- return &pImpl->GetOpenGLContext();
+ return pImpl->GetOpenGLContext();
return NULL;
}
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index caf3d30..a0fca30 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 )
@@ -1203,13 +1209,30 @@ 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;
+ pSVData->maGDIData.mpLastContext = this;
+ }
+ }
#endif
}
@@ -1282,4 +1305,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: */
diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx
index 91c4db7..28beaf4 100644
--- a/vcl/unx/generic/gdi/gdiimpl.cxx
+++ b/vcl/unx/generic/gdi/gdiimpl.cxx
@@ -739,7 +739,7 @@ void X11SalGraphicsImpl::drawMaskedBitmap( const SalTwoRect& rPosAry,
// bitdepth to create pixmaps for, otherwise, XCopyArea will
// refuse to work.
const sal_uInt16 nDepth( mrParent.m_pVDev ?
- mrParent.m_pVDev->GetDepth() :
+ static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() :
pSalDisp->GetVisual( mrParent.m_nXScreen ).GetDepth() );
Pixmap aFG( limitXCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth,
rPosAry.mnDestHeight, nDepth ) );
@@ -861,7 +861,7 @@ bool X11SalGraphicsImpl::drawAlphaBitmap( const SalTwoRect& rTR,
Display* pXDisplay = pSalDisp->GetDisplay();
// create source Picture
- int nDepth = mrParent.m_pVDev ? mrParent.m_pVDev->GetDepth() : rSalVis.GetDepth();
+ int nDepth = mrParent.m_pVDev ? static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() : rSalVis.GetDepth();
const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap );
ImplSalDDB* pSrcDDB = rSrcX11Bmp.ImplGetDDB( mrParent.hDrawable_, mrParent.m_nXScreen, nDepth, rTR );
if( !pSrcDDB )
@@ -988,7 +988,7 @@ bool X11SalGraphicsImpl::drawAlphaRect( long nX, long nY, long nWidth,
if( mbPenGC || !mbBrushGC || mbXORMode )
return false; // can only perform solid fills without XOR.
- if( mrParent.m_pVDev && mrParent.m_pVDev->GetDepth() < 8 )
+ if( mrParent.m_pVDev && static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetDepth() < 8 )
return false;
Picture aDstPic = GetXRenderPicture();
@@ -1575,7 +1575,7 @@ long X11SalGraphicsImpl::GetGraphicsHeight() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nHeight;
else if( mrParent.m_pVDev )
- return mrParent.m_pVDev->GetHeight();
+ return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetHeight();
else
return 0;
}
@@ -1849,7 +1849,7 @@ long X11SalGraphicsImpl::GetGraphicsWidth() const
if( mrParent.m_pFrame )
return mrParent.m_pFrame->maGeometry.nWidth;
else if( mrParent.m_pVDev )
- return mrParent.m_pVDev->GetWidth();
+ return static_cast< X11SalVirtualDevice* >(mrParent.m_pVDev)->GetWidth();
else
return 0;
}
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 3c1a727..e527d6d 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -148,11 +148,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
m_aXRenderPicture = 0;
}
- if( hDrawable_ )
- {
- mpImpl->Init();
- // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
- }
+ // TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
}
void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
@@ -162,6 +158,7 @@ void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget,
m_nXScreen = nXScreen;
m_pFrame = pFrame;
SetDrawable( aTarget, nXScreen );
+ mpImpl->Init();
bWindow_ = true;
m_pVDev = NULL;
diff --git a/vcl/unx/generic/gdi/salvd.cxx b/vcl/unx/generic/gdi/salvd.cxx
index 71ec509..7967a4d 100644
--- a/vcl/unx/generic/gdi/salvd.cxx
+++ b/vcl/unx/generic/gdi/salvd.cxx
@@ -32,49 +32,17 @@
#include <salinst.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include <opengl/x11/salvd.hxx>
+
SalVirtualDevice* X11SalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
long nDX, long nDY,
sal_uInt16 nBitCount, const SystemGraphicsData *pData )
{
- X11SalVirtualDevice *pVDev = new X11SalVirtualDevice();
- if( !nBitCount && pGraphics )
- nBitCount = pGraphics->GetBitCount();
-
- if( pData && pData->hDrawable != None )
- {
- ::Window aRoot;
- int x, y;
- unsigned int w = 0, h = 0, bw, d;
- Display* pDisp = GetGenericData()->GetSalDisplay()->GetDisplay();
- XGetGeometry( pDisp, pData->hDrawable,
- &aRoot, &x, &y, &w, &h, &bw, &d );
- int nScreen = 0;
- while( nScreen < ScreenCount( pDisp ) )
- {
- if( RootWindow( pDisp, nScreen ) == aRoot )
- break;
- nScreen++;
- }
- nDX = (long)w;
- nDY = (long)h;
- if( !pVDev->Init( GetGenericData()->GetSalDisplay(), nDX, nDY, nBitCount,
- SalX11Screen( nScreen ), pData->hDrawable,
- static_cast< XRenderPictFormat* >( pData->pXRenderFormat )) )
- {
- delete pVDev;
- return NULL;
- }
- }
- else if( !pVDev->Init( GetGenericData()->GetSalDisplay(), nDX, nDY, nBitCount,
- pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
- GetGenericData()->GetSalDisplay()->GetDefaultXScreen() ) )
- {
- delete pVDev;
- return NULL;
- }
-
- pVDev->InitGraphics( pVDev );
- return pVDev;
+ if (OpenGLHelper::isVCLOpenGLEnabled())
+ return new X11OpenGLSalVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
+ else
+ return new X11SalVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
}
void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
@@ -110,66 +78,78 @@ void X11SalGraphics::Init( X11SalVirtualDevice *pDevice, SalColormap* pColormap,
const Drawable aVdevDrawable = pDevice->GetDrawable();
SetDrawable( aVdevDrawable, m_nXScreen );
+ mpImpl->Init();
}
-bool X11SalVirtualDevice::Init( SalDisplay *pDisplay,
- long nDX, long nDY,
- sal_uInt16 nBitCount,
- SalX11Screen nXScreen,
- Pixmap hDrawable,
- XRenderPictFormat* pXRenderFormat )
+X11SalVirtualDevice::X11SalVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY,
+ sal_uInt16 nBitCount,
+ const SystemGraphicsData *pData ) :
+ m_nXScreen( 0 ),
+ bGraphics_( false )
{
SalColormap* pColormap = NULL;
bool bDeleteColormap = false;
- pDisplay_ = pDisplay;
+ if( !nBitCount && pGraphics )
+ nBitCount = pGraphics->GetBitCount();
+
+ pDisplay_ = GetGenericData()->GetSalDisplay();
pGraphics_ = new X11SalGraphics();
- m_nXScreen = nXScreen;
- if( pXRenderFormat ) {
+ nDepth_ = nBitCount;
+
+ if( pData && pData->hDrawable != None )
+ {
+ ::Window aRoot;
+ int x, y;
+ unsigned int w = 0, h = 0, bw, d;
+ Display* pDisp = pDisplay_->GetDisplay();
+ XGetGeometry( pDisp, pData->hDrawable,
+ &aRoot, &x, &y, &w, &h, &bw, &d );
+ int nScreen = 0;
+ while( nScreen < ScreenCount( pDisp ) )
+ {
+ if( RootWindow( pDisp, nScreen ) == aRoot )
+ break;
+ nScreen++;
+ }
+ nDX_ = (long)w;
+ nDY_ = (long)h;
+ m_nXScreen = SalX11Screen( nScreen );
+ hDrawable_ = pData->hDrawable;
+ bExternPixmap_ = true;
+ }
+ else
+ {
+ nDX_ = nDX;
+ nDY_ = nDY;
+ m_nXScreen = pGraphics ? static_cast<X11SalGraphics*>(pGraphics)->GetScreenNumber() :
+ GetGenericData()->GetSalDisplay()->GetDefaultXScreen();
+ hDrawable_ = limitXCreatePixmap( GetXDisplay(),
+ pDisplay_->GetDrawable( m_nXScreen ),
+ nDX_, nDY_,
+ GetDepth() );
+ bExternPixmap_ = false;
+ }
+
+ XRenderPictFormat* pXRenderFormat = pData ? static_cast<XRenderPictFormat*>(pData->pXRenderFormat) : NULL;
+ if( pXRenderFormat )
+ {
pGraphics_->SetXRenderFormat( pXRenderFormat );
if( pXRenderFormat->colormap )
- pColormap = new SalColormap( pDisplay, pXRenderFormat->colormap, m_nXScreen );
+ pColormap = new SalColormap( pDisplay_, pXRenderFormat->colormap, m_nXScreen );
else
pColormap = new SalColormap( nBitCount );
bDeleteColormap = true;
}
- else if( nBitCount != pDisplay->GetVisual( m_nXScreen ).GetDepth() )
+ else if( nBitCount != pDisplay_->GetVisual( m_nXScreen ).GetDepth() )
{
pColormap = new SalColormap( nBitCount );
bDeleteColormap = true;
}
- pGraphics_->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
- nDX_ = nDX;
- nDY_ = nDY;
- nDepth_ = nBitCount;
-
- if( hDrawable == None )
- hDrawable_ = limitXCreatePixmap( GetXDisplay(),
- pDisplay_->GetDrawable( m_nXScreen ),
- nDX_, nDY_,
- GetDepth() );
- else
- {
- hDrawable_ = hDrawable;
- bExternPixmap_ = true;
- }
+ pGraphics_->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
pGraphics_->Init( this, pColormap, bDeleteColormap );
-
- return hDrawable_ != None;
-}
-
-X11SalVirtualDevice::X11SalVirtualDevice() :
- m_nXScreen( 0 )
-{
- pDisplay_ = NULL;
- pGraphics_ = NULL;
- hDrawable_ = None;
- nDX_ = 0;
- nDY_ = 0;
- nDepth_ = 0;
- bGraphics_ = false;
- bExternPixmap_ = false;
}
X11SalVirtualDevice::~X11SalVirtualDevice()
@@ -196,8 +176,6 @@ SalGraphics* X11SalVirtualDevice::AcquireGraphics()
void X11SalVirtualDevice::ReleaseGraphics( SalGraphics* )
{ bGraphics_ = false; }
-#include "opengl/x11/gdiimpl.hxx"
-
bool X11SalVirtualDevice::SetSize( long nDX, long nDY )
{
if( bExternPixmap_ )
@@ -231,14 +209,7 @@ bool X11SalVirtualDevice::SetSize( long nDX, long nDY )
nDY_ = nDY;
if( pGraphics_ )
- {
- InitGraphics( this );
-
- // re-initialize OpenGLContext [!] having freed it's underlying pixmap above
- X11OpenGLSalGraphicsImpl *pImpl = dynamic_cast< X11OpenGLSalGraphicsImpl* >(pGraphics_->GetImpl());
- if( pImpl )
- pImpl->Init();
- }
+ pGraphics_->Init( this );
return true;
}
commit 07eea5d1b0eb0265f43c6d8d63d775a316f9b42a
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 08:11:33 2014 -0500
vcl: Make sure the active framebuffer is the right one before drawing
Change-Id: Icc30bee1d58dbf8f5e7b65ba90cfdf0c9135b464
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 85d2a1c..8f4c6c4 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -212,6 +212,9 @@ void OpenGLSalGraphicsImpl::PreDraw()
// TODO: lfrb: make sure the render target has the right size
if( mbOffscreen )
CheckOffscreenTexture();
+ else
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ CHECK_GL_ERROR();
glViewport( 0, 0, GetWidth(), GetHeight() );
ImplInitClipRegion();
commit aff5f1973421e661791a81a74d28e8a2e80cef8b
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 08:10:48 2014 -0500
vcl: Re-flip native X11 widgets upside down in OpenGL backend
Change-Id: I1819f8e3357dc2f805b0ecebca0659fe073ec611
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index b04bab6..605cbd5 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -199,14 +199,14 @@ bool X11OpenGLSalGraphicsImpl::RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixm
glXBindTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT, NULL );
aMaskTexture.Unbind();
- DrawTextureDiff( aTexture, aMaskTexture, aPosAry, !bInverted );
+ DrawTextureDiff( aTexture, aMaskTexture, aPosAry, bInverted );
glXReleaseTexImageEXT( pDisplay, pGlxMask, GLX_FRONT_LEFT_EXT );
glXDestroyPixmap( pDisplay, pGlxMask );
}
else
{
- DrawTexture( aTexture, aPosAry, !bInverted );
+ DrawTexture( aTexture, aPosAry, bInverted );
}
CHECK_GL_ERROR();
commit 11b2007fc5a827228822150a66b53997e67d0287
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 08:09:29 2014 -0500
vcl: Improve precision and performance of clipping when region is a RegionBand
Change-Id: I7a481ba86d03b0eb8f4b456e38cfa89b6cbc209d
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index a6495b7..ee7889e 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -24,6 +24,7 @@
#include <vcl/dllapi.h>
#include "opengl/texture.hxx"
+#include "regionband.hxx"
#include <tools/poly.hxx>
#include <vcl/opengl/OpenGLContext.hxx>
@@ -125,6 +126,7 @@ public:
void DrawRect( const Rectangle& rRect );
void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
+ void DrawRegionBand( const RegionBand& rRegion );
void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f7b8bdf..85d2a1c 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -247,7 +247,10 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
glClear( GL_STENCIL_BUFFER_BIT );
BeginSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) );
- DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
+ if( rClip.getRegionBand() )
+ DrawRegionBand( *rClip.getRegionBand() );
+ else
+ DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
EndSolid();
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
@@ -793,6 +796,41 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
CHECK_GL_ERROR();
}
+void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
+{
+ RectangleVector aRects;
+ std::vector<GLfloat> aVertices;
+ rRegion.GetRegionRectangles( aRects );
+
+ if( aRects.empty() )
+ return;
+
+#define ADD_VERTICE(pt) \
+ aVertices.push_back( 2 * pt.X() / GetWidth() - 1.0 ); \
+ aVertices.push_back( 1.0 - (2 * pt.Y() / GetHeight()) );
+
+ for( size_t i = 0; i < aRects.size(); ++i )
+ {
+ aRects[i].Bottom() += 1;
+ aRects[i].Right() += 1;
+ ADD_VERTICE( aRects[i].TopLeft() );
+ ADD_VERTICE( aRects[i].TopRight() );
+ ADD_VERTICE( aRects[i].BottomLeft() );
+ ADD_VERTICE( aRects[i].BottomLeft() );
+ ADD_VERTICE( aRects[i].TopRight() );
+ ADD_VERTICE( aRects[i].BottomRight() );
+ }
+
+#undef ADD_VERTICE
+
+ glEnableVertexAttribArray( GL_ATTRIB_POS );
+ glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
+ glDisableVertexAttribArray( GL_ATTRIB_POS );
+
+ CHECK_GL_ERROR();
+}
+
void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted )
{
GLfloat aTexCoord[8];
commit 6563a9071d6da2cc92f4967da7be5f6f67154081
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 08:07:47 2014 -0500
vcl: Track the GL context's clip region and update before drawing when needed
Change-Id: Ibec92851dc87f6696ee55a8db10fe160cd97d09c
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index b790453..9be9c59 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -230,6 +230,7 @@ private:
#endif
public:
+ vcl::Region maClipRegion;
int mnPainting;
OpenGLContext* mpPrevContext;
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 7446903..a6495b7 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -38,6 +38,7 @@ protected:
OpenGLContext* mpContext;
// clipping
+ vcl::Region maClipRegion;
bool mbUseScissor;
bool mbUseStencil;
@@ -91,6 +92,7 @@ protected:
GLuint mnRadialGradientEndColorUniform;
GLuint mnRadialGradientCenterUniform;
+ void ImplInitClipRegion();
void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
bool CheckOffscreenTexture();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 1151b73..f7b8bdf 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -213,13 +213,7 @@ void OpenGLSalGraphicsImpl::PreDraw()
if( mbOffscreen )
CheckOffscreenTexture();
glViewport( 0, 0, GetWidth(), GetHeight() );
- if( mbUseScissor )
- glEnable( GL_SCISSOR_TEST );
- if( mbUseStencil )
- {
- glStencilFunc( GL_EQUAL, 1, 0x1 );
- glEnable( GL_STENCIL_TEST );
- }
+ ImplInitClipRegion();
CHECK_GL_ERROR();
}
@@ -263,36 +257,44 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
CHECK_GL_ERROR();
}
-bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
+void OpenGLSalGraphicsImpl::ImplInitClipRegion()
{
- SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip );
-
- if( rClip.IsEmpty() )
+ // make sure the context has the right clipping set
+ if( maClipRegion != mpContext->maClipRegion )
{
- ResetClipRegion();
- return true;
+ mpContext->maClipRegion = maClipRegion;
+ if( maClipRegion.IsRectangle() )
+ {
+ Rectangle aRect( maClipRegion.GetBoundRect() );
+ glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, aRect.GetWidth() + 1, aRect.GetHeight() + 1 );
+ }
+ else if( !maClipRegion.IsEmpty() )
+ {
+ ImplSetClipBit( maClipRegion, 0x01 );
+ }
}
- if( rClip.IsRectangle() )
+ if( mbUseScissor )
+ glEnable( GL_SCISSOR_TEST );
+ if( mbUseStencil )
{
- Rectangle aRect( rClip.GetBoundRect() );
+ glStencilFunc( GL_EQUAL, 1, 0x1 );
+ glEnable( GL_STENCIL_TEST );
+ }
+}
+
+bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
+{
+ SAL_INFO( "vcl.opengl", "::setClipRegion " << rClip );
+ maClipRegion = rClip;
- mbUseStencil = false;
+ mbUseStencil = false;
+ mbUseScissor = false;
+ if( maClipRegion.IsRectangle() )
mbUseScissor = true;
- maContext.makeCurrent();
- glViewport( 0, 0, GetWidth(), GetHeight() );
- glScissor( aRect.Left(), GetHeight() - aRect.Bottom() - 1, aRect.GetWidth(), aRect.GetHeight() );
- }
- else
- {
+ else if ( !maClipRegion.IsEmpty() )
mbUseStencil = true;
- mbUseScissor = false;
- maContext.makeCurrent();
- glViewport( 0, 0, GetWidth(), GetHeight() );
- ImplSetClipBit( rClip, 0x01 );
- }
- CHECK_GL_ERROR();
return true;
}
@@ -300,6 +302,7 @@ bool OpenGLSalGraphicsImpl::setClipRegion( const vcl::Region& rClip )
void OpenGLSalGraphicsImpl::ResetClipRegion()
{
SAL_INFO( "vcl.opengl", "::ResetClipRegion" );
+ maClipRegion.SetEmpty();
mbUseScissor = false;
mbUseStencil = false;
}
commit 385dd7da3aa1c202ec70e2c3213b6b70ab772108
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 08:04:23 2014 -0500
vcl: Move the painting fence to the OpenGL context
Change-Id: I462e68a1ad7a56fafe57504959cf169a70665f81
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 9414dac..b790453 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -230,6 +230,8 @@ private:
#endif
public:
+ int mnPainting;
+
OpenGLContext* mpPrevContext;
OpenGLContext* mpNextContext;
};
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index a1cd142..7446903 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -35,8 +35,6 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
{
protected:
- SalFrame* mpFrame;
- int mnPainting;
OpenGLContext* mpContext;
// clipping
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6e6ea5f..1151b73 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -228,7 +228,7 @@ void OpenGLSalGraphicsImpl::PostDraw()
{
if( mbOffscreen )
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- else if( mnPainting == 0 )
+ else if( mpContext->mnPainting == 0 )
glFlush();
if( mbUseScissor )
glDisable( GL_SCISSOR_TEST );
@@ -1872,15 +1872,16 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
void OpenGLSalGraphicsImpl::beginPaint()
{
- mnPainting++;
SAL_INFO( "vcl.opengl", "BEGIN PAINT " << this );
+ mpContext->mnPainting++;
}
void OpenGLSalGraphicsImpl::endPaint()
{
- mnPainting--;
SAL_INFO( "vcl.opengl", "END PAINT " << this );
- if( mnPainting == 0 )
+ mpContext->mnPainting--;
+ assert( mpContext->mnPainting >= 0 );
+ if( mpContext->mnPainting == 0 && !mbOffscreen )
{
mpContext->makeCurrent();
glFlush();
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index 9bbe1e2..caf3d30 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -53,6 +53,7 @@ OpenGLContext::OpenGLContext():
mbRequestLegacyContext(false),
mbUseDoubleBufferedRendering(true),
mbRequestVirtualDevice(false),
+ mnPainting(0),
mpPrevContext(NULL),
mpNextContext(NULL)
{
commit e26c8fdd1922282ef5f0ce97b503ef9d7bb9907b
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Sat Nov 22 07:58:38 2014 -0500
vcl: Always use the same OpenGL context when drawing in a window
Change-Id: Ief0e947149c133aaa8e81973e088c4df6432bfdc
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index c5e53e8..9414dac 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -174,6 +174,9 @@ public:
bool init( HDC hDC, HWND hWnd );
#endif
+ void AddRef();
+ void DeRef();
+
void makeCurrent();
void resetCurrent();
void swapBuffers();
@@ -218,12 +221,17 @@ private:
SystemChildWindow* m_pChildWindow;
boost::scoped_ptr<SystemChildWindow> m_pChildWindowGC;
bool mbInitialized;
+ int mnRefCount;
bool mbRequestLegacyContext;
bool mbUseDoubleBufferedRendering;
bool mbRequestVirtualDevice;
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
bool mbPixmap; // is a pixmap instead of a window
#endif
+
+public:
+ OpenGLContext* mpPrevContext;
+ OpenGLContext* mpNextContext;
};
#endif
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index 557e58a..66a0333 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -15,6 +15,8 @@
#include "openglgdiimpl.hxx"
#include "win/salgdi.h"
+class OpenGLContext;
+
class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl
{
friend class WinLayout;
@@ -24,9 +26,16 @@ private:
public:
WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics);
+ virtual void Init() SAL_OVERRIDE;
+
protected:
virtual GLfloat GetWidth() const SAL_OVERRIDE;
virtual GLfloat GetHeight() const SAL_OVERRIDE;
+ virtual bool IsOffscreen() const SAL_OVERRIDE;
+
+ virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
+ virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
+ virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
public:
virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index d25d5d0..f5e5bfb 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -28,12 +28,16 @@ public:
protected:
GLfloat GetWidth() const SAL_OVERRIDE;
GLfloat GetHeight() const SAL_OVERRIDE;
+ bool IsOffscreen() const SAL_OVERRIDE;
+
+ virtual OpenGLContext* CreateWinContext() SAL_OVERRIDE;
+ virtual bool CompareWinContext( OpenGLContext* pContext ) SAL_OVERRIDE;
+ virtual OpenGLContext* CreatePixmapContext() SAL_OVERRIDE;
public:
// implementation of X11GraphicsImpl
virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
- void Init() SAL_OVERRIDE;
bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) SAL_OVERRIDE;
};
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 5a7382b..a1cd142 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -35,9 +35,9 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
{
protected:
- OpenGLContext maContext;
SalFrame* mpFrame;
int mnPainting;
+ OpenGLContext* mpContext;
// clipping
bool mbUseScissor;
@@ -144,21 +144,35 @@ public:
// get the height of the device
virtual GLfloat GetHeight() const = 0;
+ // check whether this instance is used for offscreen rendering
+ virtual bool IsOffscreen() const = 0;
+
// operations to do before painting
virtual void PreDraw();
// operations to do after painting
virtual void PostDraw();
- // enable/disable offscreen rendering
- virtual void SetOffscreen( bool bOffscreen );
+protected:
+ bool AcquireContext( bool bOffscreen );
+ bool ReleaseContext();
+
+ // create a new context for window rendering
+ virtual OpenGLContext* CreateWinContext() = 0;
+ // check whether the given context can be used by this instance
+ virtual bool CompareWinContext( OpenGLContext* pContext ) = 0;
+
+ // create a new context for window rendering
+ virtual OpenGLContext* CreatePixmapContext() = 0;
public:
OpenGLSalGraphicsImpl();
virtual ~OpenGLSalGraphicsImpl ();
- OpenGLContext& GetOpenGLContext() { return maContext; }
+ OpenGLContext& GetOpenGLContext() { return *mpContext; }
+
+ virtual void Init() SAL_OVERRIDE;
virtual void freeResources() SAL_OVERRIDE;
diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx
index 2fd7f56..e92c65f 100644
--- a/vcl/inc/salgdiimpl.hxx
+++ b/vcl/inc/salgdiimpl.hxx
@@ -44,6 +44,8 @@ public:
virtual ~SalGraphicsImpl();
+ virtual void Init() = 0;
+
virtual void freeResources() = 0;
virtual bool setClipRegion( const vcl::Region& ) = 0;
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index c1d9eed..212e036 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -89,6 +89,7 @@ class SalI18NImeStatus;
class DockingManager;
class VclEventListeners2;
class SalData;
+class OpenGLContext;
namespace vcl { class DisplayConnection; class SettingsConfigItem; class DeleteOnDeinitBase; }
@@ -161,6 +162,8 @@ struct ImplSVGDIData
OutputDevice* mpLastPrnGraphics; // Last OutputDevice with a InfoPrinter Graphics
VirtualDevice* mpFirstVirDev; // First VirtualDevice
VirtualDevice* mpLastVirDev; // Last VirtualDevice
+ OpenGLContext* mpFirstContext; // First OpenGLContext
+ OpenGLContext* mpLastContext; // Last OpenGLContext
Printer* mpFirstPrinter; // First Printer
Printer* mpLastPrinter; // Last Printer
ImplPrnQueueList* mpPrinterQueueList; // List of all printer queue
diff --git a/vcl/inc/unx/x11/x11gdiimpl.h b/vcl/inc/unx/x11/x11gdiimpl.h
index 239d217..22859c3 100644
--- a/vcl/inc/unx/x11/x11gdiimpl.h
+++ b/vcl/inc/unx/x11/x11gdiimpl.h
@@ -17,7 +17,6 @@ class X11GraphicsImpl
public:
virtual ~X11GraphicsImpl() {};
- virtual void Init() = 0;
virtual bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) = 0;
virtual bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) = 0;
};
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 1af7807..443c1c2 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -181,6 +181,7 @@ public:
class WinSalGraphics : public SalGraphics
{
friend class WinSalGraphicsImpl;
+ friend class WinOpenGLSalGraphicsImpl;
friend class ScopedFont;
friend class OpenGLCompatibleDC;
friend class WinLayout;
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 54be610..6e6ea5f 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -31,6 +31,7 @@
#include <vcl/opengl/OpenGLHelper.hxx>
#include "salgdi.hxx"
+#include "svdata.hxx"
#include "opengl/salbmp.hxx"
#include <glm/glm.hpp>
@@ -63,8 +64,7 @@
1.0f )
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
- : mpFrame(NULL)
- , mnPainting(0)
+ : mpContext(0)
, mbUseScissor(false)
, mbUseStencil(false)
, mbOffscreen(false)
@@ -109,11 +109,106 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
OpenGLSalGraphicsImpl::~OpenGLSalGraphicsImpl()
{
+ ReleaseContext();
+}
+
+bool OpenGLSalGraphicsImpl::AcquireContext( bool bOffscreen )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if( mpContext )
+ mpContext->DeRef();
+
+ if( bOffscreen )
+ {
+ mpContext = CreatePixmapContext();
+ return (mpContext != NULL);
+ }
+
+ OpenGLContext* pContext = pSVData->maGDIData.mpLastContext;
+ while( pContext )
+ {
+ // check if this context can be used by this SalGraphicsImpl instance
+ if( CompareWinContext( pContext ) )
+ break;
+ pContext = pContext->mpPrevContext;
+ }
+
+ if( pContext )
+ pContext->AddRef();
+ else
+ pContext = CreateWinContext();
+
+ mpContext = pContext;
+ return (mpContext != NULL);
+}
+
+bool OpenGLSalGraphicsImpl::ReleaseContext()
+{
+ if( mpContext )
+ mpContext->DeRef();
+ mpContext = NULL;
+ return true;
+}
+
+void OpenGLSalGraphicsImpl::Init()
+{
+ const bool bOffscreen = IsOffscreen();
+
+ // check if we can simply re-use the same context
+ if( mpContext )
+ {
+ if( bOffscreen != mbOffscreen || ( !mbOffscreen && CompareWinContext( mpContext ) ) )
+ ReleaseContext();
+ }
+
+ if( !mpContext && !AcquireContext( bOffscreen ) )
+ {
+ SAL_WARN( "vcl.opengl", "Couldn't acquire context for SalGraphics" );
+ return;
+ }
+
+ mpContext->makeCurrent();
+
+ if( mbOffscreen == bOffscreen )
+ {
+ // Nothing more to do for onscreen case
+ if( !mbOffscreen )
+ return;
+
+ // Already enabled and same size
+ if( maOffscreenTex.GetWidth() == GetWidth() &&
+ maOffscreenTex.GetHeight() == GetHeight() )
+ return;
+ }
+ else
+ {
+ mbOffscreen = bOffscreen;
+ if( bOffscreen )
+ glGenFramebuffers( 1, &mnFramebufferId );
+ else
+ glDeleteFramebuffers( 1, &mnFramebufferId );
+ }
+
+ // Create/update attached offscreen texture
+ if( mbOffscreen )
+ {
+ glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
+ maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
+ glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
+ GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+ if( nStatus != GL_FRAMEBUFFER_COMPLETE )
+ SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
+ glBindFramebuffer( GL_FRAMEBUFFER, 0 );
+ CHECK_GL_ERROR();
+ }
}
void OpenGLSalGraphicsImpl::PreDraw()
{
- maContext.makeCurrent();
+ assert( mpContext && mpContext->isInitialized() );
+
+ mpContext->makeCurrent();
// TODO: lfrb: make sure the render target has the right size
if( mbOffscreen )
CheckOffscreenTexture();
@@ -273,46 +368,17 @@ void OpenGLSalGraphicsImpl::SetROPFillColor( SalROPColor /*nROPColor*/ )
{
}
-// enable/disbale offscreen rendering
-void OpenGLSalGraphicsImpl::SetOffscreen( bool bOffscreen )
-{
- if( bOffscreen == mbOffscreen )
- {
- // Already disabled
- if( !mbOffscreen )
- return;
-
- // Already enabled and same size
- if( maOffscreenTex.GetWidth() == GetWidth() &&
- maOffscreenTex.GetHeight() == GetHeight() )
- return;
- }
- else
- {
- mbOffscreen = bOffscreen;
- if( bOffscreen )
- glGenFramebuffers( 1, &mnFramebufferId );
- else
- glDeleteFramebuffers( 1, &mnFramebufferId );
- }
-
- if( mbOffscreen )
- {
- glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
- maOffscreenTex = OpenGLTexture( GetWidth(), GetHeight() );
- glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, maOffscreenTex.Id(), 0 );
- glBindFramebuffer( GL_FRAMEBUFFER, 0 );
- }
-
- CHECK_GL_ERROR();
-}
-
bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
{
glBindFramebuffer( GL_FRAMEBUFFER, mnFramebufferId );
if( maOffscreenTex.IsUnique() )
+ {
+ GLenum nStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER );
+ if( nStatus != GL_FRAMEBUFFER_COMPLETE )
+ SAL_WARN( "vcl.opengl", "Incomplete framebuffer " << nStatus );
return true;
+ }
SalTwoRect aPosAry;
aPosAry.mnSrcX = aPosAry.mnDestX = 0;
@@ -1816,7 +1882,7 @@ void OpenGLSalGraphicsImpl::endPaint()
SAL_INFO( "vcl.opengl", "END PAINT " << this );
if( mnPainting == 0 )
{
- maContext.makeCurrent();
+ mpContext->makeCurrent();
glFlush();
}
}
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index 67a192e..55b3c5a 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -68,4 +68,34 @@ GLfloat WinOpenGLSalGraphicsImpl::GetHeight() const
return 1;
}
+bool WinOpenGLSalGraphicsImpl::IsOffscreen() const
+{
+ WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() );
+ return ( pFrame == NULL );
+}
+
+OpenGLContext* WinOpenGLSalGraphicsImpl::CreateWinContext()
+{
+ OpenGLContext* pContext = new OpenGLContext();
+ pContext->requestSingleBufferedRendering();
+ pContext->init( mrParent.mhLocalDC, mrParent.mhWnd );
+ return pContext;
+}
+
+bool WinOpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+{
+ if( !pContext || !pContext->isInitialized() )
+ return false;
+ return ( pContext->getOpenGLWindow().hWnd == mrParent.mhWnd );
+}
+
+OpenGLContext* WinOpenGLSalGraphicsImpl::CreatePixmapContext()
+{
+ OpenGLContext* pContext = new OpenGLContext();
+ pContext->requestVirtualDevice();
+ pContext->requestSingleBufferedRendering();
+ pContext->init( mrParent.mhLocalDC, mrParent.mhWnd );
+ return pContext;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index 838be1b..b04bab6 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -59,31 +59,53 @@ GLfloat X11OpenGLSalGraphicsImpl::GetHeight() const
return 1;
}
-void X11OpenGLSalGraphicsImpl::Init()
+bool X11OpenGLSalGraphicsImpl::IsOffscreen() const
{
X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
-
- // Called after eg. a vdev re-size where we need to update the underlying pixmap
- maContext.resetToReInitialize();
- if (pProvider)
- {
- Window aWin = pProvider->GetX11Window();
- maContext.init( mrParent.GetXDisplay(), aWin, mrParent.m_nXScreen.getXScreen());
- SetOffscreen( false );
- }
+ if( pProvider )
+ return false;
else if( mrParent.m_pVDev )
- {
- maContext.init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
- mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
- mrParent.m_nXScreen.getXScreen() );
- SetOffscreen( true );
- }
+ return true;
else
{
SAL_WARN( "vcl.opengl", "what happened here?" );
+ return true;
}
}
+OpenGLContext* X11OpenGLSalGraphicsImpl::CreateWinContext()
+{
+ X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+ if( !pProvider )
+ return NULL;
+ Window aWin = pProvider->GetX11Window();
+ OpenGLContext* pContext = new OpenGLContext();
+ pContext->init( mrParent.GetXDisplay(), aWin,
+ mrParent.m_nXScreen.getXScreen() );
+ return pContext;
+}
+
+bool X11OpenGLSalGraphicsImpl::CompareWinContext( OpenGLContext* pContext )
+{
+ X11WindowProvider *pProvider = dynamic_cast<X11WindowProvider*>(mrParent.m_pFrame);
+
+ if( !pProvider || !pContext->isInitialized() )
+ return false;
+ return ( pContext->getOpenGLWindow().win == pProvider->GetX11Window() );
+}
+
+OpenGLContext* X11OpenGLSalGraphicsImpl::CreatePixmapContext()
+{
+ if( mrParent.m_pVDev == NULL )
+ return NULL;
+ OpenGLContext* pContext = new OpenGLContext();
+ pContext->init( mrParent.GetXDisplay(), mrParent.m_pVDev->GetDrawable(),
+ mrParent.m_pVDev->GetWidth(), mrParent.m_pVDev->GetHeight(),
+ mrParent.m_nXScreen.getXScreen() );
+ return pContext;
+}
+
void X11OpenGLSalGraphicsImpl::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics )
{
OpenGLSalGraphicsImpl *pImpl = pSrcGraphics ? dynamic_cast< OpenGLSalGraphicsImpl* >(pSrcGraphics->GetImpl()) : static_cast< OpenGLSalGraphicsImpl *>(mrParent.GetImpl());
@@ -104,7 +126,7 @@ bool X11OpenGLSalGraphicsImpl::FillPixmapFromScreen( X11Pixmap* pPixmap, int nX,
return false;
// make sure everything is synced up before reading back
- maContext.makeCurrent();
+ mpContext->makeCurrent();
glXWaitX();
// TODO: lfrb: What if offscreen?
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index d1c1b72..9bbe1e2 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -27,6 +27,8 @@
#include <win/saldata.hxx>
#endif
+#include "svdata.hxx"
+
using namespace com::sun::star;
// TODO use rtl::Static instead of 'static'
@@ -47,13 +49,26 @@ OpenGLContext::OpenGLContext():
mpWindow(NULL),
m_pChildWindow(NULL),
mbInitialized(false),
+ mnRefCount(1),
mbRequestLegacyContext(false),
mbUseDoubleBufferedRendering(true),
- mbRequestVirtualDevice(false)
+ mbRequestVirtualDevice(false),
+ mpPrevContext(NULL),
+ mpNextContext(NULL)
{
#if defined( UNX ) && !defined MACOSX && !defined IOS && !defined ANDROID
mbPixmap = false;
#endif
+
+ ImplSVData* pSVData = ImplGetSVData();
+ if( pSVData->maGDIData.mpLastContext )
+ {
+ pSVData->maGDIData.mpLastContext->mpNextContext = this;
+ mpPrevContext = pSVData->maGDIData.mpLastContext;
+ }
+ else
+ pSVData->maGDIData.mpFirstContext = this;
+ pSVData->maGDIData.mpLastContext = this;
}
OpenGLContext::~OpenGLContext()
@@ -67,6 +82,16 @@ OpenGLContext::~OpenGLContext()
wglDeleteContext( m_aGLWin.hRC );
ReleaseDC( m_aGLWin.hWnd, m_aGLWin.hDC );
}
+ ImplSVData* pSVData = ImplGetSVData();
+ if( mpPrevContext )
+ mpPrevContext->mpNextContext = mpNextContext;
+ else
+ pSVData->maGDIData.mpFirstContext = mpNextContext;
+ if( mpNextContext )
+ mpNextContext->mpPrevContext = mpPrevContext;
+ else
+ pSVData->maGDIData.mpLastContext = mpPrevContext;
+
#elif defined( MACOSX )
OpenGLWrapper::resetCurrent();
#elif defined( IOS ) || defined( ANDROID )
@@ -89,6 +114,17 @@ OpenGLContext::~OpenGLContext()
#endif
}
+void OpenGLContext::AddRef()
+{
+ mnRefCount++;
+}
+
+void OpenGLContext::DeRef()
+{
+ if( --mnRefCount == 0 )
+ delete this;
+}
+
void OpenGLContext::requestLegacyContext()
{
mbRequestLegacyContext = true;
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 34df86d..3c1a727 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -150,7 +150,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
if( hDrawable_ )
{
- dynamic_cast<X11GraphicsImpl&>(*mpImpl.get()).Init();
+ mpImpl->Init();
// TODO: moggi: FIXME nTextPixel_ = GetPixel( nTextColor_ );
}
}
diff --git a/vcl/win/source/gdi/gdiimpl.cxx b/vcl/win/source/gdi/gdiimpl.cxx
index 8a4b390..e17b3e1 100644
--- a/vcl/win/source/gdi/gdiimpl.cxx
+++ b/vcl/win/source/gdi/gdiimpl.cxx
@@ -294,6 +294,10 @@ WinSalGraphicsImpl::~WinSalGraphicsImpl()
}
+void WinSalGraphicsImpl::Init()
+{
+}
+
void WinSalGraphicsImpl::freeResources()
{
}
diff --git a/vcl/win/source/gdi/gdiimpl.hxx b/vcl/win/source/gdi/gdiimpl.hxx
index ded35ac..65e9d3f 100644
--- a/vcl/win/source/gdi/gdiimpl.hxx
+++ b/vcl/win/source/gdi/gdiimpl.hxx
@@ -52,6 +52,8 @@ public:
virtual ~WinSalGraphicsImpl();
+ virtual void Init() SAL_OVERRIDE;
+
virtual void freeResources() SAL_OVERRIDE;
virtual bool setClipRegion( const vcl::Region& ) SAL_OVERRIDE;
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 678067d..05279d1 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -482,15 +482,7 @@ void WinSalGraphics::InitGraphics()
::SetTextAlign( getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP );
::SetBkMode( getHDC(), WIN32_TRANSPARENT );
::SetROP2( getHDC(), R2_COPYPEN );
-
- OpenGLSalGraphicsImpl* pImpl = dynamic_cast<OpenGLSalGraphicsImpl*>(mpImpl.get());
- if (pImpl)
- {
- if (mbVirDev)
- pImpl->GetOpenGLContext().requestVirtualDevice();
- pImpl->GetOpenGLContext().requestSingleBufferedRendering();
- pImpl->GetOpenGLContext().init(mhLocalDC, mhWnd);
- }
+ mpImpl->Init();
}
void WinSalGraphics::DeInitGraphics()
commit c90741573814173e9df5bf945d8cbe9d7d77ec39
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Fri Nov 21 12:17:02 2014 -0500
vcl: Use old method for pixmap painting for GTK widgets without OpenGL
Change-Id: Ie6078308f7a7f70683a7f963b15857b5dac753b0
diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index 9ce374d..568ef5c 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -133,6 +133,7 @@ public:
// will be set when UI theme was changed
static bool bThemeChanged;
static bool bNeedPixmapPaint;
+ static bool bNeedTwoPasses;
// native widget methods
virtual bool IsNativeControlSupported( ControlType nType, ControlPart nPart ) SAL_OVERRIDE;
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 46ec7b4..f3b1ecf6 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -49,10 +49,12 @@ const char* const tabPrelitDataName="libreoffice-tab-is-prelit";
// initialize statics
bool GtkSalGraphics::bThemeChanged = true;
bool GtkSalGraphics::bNeedPixmapPaint = false;
+bool GtkSalGraphics::bNeedTwoPasses = false;
enum
{
BG_NONE = 0,
+ BG_FILL,
BG_WHITE,
BG_BLACK
};
@@ -511,7 +513,10 @@ void GtkData::initNWF( void )
// use offscreen rendering when using OpenGL backend
if( OpenGLHelper::isVCLOpenGLEnabled() )
+ {
GtkSalGraphics::bNeedPixmapPaint = true;
+ GtkSalGraphics::bNeedTwoPasses = true;
+ }
int nScreens = GetGtkSalData()->GetGtkDisplay()->GetXScreenCount();
gWidgetData = WidgetDataVector( nScreens );
@@ -898,13 +903,24 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType,
aPixmapRect = Rectangle( Point( aCtrlRect.Left()-1, aCtrlRect.Top()-1 ),
Size( aCtrlRect.GetWidth()+2, aCtrlRect.GetHeight()+2) );
- xPixmap.reset( NWGetPixmapFromScreen( aPixmapRect, BG_WHITE ) );
- xMask.reset( NWGetPixmapFromScreen( aPixmapRect, BG_BLACK ) );
- if( !xPixmap || !xMask )
- return false;
- nPasses = 2;
- gdkDrawable[0] = xPixmap->GetGdkDrawable();
- gdkDrawable[1] = xMask->GetGdkDrawable();
+ if( bNeedTwoPasses )
+ {
+ xPixmap.reset( NWGetPixmapFromScreen( aPixmapRect, BG_WHITE ) );
+ xMask.reset( NWGetPixmapFromScreen( aPixmapRect, BG_BLACK ) );
+ if( !xPixmap || !xMask )
+ return false;
+ nPasses = 2;
+ gdkDrawable[0] = xPixmap->GetGdkDrawable();
+ gdkDrawable[1] = xMask->GetGdkDrawable();
+ }
+ else
+ {
+ xPixmap.reset( NWGetPixmapFromScreen( aPixmapRect, BG_FILL ) );
+ if( !xPixmap )
+ return false;
+ nPasses = 1;
+ gdkDrawable[0] = xPixmap->GetGdkDrawable();
+ }
aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() );
aClip.push_back( aCtrlRect );
@@ -926,7 +942,6 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType,
}
bool returnVal = false;
- SAL_INFO( "vcl.opengl", "Rendering with " << nPasses << " passe(s)" );
for( int i = 0; i < nPasses; ++i )
{
@@ -1324,6 +1339,62 @@ bool GtkSalGraphics::getNativeControlRegion( ControlType nType,
/************************************************************************
* Individual control drawing functions
************************************************************************/
+
+// macros to call before and after the rendering code for a widget
+// it takes care of creating the needed pixmaps
+#define BEGIN_PIXMAP_RENDER(aRect, gdkPixmap) \
+ std::unique_ptr<GdkX11Pixmap> _pixmap, _mask; \
+ int _nPasses = 0; \
+ if( bNeedTwoPasses ) \
+ { \
+ _nPasses = 2; \
+ _pixmap.reset( NWGetPixmapFromScreen( aRect, BG_WHITE ) ); \
+ _mask.reset( NWGetPixmapFromScreen( aRect, BG_BLACK ) ); \
+ } \
+ else \
+ { \
+ _nPasses = 1; \
+ _pixmap.reset( NWGetPixmapFromScreen( aRect, BG_FILL ) ); \
+ } \
+ if( !_pixmap || ( bNeedTwoPasses && !_mask ) ) \
+ return false; \
+ for( int i = 0; i < _nPasses; ++i ) \
+ { \
+ GdkPixmap* gdkPixmap = (i == 0) ? _pixmap->GetGdkPixmap() \
+ : _mask->GetGdkPixmap();
+
+#define END_PIXMAP_RENDER(aRect) \
+ } \
+ if( !NWRenderPixmapToScreen( _pixmap.get(), _mask.get(), aRect ) ) \
+ return false;
+
+// same as above but with pixmaps that should be kept for caching
+#define BEGIN_CACHE_PIXMAP_RENDER(aRect, pixmap, mask, gdkPixmap) \
+ int _nPasses = 0; \
+ if( bNeedTwoPasses ) \
+ { \
+ _nPasses = 2; \
+ pixmap = NWGetPixmapFromScreen( aRect, BG_WHITE ); \
+ mask = NWGetPixmapFromScreen( aRect, BG_BLACK ); \
+ } \
+ else \
+ { \
+ _nPasses = 1; \
+ pixmap = NWGetPixmapFromScreen( aRect, BG_FILL ); \
+ mask = NULL; \
+ } \
+ if( !pixmap || ( bNeedTwoPasses && !mask ) ) \
+ return false; \
+ for( int i = 0; i < _nPasses; ++i ) \
+ { \
+ GdkPixmap* gdkPixmap = (i == 0) ? pixmap->GetGdkPixmap() \
+ : mask->GetGdkPixmap();
+
+#define END_CACHE_PIXMAP_RENDER(aRect, pixmap, mask) \
+ } \
+ if( !NWRenderPixmapToScreen( pixmap, mask, aRect ) ) \
+ return false;
+
bool GtkSalGraphics::NWPaintGTKArrow(
GdkDrawable* gdkDrawable,
ControlType, ControlPart,
@@ -2427,16 +2498,8 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
else
pixmapRect = rControlRectangle;
- std::unique_ptr<GdkX11Pixmap> pixmap( NWGetPixmapFromScreen( pixmapRect, BG_WHITE ) );
- std::unique_ptr<GdkX11Pixmap> mask( NWGetPixmapFromScreen( pixmapRect, BG_BLACK ) );
- if( !pixmap || !mask )
- return false;
-
- for( int i = 0; i < 2; ++i )
+ BEGIN_PIXMAP_RENDER( pixmapRect, gdkPixmap )
{
- GdkPixmap* gdkPixmap = (i == 0) ? pixmap->GetGdkPixmap()
- : mask->GetGdkPixmap();
-
// First render background
gtk_paint_flat_box(m_pWindow->style,gdkPixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
-pixmapRect.Left(),
@@ -2478,8 +2541,9 @@ bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
NWPaintOneSpinButton( m_nXScreen, gdkPixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
}
+ END_PIXMAP_RENDER( pixmapRect );
- return NWRenderPixmapToScreen( pixmap.get(), mask.get(), pixmapRect );
+ return true;
}
static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen,
@@ -2786,18 +2850,13 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
return NWRenderPixmapToScreen( pixmap, mask, pixmapRect );
}
- int nDepth = GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth();
- pixmap = new GdkX11Pixmap( pixmapRect.GetWidth(), pixmapRect.GetHeight(), nDepth );
- mask = new GdkX11Pixmap( pixmapRect.GetWidth(), pixmapRect.GetHeight(), nDepth );
GdkRectangle paintRect;
paintRect.x = paintRect.y = 0;
paintRect.width = pixmapRect.GetWidth();
paintRect.height = pixmapRect.GetHeight();
- for( int i = 0; i < 2; ++i )
+ BEGIN_CACHE_PIXMAP_RENDER( pixmapRect, pixmap, mask, gdkPixmap )
{
- GdkPixmap* gdkPixmap = (i == 0) ? pixmap->GetGdkPixmap() : mask->GetGdkPixmap();
-
gtk_paint_flat_box( m_pWindow->style, gdkPixmap, GTK_STATE_NORMAL,
GTK_SHADOW_NONE, &paintRect, m_pWindow, "base",
-rControlRectangle.Left(),
@@ -2851,6 +2910,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
break;
}
}
+ END_CACHE_PIXMAP_RENDER( pixmapRect, pixmap, mask )
// cache data
if( nType == CTRL_TAB_ITEM )
@@ -2858,8 +2918,7 @@ bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
else
aCachePage.Fill( nType, nState, pixmapRect, pixmap, mask );
- bool bSuccess = NWRenderPixmapToScreen( pixmap, mask, pixmapRect );
- return bSuccess;
+ return true;
}
bool GtkSalGraphics::NWPaintGTKListBox( GdkDrawable* gdkDrawable,
@@ -3434,15 +3493,8 @@ bool GtkSalGraphics::NWPaintGTKListNode(
break;
}
- std::unique_ptr<GdkX11Pixmap> pixmap( NWGetPixmapFromScreen( aRect, BG_WHITE ) );
- std::unique_ptr<GdkX11Pixmap> mask( NWGetPixmapFromScreen( aRect, BG_BLACK ) );
- if( !pixmap || !mask )
- return false;
-
- for( int i = 0; i < 2; ++i )
+ BEGIN_PIXMAP_RENDER( aRect, pixDrawable )
{
- GdkDrawable* const &pixDrawable = (i == 0) ? pixmap->GetGdkDrawable()
- : mask->GetGdkDrawable();
gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style,
pixDrawable,
stateType,
@@ -3452,8 +3504,9 @@ bool GtkSalGraphics::NWPaintGTKListNode(
w/2, h/2,
eStyle );
}
+ END_PIXMAP_RENDER( aRect )
- return NWRenderPixmapToScreen( pixmap.get(), mask.get(), aRect );
+ return true;
}
bool GtkSalGraphics::NWPaintGTKProgress(
@@ -3469,20 +3522,12 @@ bool GtkSalGraphics::NWPaintGTKProgress(
gint w, h;
w = rControlRectangle.GetWidth();
h = rControlRectangle.GetHeight();
+ Rectangle aRect( Point( 0, 0 ), Size( w, h ) );
long nProgressWidth = rValue.getNumericVal();
- Rectangle aRect( Point( 0, 0 ), Size( w, h ) );
- std::unique_ptr<GdkX11Pixmap> pixmap( NWGetPixmapFromScreen( aRect, BG_WHITE ) );
- std::unique_ptr<GdkX11Pixmap> mask( NWGetPixmapFromScreen( aRect, BG_BLACK ) );
- if( !pixmap || !mask )
- return false;
-
- for( int i = 0; i < 2; ++i )
+ BEGIN_PIXMAP_RENDER( aRect, pixDrawable )
{
- GdkDrawable* const &pixDrawable = (i == 0) ? pixmap->GetGdkDrawable()
- : mask->GetGdkDrawable();
-
// paint background
gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable,
GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
@@ -3524,8 +3569,9 @@ bool GtkSalGraphics::NWPaintGTKProgress(
}
}
}
+ END_PIXMAP_RENDER( rControlRectangle )
- return NWRenderPixmapToScreen( pixmap.get(), mask.get(), rControlRectangle );
+ return true;
}
bool GtkSalGraphics::NWPaintGTKSlider(
@@ -3545,16 +3591,8 @@ bool GtkSalGraphics::NWPaintGTKSlider(
const SliderValue* pVal = static_cast<const SliderValue*>(&rValue);
- std::unique_ptr<GdkX11Pixmap> pixmap( NWGetPixmapFromScreen( rControlRectangle, BG_WHITE ) );
- std::unique_ptr<GdkX11Pixmap> mask( NWGetPixmapFromScreen( rControlRectangle, BG_BLACK ) );
- if( !pixmap || !mask )
- return false;
-
- for( int i = 0; i < 2; ++i )
+ BEGIN_PIXMAP_RENDER( rControlRectangle, pixDrawable )
{
- GdkDrawable* const &pixDrawable = (i == 0) ? pixmap->GetGdkDrawable()
- : mask->GetGdkDrawable();
-
GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA)
? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale)
: GTK_WIDGET(gWidgetData[m_nXScreen].gVScale);
@@ -3615,8 +3653,9 @@ bool GtkSalGraphics::NWPaintGTKSlider(
eOri );
}
}
+ END_PIXMAP_RENDER( rControlRectangle )
- return NWRenderPixmapToScreen( pixmap.get(), mask.get(), rControlRectangle );
+ return true;
}
static int getFrameWidth(GtkWidget* widget)
@@ -4196,7 +4235,11 @@ GdkX11Pixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect, int nBgC
pPixmap = new GdkX11Pixmap( srcRect.GetWidth(), srcRect.GetHeight(), nDepth );
- if( nBgColor != BG_NONE )
+ if( nBgColor == BG_FILL )
+ {
+ FillPixmapFromScreen( pPixmap, srcRect.Left(), srcRect.Top() );
+ }
+ else if( nBgColor != BG_NONE )
{
cairo_t *cr = gdk_cairo_create( pPixmap->GetGdkDrawable() );
if( nBgColor == BG_BLACK)
commit 71c1cbc7f8011ac82ac195c6027e4094312d7403
Author: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Date: Thu Nov 20 22:07:12 2014 -0500
vcl: Draw native widgets twice on black/white background to synthesize alpha
Change-Id: Ic4c073360070a559855732d2de41ae9085d7d51b
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index 4a4f30f..d81c0ec 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
blendedTextureFragmentShader.glsl \
blendedTextureVertexShader.glsl \
+ diffTextureFragmentShader.glsl \
convolutionFragmentShader.glsl \
linearGradientFragmentShader.glsl \
maskFragmentShader.glsl \
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index a2b863e..d25d5d0 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -35,7 +35,7 @@ public:
virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) SAL_OVERRIDE;
void Init() SAL_OVERRIDE;
bool FillPixmapFromScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
- bool RenderPixmapToScreen( X11Pixmap* pPixmap, int nX, int nY ) SAL_OVERRIDE;
+ bool RenderPixmapToScreen( X11Pixmap* pPixmap, X11Pixmap* pMask, int nX, int nY ) SAL_OVERRIDE;
};
#endif // INCLUDED_VCL_INC_OPENGL_X11_GDIIMPL_HXX
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 761b405..5a7382b 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -67,6 +67,10 @@ protected:
GLuint mnTransformedMaskedSamplerUniform;
GLuint mnTransformedMaskedMaskUniform;
+ GLuint mnDiffTextureProgram;
+ GLuint mnDiffTextureUniform;
+ GLuint mnDiffMaskUniform;
+
GLuint mnMaskedTextureProgram;
GLuint mnMaskedSamplerUniform;
GLuint mnMaskSamplerUniform;
@@ -96,6 +100,7 @@ protected:
bool CreateSolidProgram( void );
bool CreateTextureProgram( void );
bool CreateTransformedTextureProgram( void );
+ bool CreateDiffTextureProgram( void );
bool CreateMaskedTextureProgram( void );
bool CreateBlendedTextureProgram( void );
bool CreateTransformedMaskedTextureProgram( void );
@@ -124,6 +129,7 @@ public:
void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
void DrawTransformedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY );
void DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false, bool pPremultiplied = false );
+ void DrawTextureDiff( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry, bool bInverted = false );
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list