From 90c8619f426170b820f968b7633ee312b19b77ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 14 Mar 2018 12:23:38 +0100 Subject: [PATCH] gl renderer: Properly draw gl textures from a different context 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 | 35 +++++++++++++++++++++++++++-------- gsk/gl/gskglrenderer.c | 31 ++++++++----------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index a7a62a49e1..21e1a5a1ee 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -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); - - if (t) { - if (t->min_filter == min_filter && t->mag_filter == mag_filter) - return t->texture_id; + GdkGLContext *texture_context = gdk_gl_texture_get_context ((GdkGLTexture *)texture); + + 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 + { + 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, diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index ca8fe4a30e..8a4aa9393b 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -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 }, }, + 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, 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 }, }, - - { { 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