Blame SOURCES/0001-gtk3-implement-opengl-support-for-slideshow.patch

dc0b3e
From ac19024c141448dbc5d89ad943a28875b4504f5c Mon Sep 17 00:00:00 2001
dc0b3e
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
dc0b3e
Date: Fri, 25 Nov 2016 14:11:13 +0000
dc0b3e
Subject: [PATCH] gtk3: implement opengl support for slideshow
dc0b3e
MIME-Version: 1.0
dc0b3e
Content-Type: text/plain; charset=UTF-8
dc0b3e
Content-Transfer-Encoding: 8bit
dc0b3e
dc0b3e
all of them work, except "Fall" doesn't look right, but it has
dc0b3e
the exact same problem under gtk2/gen to.
dc0b3e
dc0b3e
Change-Id: I73cb9c0fb8211f727198be78d90d4f80a4f8c7c8
dc0b3e
Reviewed-on: https://gerrit.libreoffice.org/31214
dc0b3e
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
dc0b3e
Tested-by: Caolán McNamara <caolanm@redhat.com>
dc0b3e
(cherry picked from commit 8bd9db90383ee008777903c35c7a5eb2c5352e71)
dc0b3e
---
dc0b3e
 include/vcl/opengl/OpenGLContext.hxx               |   2 +
dc0b3e
 slideshow/source/engine/opengl/TransitionImpl.cxx  |  73 ++++++------
dc0b3e
 slideshow/source/engine/opengl/TransitionImpl.hxx  |   9 +-
dc0b3e
 .../source/engine/opengl/TransitionerImpl.cxx      |   7 +-
dc0b3e
 vcl/inc/unx/gtk/gtkinst.hxx                        |   1 +
dc0b3e
 vcl/source/opengl/OpenGLContext.cxx                |   5 +
dc0b3e
 vcl/unx/gtk3/gtk3gtkinst.cxx                       | 127 +++++++++++++++++++++
dc0b3e
 7 files changed, 181 insertions(+), 43 deletions(-)
dc0b3e
dc0b3e
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
dc0b3e
index ffcd816..5796f7e 100644
dc0b3e
--- a/include/vcl/opengl/OpenGLContext.hxx
dc0b3e
+++ b/include/vcl/opengl/OpenGLContext.hxx
dc0b3e
@@ -129,6 +129,8 @@ public:
dc0b3e
     void registerAsCurrent();
dc0b3e
     /// reset the GL context so this context is not implicit in subsequent GL calls.
dc0b3e
     virtual void resetCurrent();
dc0b3e
+    /// unbind the GL_FRAMEBUFFER to its default state, needed for gtk3
dc0b3e
+    virtual void restoreDefaultFramebuffer();
dc0b3e
     virtual void swapBuffers();
dc0b3e
     virtual void sync();
dc0b3e
     void show();
dc0b3e
diff --git a/slideshow/source/engine/opengl/TransitionImpl.cxx b/slideshow/source/engine/opengl/TransitionImpl.cxx
dc0b3e
index 115aaf2..7b9b894 100644
dc0b3e
--- a/slideshow/source/engine/opengl/TransitionImpl.cxx
dc0b3e
+++ b/slideshow/source/engine/opengl/TransitionImpl.cxx
dc0b3e
@@ -29,6 +29,7 @@
dc0b3e
 #include <glm/gtc/matrix_transform.hpp>
dc0b3e
 #include <glm/gtc/type_ptr.hpp>
dc0b3e
 #include <vcl/opengl/OpenGLHelper.hxx>
dc0b3e
+#include <vcl/opengl/OpenGLContext.hxx>
dc0b3e
 
dc0b3e
 #include <algorithm>
dc0b3e
 #include <array>
dc0b3e
@@ -132,7 +133,7 @@ static std::vector<int> uploadPrimitives(const Primitives_t& primitives)
dc0b3e
     return indices;
dc0b3e
 }
dc0b3e
 
dc0b3e
-bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
dc0b3e
+bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     m_nProgramObject = makeShader();
dc0b3e
     if (!m_nProgramObject)
dc0b3e
@@ -200,7 +201,7 @@ bool OGLTransitionImpl::prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteri
dc0b3e
     glBindBuffer(GL_ARRAY_BUFFER, 0);
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
 
dc0b3e
-    prepareTransition( glLeavingSlideTex, glEnteringSlideTex );
dc0b3e
+    prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
dc0b3e
     return true;
dc0b3e
 }
dc0b3e
 
dc0b3e
@@ -233,7 +234,7 @@ void OGLTransitionImpl::finish( double, double, double, double, double )
dc0b3e
 {
dc0b3e
 }
dc0b3e
 
dc0b3e
-void OGLTransitionImpl::prepareTransition( sal_Int32, sal_Int32 )
dc0b3e
+void OGLTransitionImpl::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
dc0b3e
 {
dc0b3e
 }
dc0b3e
 
dc0b3e
@@ -241,7 +242,7 @@ void OGLTransitionImpl::finishTransition()
dc0b3e
 {
dc0b3e
 }
dc0b3e
 
dc0b3e
-void OGLTransitionImpl::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
dc0b3e
+void OGLTransitionImpl::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -257,7 +258,7 @@ void OGLTransitionImpl::displaySlides_( double nTime, sal_Int32 glLeavingSlideTe
dc0b3e
 }
dc0b3e
 
dc0b3e
 void OGLTransitionImpl::display( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
dc0b3e
-                                 double SlideWidth, double SlideHeight, double DispWidth, double DispHeight )
dc0b3e
+                                 double SlideWidth, double SlideHeight, double DispWidth, double DispHeight, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     const double SlideWidthScale = SlideWidth/DispWidth;
dc0b3e
     const double SlideHeightScale = SlideHeight/DispHeight;
dc0b3e
@@ -267,7 +268,7 @@ void OGLTransitionImpl::display( double nTime, sal_Int32 glLeavingSlideTex, sal_
dc0b3e
     prepare( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
dc0b3e
 
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
-    displaySlides_( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale );
dc0b3e
+    displaySlides_( nTime, glLeavingSlideTex, glEnteringSlideTex, SlideWidthScale, SlideHeightScale, pContext );
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     displayScene( nTime, SlideWidth, SlideHeight, DispWidth, DispHeight );
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
@@ -534,9 +535,9 @@ public:
dc0b3e
 
dc0b3e
 private:
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override;
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
dc0b3e
 
dc0b3e
-    virtual void prepareTransition( sal_Int32, sal_Int32 ) override {
dc0b3e
+    virtual void prepareTransition( sal_Int32, sal_Int32, OpenGLContext* ) override {
dc0b3e
         glDisable(GL_CULL_FACE);
dc0b3e
     }
dc0b3e
 
dc0b3e
@@ -551,7 +552,7 @@ GLuint ReflectionTransition::makeShader() const
dc0b3e
 }
dc0b3e
 
dc0b3e
 void ReflectionTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
dc0b3e
-                                              double SlideWidthScale, double SlideHeightScale )
dc0b3e
+                                              double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -598,7 +599,7 @@ public:
dc0b3e
 private:
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
 
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override;
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
dc0b3e
 };
dc0b3e
 
dc0b3e
 GLuint SimpleTransition::makeShader() const
dc0b3e
@@ -607,7 +608,7 @@ GLuint SimpleTransition::makeShader() const
dc0b3e
 }
dc0b3e
 
dc0b3e
 void SimpleTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
dc0b3e
-                                              double SlideWidthScale, double SlideHeightScale )
dc0b3e
+                                       double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -857,10 +858,10 @@ public:
dc0b3e
     {}
dc0b3e
 
dc0b3e
 private:
dc0b3e
-    virtual void displaySlides_(double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale) override;
dc0b3e
+    virtual void displaySlides_(double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext) override;
dc0b3e
 };
dc0b3e
 
dc0b3e
-void RochadeTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
dc0b3e
+void RochadeTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
dc0b3e
 {
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
 
dc0b3e
@@ -1195,7 +1196,7 @@ public:
dc0b3e
         {}
dc0b3e
 
dc0b3e
 private:
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override;
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
dc0b3e
 };
dc0b3e
 
dc0b3e
 Primitives_t makeLeavingSlide(double nTime)
dc0b3e
@@ -1229,7 +1230,7 @@ Primitives_t makeLeavingSlide(double nTime)
dc0b3e
 }
dc0b3e
 
dc0b3e
 void DiamondTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
dc0b3e
-                                              double SlideWidthScale, double SlideHeightScale )
dc0b3e
+                                        double SlideWidthScale, double SlideHeightScale, OpenGLContext * )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -1411,7 +1412,7 @@ protected:
dc0b3e
     {}
dc0b3e
 
dc0b3e
     virtual void finishTransition() override;
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override;
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
dc0b3e
 
dc0b3e
 private:
dc0b3e
     /** various data */
dc0b3e
@@ -1488,7 +1489,7 @@ void initPermTexture(GLuint *texID)
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
 }
dc0b3e
 
dc0b3e
-void PermTextureTransition::prepareTransition( sal_Int32, sal_Int32 )
dc0b3e
+void PermTextureTransition::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     GLint location = glGetUniformLocation( m_nProgramObject, "permTexture" );
dc0b3e
@@ -1629,8 +1630,8 @@ public:
dc0b3e
 private:
dc0b3e
     virtual void finishTransition() override;
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override;
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override;
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
dc0b3e
 
dc0b3e
     GLint mnSlideLocation = -1;
dc0b3e
     GLint mnTileInfoLocation = -1;
dc0b3e
@@ -1679,10 +1680,10 @@ glm::mat4 lookAt(const glm::vec3& eye, const glm::vec3& center, const glm::vec3&
dc0b3e
                      -glm::dot(s, eye), -glm::dot(u, eye), glm::dot(f, eye), 1);
dc0b3e
 }
dc0b3e
 
dc0b3e
-void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
dc0b3e
+void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
-    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex );
dc0b3e
+    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
 
dc0b3e
     mnSlideLocation = glGetUniformLocation(m_nProgramObject, "slide");
dc0b3e
@@ -1783,7 +1784,7 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32
dc0b3e
         }
dc0b3e
     }
dc0b3e
 
dc0b3e
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
dc0b3e
+    pContext->restoreDefaultFramebuffer();
dc0b3e
     glBindTexture(GL_TEXTURE_2D, 0);
dc0b3e
 
dc0b3e
     glActiveTexture( GL_TEXTURE2 );
dc0b3e
@@ -1793,7 +1794,7 @@ void VortexTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32
dc0b3e
     glActiveTexture( GL_TEXTURE0 );
dc0b3e
 }
dc0b3e
 
dc0b3e
-void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale )
dc0b3e
+void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext * pContext )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations( nTime, SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -1815,7 +1816,7 @@ void VortexTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex
dc0b3e
     displaySlide( nTime, glEnteringSlideTex, getScene().getEnteringSlide(), SlideWidthScale, SlideHeightScale );
dc0b3e
 
dc0b3e
     glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
dc0b3e
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
dc0b3e
+    pContext->restoreDefaultFramebuffer();
dc0b3e
     glUniform1f( mnShadowLocation, 0.0 );
dc0b3e
     glUniform1f( mnSlideLocation, 0.0 );
dc0b3e
     displaySlide( nTime, glLeavingSlideTex, getScene().getLeavingSlide(), SlideWidthScale, SlideHeightScale );
dc0b3e
@@ -1877,7 +1878,7 @@ public:
dc0b3e
 
dc0b3e
 private:
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override;
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
dc0b3e
     virtual void prepare( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override;
dc0b3e
 
dc0b3e
     glm::vec2 maCenter;
dc0b3e
@@ -1889,7 +1890,7 @@ GLuint RippleTransition::makeShader() const
dc0b3e
     return OpenGLHelper::LoadShaders( "basicVertexShader", "rippleFragmentShader" );
dc0b3e
 }
dc0b3e
 
dc0b3e
-void RippleTransition::prepareTransition( sal_Int32, sal_Int32 )
dc0b3e
+void RippleTransition::prepareTransition( sal_Int32, sal_Int32, OpenGLContext* )
dc0b3e
 {
dc0b3e
     GLint nCenterLocation = glGetUniformLocation(m_nProgramObject, "center");
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
@@ -1974,7 +1975,7 @@ public:
dc0b3e
 
dc0b3e
 private:
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override;
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
dc0b3e
     virtual void finish( double nTime, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight ) override;
dc0b3e
 
dc0b3e
     GLuint maBuffer = 0;
dc0b3e
@@ -1990,10 +1991,10 @@ struct ThreeFloats
dc0b3e
     GLfloat x, y, z;
dc0b3e
 };
dc0b3e
 
dc0b3e
-void GlitterTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
dc0b3e
+void GlitterTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
-    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex );
dc0b3e
+    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
 
dc0b3e
     GLint nNumTilesLocation = glGetUniformLocation(m_nProgramObject, "numTiles");
dc0b3e
@@ -2078,8 +2079,8 @@ public:
dc0b3e
 private:
dc0b3e
     virtual void finishTransition() override;
dc0b3e
     virtual GLuint makeShader() const override;
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex ) override;
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale ) override;
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext ) override;
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext ) override;
dc0b3e
 
dc0b3e
     GLint maHexagonSizeLocation = -1;
dc0b3e
     GLint maSelectedTextureLocation = -1;
dc0b3e
@@ -2112,10 +2113,10 @@ GLuint HoneycombTransition::makeShader() const
dc0b3e
     return OpenGLHelper::LoadShaders( "honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader" );
dc0b3e
 }
dc0b3e
 
dc0b3e
-void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex )
dc0b3e
+void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
-    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex );
dc0b3e
+    PermTextureTransition::prepareTransition( glLeavingSlideTex, glEnteringSlideTex, pContext );
dc0b3e
 
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     maHexagonSizeLocation = glGetUniformLocation(m_nProgramObject, "hexagonSize");
dc0b3e
@@ -2189,11 +2190,11 @@ void HoneycombTransition::prepareTransition( sal_Int32 glLeavingSlideTex, sal_In
dc0b3e
         return;
dc0b3e
     }
dc0b3e
 
dc0b3e
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
dc0b3e
+    pContext->restoreDefaultFramebuffer();
dc0b3e
 }
dc0b3e
 
dc0b3e
 void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex,
dc0b3e
-                                              double SlideWidthScale, double SlideHeightScale )
dc0b3e
+                                          double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext )
dc0b3e
 {
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
     applyOverallOperations(nTime, SlideWidthScale, SlideHeightScale);
dc0b3e
@@ -2217,7 +2218,7 @@ void HoneycombTransition::displaySlides_( double nTime, sal_Int32 glLeavingSlide
dc0b3e
 
dc0b3e
     // The back (entering) slide needs to be drawn before the front (leaving) one in order for blending to work.
dc0b3e
     glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
dc0b3e
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
dc0b3e
+    pContext->restoreDefaultFramebuffer();
dc0b3e
     glUniform1f(mnShadowLocation, 0.0);
dc0b3e
     glUniform1f(maSelectedTextureLocation, 0.0);
dc0b3e
     glUniform1f(maHexagonSizeLocation, 1.0f - borderSize);
dc0b3e
diff --git a/slideshow/source/engine/opengl/TransitionImpl.hxx b/slideshow/source/engine/opengl/TransitionImpl.hxx
dc0b3e
index b739c0c..54b7ba0 100644
dc0b3e
--- a/slideshow/source/engine/opengl/TransitionImpl.hxx
dc0b3e
+++ b/slideshow/source/engine/opengl/TransitionImpl.hxx
dc0b3e
@@ -36,6 +36,7 @@
dc0b3e
 #include <vector>
dc0b3e
 
dc0b3e
 class Primitive;
dc0b3e
+class OpenGLContext;
dc0b3e
 class Operation;
dc0b3e
 class SceneObject;
dc0b3e
 class TransitionData;
dc0b3e
@@ -136,10 +137,10 @@ public:
dc0b3e
 
dc0b3e
     /** Prepare transition.
dc0b3e
       */
dc0b3e
-    bool prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex );
dc0b3e
+    bool prepare( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext );
dc0b3e
     /** Display a step of the transition.
dc0b3e
       */
dc0b3e
-    void display( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight );
dc0b3e
+    void display( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidth, double SlideHeight, double DispWidth, double DispHeight, OpenGLContext *pContext );
dc0b3e
     /** Clean up after transition.
dc0b3e
       */
dc0b3e
     void finish();
dc0b3e
@@ -182,7 +183,7 @@ private:
dc0b3e
       *
dc0b3e
       * Default implementation does nothing.
dc0b3e
       */
dc0b3e
-    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex );
dc0b3e
+    virtual void prepareTransition( sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, OpenGLContext *pContext );
dc0b3e
 
dc0b3e
     /** This function is called when the transition needs to clear after itself, like delete own textures etc.
dc0b3e
       *
dc0b3e
@@ -195,7 +196,7 @@ private:
dc0b3e
       * Default implementation applies overall operations and then
dc0b3e
       * displays both slides.
dc0b3e
       */
dc0b3e
-    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale );
dc0b3e
+    virtual void displaySlides_( double nTime, sal_Int32 glLeavingSlideTex, sal_Int32 glEnteringSlideTex, double SlideWidthScale, double SlideHeightScale, OpenGLContext *pContext );
dc0b3e
 
dc0b3e
     /** This function is called in prepare method to create the GL program.
dc0b3e
       *
dc0b3e
diff --git a/slideshow/source/engine/opengl/TransitionerImpl.cxx b/slideshow/source/engine/opengl/TransitionerImpl.cxx
dc0b3e
index 01cd3e5..f2f0b3f 100644
dc0b3e
--- a/slideshow/source/engine/opengl/TransitionerImpl.cxx
dc0b3e
+++ b/slideshow/source/engine/opengl/TransitionerImpl.cxx
dc0b3e
@@ -407,7 +407,7 @@ void OGLTransitionerImpl::impl_prepareSlides()
dc0b3e
 bool OGLTransitionerImpl::impl_prepareTransition()
dc0b3e
 {
dc0b3e
     if( mpTransition && mpTransition->getSettings().mnRequiredGLVersion <= mnGLVersion )
dc0b3e
-        return mpTransition->prepare( maLeavingSlideGL, maEnteringSlideGL );
dc0b3e
+        return mpTransition->prepare( maLeavingSlideGL, maEnteringSlideGL, mpContext.get() );
dc0b3e
     return false;
dc0b3e
 }
dc0b3e
 
dc0b3e
@@ -1046,10 +1046,11 @@ void SAL_CALL OGLTransitionerImpl::update( double nTime ) throw (uno::RuntimeExc
dc0b3e
     CHECK_GL_ERROR();
dc0b3e
 
dc0b3e
     const GLWindow& rGLWindow(mpContext->getOpenGLWindow());
dc0b3e
-    mpTransition->display( nTime, maLeavingSlideGL, maEnteringSlideGL,
dc0b3e
+    mpTransition->display(nTime, maLeavingSlideGL, maEnteringSlideGL,
dc0b3e
                           maSlideSize.Width, maSlideSize.Height,
dc0b3e
                           static_cast<double>(rGLWindow.Width),
dc0b3e
-                          static_cast<double>(rGLWindow.Height) );
dc0b3e
+                          static_cast<double>(rGLWindow.Height),
dc0b3e
+                          mpContext.get());
dc0b3e
 
dc0b3e
     mpContext->swapBuffers();
dc0b3e
 
dc0b3e
diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx
dc0b3e
index 514b13f..e20ca9d 100644
dc0b3e
--- a/vcl/inc/unx/gtk/gtkinst.hxx
dc0b3e
+++ b/vcl/inc/unx/gtk/gtkinst.hxx
dc0b3e
@@ -239,6 +239,7 @@ public:
dc0b3e
     virtual css::uno::Reference< css::uno::XInterface > CreateClipboard( const css::uno::Sequence< css::uno::Any >& i_rArguments ) override;
dc0b3e
     virtual css::uno::Reference< css::uno::XInterface > CreateDragSource() override;
dc0b3e
     virtual css::uno::Reference< css::uno::XInterface > CreateDropTarget() override;
dc0b3e
+    virtual OpenGLContext* CreateOpenGLContext() override;
dc0b3e
 #endif
dc0b3e
 
dc0b3e
     virtual const cairo_font_options_t* GetCairoFontOptions() override;
dc0b3e
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
dc0b3e
index 1b2893b..d7d7841 100644
dc0b3e
--- a/vcl/source/opengl/OpenGLContext.cxx
dc0b3e
+++ b/vcl/source/opengl/OpenGLContext.cxx
dc0b3e
@@ -330,6 +330,11 @@ void OpenGLContext::InitGLDebugging()
dc0b3e
 #endif
dc0b3e
 }
dc0b3e
 
dc0b3e
+void OpenGLContext::restoreDefaultFramebuffer()
dc0b3e
+{
dc0b3e
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
dc0b3e
+}
dc0b3e
+
dc0b3e
 void OpenGLContext::setWinPosAndSize(const Point &rPos, const Size& rSize)
dc0b3e
 {
dc0b3e
     if(m_xWindow)
dc0b3e
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
dc0b3e
index 7148882..947bcc9 100644
dc0b3e
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
dc0b3e
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
dc0b3e
@@ -916,4 +916,131 @@ Reference< XInterface > GtkInstance::CreateDragSource()
dc0b3e
     return Reference< XInterface >( static_cast<cppu::OWeakObject *>(new GtkDragSource()) );
dc0b3e
 }
dc0b3e
 
dc0b3e
+class GtkOpenGLContext : public OpenGLContext
dc0b3e
+{
dc0b3e
+    GLWindow m_aGLWin;
dc0b3e
+    GtkWidget *m_pGLArea;
dc0b3e
+
dc0b3e
+public:
dc0b3e
+    GtkOpenGLContext()
dc0b3e
+        : OpenGLContext()
dc0b3e
+        , m_pGLArea(nullptr)
dc0b3e
+    {
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual bool initWindow() override
dc0b3e
+    {
dc0b3e
+        if( !m_pChildWindow )
dc0b3e
+        {
dc0b3e
+            SystemWindowData winData = generateWinData(mpWindow, mbRequestLegacyContext);
dc0b3e
+            m_pChildWindow = VclPtr<SystemChildWindow>::Create(mpWindow, 0, &winData, false);
dc0b3e
+        }
dc0b3e
+
dc0b3e
+        if (m_pChildWindow)
dc0b3e
+        {
dc0b3e
+            InitChildWindow(m_pChildWindow.get());
dc0b3e
+        }
dc0b3e
+
dc0b3e
+        return true;
dc0b3e
+    }
dc0b3e
+
dc0b3e
+private:
dc0b3e
+    virtual const GLWindow& getOpenGLWindow() const override { return m_aGLWin; }
dc0b3e
+    virtual GLWindow& getModifiableOpenGLWindow() override { return m_aGLWin; }
dc0b3e
+
dc0b3e
+    static void signalDestroy(GtkWidget*, gpointer context)
dc0b3e
+    {
dc0b3e
+        GtkOpenGLContext* pThis = static_cast<GtkOpenGLContext*>(context);
dc0b3e
+        pThis->m_pGLArea = nullptr;
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual bool ImplInit() override
dc0b3e
+    {
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        const SystemEnvData* pEnvData = m_pChildWindow->GetSystemData();
dc0b3e
+        GtkWidget *pParent = static_cast<GtkWidget*>(pEnvData->pWidget);
dc0b3e
+        m_pGLArea = gtk_gl_area_new();
dc0b3e
+        g_signal_connect(G_OBJECT(m_pGLArea), "destroy", G_CALLBACK(signalDestroy), this);
dc0b3e
+        gtk_gl_area_set_has_depth_buffer(GTK_GL_AREA(m_pGLArea), true);
dc0b3e
+        gtk_gl_area_set_auto_render(GTK_GL_AREA(m_pGLArea), false);
dc0b3e
+        gtk_widget_set_hexpand(m_pGLArea, true);
dc0b3e
+        gtk_widget_set_vexpand(m_pGLArea, true);
dc0b3e
+        gtk_container_add(GTK_CONTAINER(pParent), m_pGLArea);
dc0b3e
+        gtk_widget_show_all(pParent);
dc0b3e
+        gtk_gl_area_make_current(GTK_GL_AREA(m_pGLArea));
dc0b3e
+        gtk_gl_area_attach_buffers(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#endif
dc0b3e
+        bool bRet = InitGL();
dc0b3e
+        InitGLDebugging();
dc0b3e
+        return bRet;
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void restoreDefaultFramebuffer() override
dc0b3e
+    {
dc0b3e
+        OpenGLContext::restoreDefaultFramebuffer();
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        gtk_gl_area_attach_buffers(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#endif
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void makeCurrent() override
dc0b3e
+    {
dc0b3e
+        if (isCurrent())
dc0b3e
+            return;
dc0b3e
+
dc0b3e
+        clearCurrent();
dc0b3e
+
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        if (m_pGLArea)
dc0b3e
+            gtk_gl_area_make_current(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#endif
dc0b3e
+
dc0b3e
+        registerAsCurrent();
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void destroyCurrentContext() override
dc0b3e
+    {
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        gdk_gl_context_clear_current();
dc0b3e
+#endif
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual bool isCurrent() override
dc0b3e
+    {
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        return m_pGLArea && gdk_gl_context_get_current() == gtk_gl_area_get_context(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#else
dc0b3e
+        return false;
dc0b3e
+#endif
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void sync() override
dc0b3e
+    {
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        gtk_gl_area_queue_render(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#endif
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void resetCurrent() override
dc0b3e
+    {
dc0b3e
+        clearCurrent();
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        gdk_gl_context_clear_current();
dc0b3e
+#endif
dc0b3e
+    }
dc0b3e
+
dc0b3e
+    virtual void swapBuffers() override
dc0b3e
+    {
dc0b3e
+#if GTK_CHECK_VERSION(3,16,0)
dc0b3e
+        gtk_gl_area_queue_render(GTK_GL_AREA(m_pGLArea));
dc0b3e
+#endif
dc0b3e
+        BuffersSwapped();
dc0b3e
+    }
dc0b3e
+};
dc0b3e
+
dc0b3e
+OpenGLContext* GtkInstance::CreateOpenGLContext()
dc0b3e
+{
dc0b3e
+    return new GtkOpenGLContext;
dc0b3e
+}
dc0b3e
+
dc0b3e
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
dc0b3e
-- 
dc0b3e
2.9.3
dc0b3e