gl renderer: Properly draw gl textures from a different context
authorTimm Bäder <mail@baedert.org>
Wed, 14 Mar 2018 11:23:38 +0000 (12:23 +0100)
committerTimm Bäder <mail@baedert.org>
Wed, 14 Mar 2018 16:28:41 +0000 (17:28 +0100)
Temporarily switch to the texture's gl context, download the texture and
create a new one in our context for it.

gsk/gl/gskgldriver.c
gsk/gl/gskglrenderer.c

index a7a62a49e1a168d8074323b2262dc43bab7bf8a1..21e1a5a1eeef364cc5e1a566c019bcfb39ce5283 100644 (file)
@@ -372,14 +372,34 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
   cairo_surface_t *surface;
 
   if (GDK_IS_GL_TEXTURE (texture))
-    return gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture));
-
-  t = gdk_texture_get_render_data (texture, driver);
+    {
+      GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture);
 
-  if (t)
+      if (texture_context != driver->gl_context)
+        {
+          /* In this case, we have to temporarily make the texture's context the current one,
+           * download its data into our context and then create a texture from it. */
+          gdk_gl_context_make_current (texture_context);
+          surface = gdk_texture_download_surface (texture);
+          gdk_gl_context_make_current (driver->gl_context);
+        }
+      else
+        {
+          /* A GL texture from the same GL context is a simple task... */
+          return gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture));
+        }
+    }
+  else
     {
-      if (t->min_filter == min_filter && t->mag_filter == mag_filter)
-        return t->texture_id;
+      t = gdk_texture_get_render_data (texture, driver);
+
+      if (t)
+        {
+          if (t->min_filter == min_filter && t->mag_filter == mag_filter)
+            return t->texture_id;
+        }
+
+      surface = gdk_texture_download_surface (texture);
     }
 
   t = create_texture (driver, gdk_texture_get_width (texture), gdk_texture_get_height (texture));
@@ -387,7 +407,6 @@ gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
   if (gdk_texture_set_render_data (texture, driver, t, gsk_gl_driver_release_texture))
     t->user = texture;
 
-  surface = gdk_texture_download_surface (texture);
   gsk_gl_driver_bind_source_texture (driver, t->texture_id);
   gsk_gl_driver_init_texture_with_surface (driver,
                                            t->texture_id,
index ca8fe4a30e567edb35479c1b8c232db199883f6f..8a4aa9393bd587d88a3bc4974828a69e5fb5de2c 100644 (file)
@@ -643,30 +643,15 @@ render_texture_node (GskGLRenderer   *self,
       ty2 = 1;
     }
 
-  if (GDK_IS_GL_TEXTURE (texture))
-    {
-      ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
-        { { min_x, min_y }, { tx1, ty2 }, },
-        { { min_x, max_y }, { tx1, ty1 }, },
-        { { max_x, min_y }, { tx2, ty2 }, },
-
-        { { max_x, max_y }, { tx2, ty1 }, },
-        { { min_x, max_y }, { tx1, ty1 }, },
-        { { max_x, min_y }, { tx2, ty2 }, },
-      });
-    }
-  else
-    {
-      ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
-        { { min_x, min_y }, { tx1, ty1 }, },
-        { { min_x, max_y }, { tx1, ty2 }, },
-        { { max_x, min_y }, { tx2, ty1 }, },
+  ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
+    { { min_x, min_y }, { tx1, ty1 }, },
+    { { min_x, max_y }, { tx1, ty2 }, },
+    { { max_x, min_y }, { tx2, ty1 }, },
 
-        { { max_x, max_y }, { tx2, ty2 }, },
-        { { min_x, max_y }, { tx1, ty2 }, },
-        { { max_x, min_y }, { tx2, ty1 }, },
-      });
-    }
+    { { max_x, max_y }, { tx2, ty2 }, },
+    { { min_x, max_y }, { tx1, ty2 }, },
+    { { max_x, min_y }, { tx2, ty1 }, },
+  });
 }
 
 static inline void