[gtk+] gl renderer: Use a gl texture in render_texture



commit c739db0e29e3752d52218e31a87beeaac6dbf6b3
Author: Timm Bäder <mail baedert org>
Date:   Sat Feb 3 19:35:25 2018 +0100

    gl renderer: Use a gl texture in render_texture
    
    Get rid of the manual y flipping and cairo business. This keeps the gl
    unit tests working at least.

 gsk/gl/gskglrenderer.c |  103 +++++++++++-------------------------------------
 1 files changed, 23 insertions(+), 80 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 1bd311b..b9b5805 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -190,9 +190,6 @@ struct _GskGLRenderer
 
   graphene_rect_t viewport;
 
-  guint texture_id;
-
-
   GdkGLContext *gl_context;
   GskGLDriver *gl_driver;
   GskGLProfiler *gl_profiler;
@@ -1679,54 +1676,6 @@ gsk_gl_renderer_dispose (GObject *gobject)
   G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (gobject);
 }
 
-static void
-gsk_gl_renderer_create_buffers (GskGLRenderer *self,
-                                int            width,
-                                int            height,
-                                int            scale_factor)
-{
-  if (self->has_buffers)
-    return;
-
-  GSK_RENDERER_NOTE (GSK_RENDERER (self), OPENGL, g_message ("Creating buffers (w:%d, h:%d, scale:%d)", 
width, height, scale_factor));
-
-  if (self->texture_id == 0)
-    {
-      self->texture_id = gsk_gl_driver_create_texture (self->gl_driver,
-                                                       width * scale_factor,
-                                                       height * scale_factor);
-      gsk_gl_driver_bind_source_texture (self->gl_driver, self->texture_id);
-      gsk_gl_driver_init_texture_empty (self->gl_driver, self->texture_id);
-    }
-
-  gsk_gl_driver_create_render_target (self->gl_driver, self->texture_id, TRUE, TRUE);
-  gsk_gl_driver_bind_render_target (self->gl_driver, self->texture_id);
-
-  self->has_buffers = TRUE;
-}
-
-static void
-gsk_gl_renderer_destroy_buffers (GskGLRenderer *self)
-{
-  if (self->gl_context == NULL)
-    return;
-
-  if (!self->has_buffers)
-    return;
-
-  GSK_RENDERER_NOTE (GSK_RENDERER (self), OPENGL, g_message ("Destroying buffers"));
-
-  gdk_gl_context_make_current (self->gl_context);
-
-  if (self->texture_id != 0)
-    {
-      gsk_gl_driver_destroy_texture (self->gl_driver, self->texture_id);
-      self->texture_id = 0;
-    }
-
-  self->has_buffers = FALSE;
-}
-
 static gboolean
 gsk_gl_renderer_create_programs (GskGLRenderer  *self,
                                  GError        **error)
@@ -2455,6 +2404,7 @@ static void
 gsk_gl_renderer_do_render (GskRenderer           *renderer,
                            GskRenderNode         *root,
                            const graphene_rect_t *viewport,
+                           int                    texture_id,
                            int                    scale_factor)
 {
   GskGLRenderer *self = GSK_GL_RENDERER (renderer);
@@ -2500,8 +2450,8 @@ gsk_gl_renderer_do_render (GskRenderer           *renderer,
   render_op_builder.render_ops = self->render_ops;
   gsk_rounded_rect_init_from_rect (&render_op_builder.current_clip, &self->viewport, 0.0f);
 
-  if (self->texture_id != 0)
-    ops_set_render_target (&render_op_builder, self->texture_id);
+  if (texture_id != 0)
+    ops_set_render_target (&render_op_builder, texture_id);
 
   gsk_gl_renderer_add_render_ops (self, root, &render_op_builder);
 
@@ -2549,10 +2499,9 @@ gsk_gl_renderer_render_texture (GskRenderer           *renderer,
 {
   GskGLRenderer *self = GSK_GL_RENDERER (renderer);
   GdkTexture *texture;
-  int stride;
-  guchar *data, *data2;
   int width, height;
-  int x, y;
+  guint texture_id;
+  guint fbo_id;
 
   g_return_val_if_fail (self->gl_context != NULL, NULL);
 
@@ -2564,35 +2513,30 @@ gsk_gl_renderer_render_texture (GskRenderer           *renderer,
 
   /* Prepare our framebuffer */
   gsk_gl_driver_begin_frame (self->gl_driver);
-  gsk_gl_renderer_create_buffers (self, width, height, 1);
-  gsk_gl_renderer_clear (self);
-  gsk_gl_driver_end_frame (self->gl_driver);
-
-  g_assert (self->texture_id != 0);
+  glGenTextures (1, &texture_id);
+  glBindTexture (GL_TEXTURE_2D, texture_id);
 
-  /* Render the actual scene */
-  gsk_gl_renderer_do_render (renderer, root, viewport, 1);
+  if (gdk_gl_context_get_use_es (self->gl_context))
+    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+  else
+    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
 
-  /* Prepare memory for the glReadPixels call */
-  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
-  data = g_malloc (height * stride);
+  glGenFramebuffers (1, &fbo_id);
+  glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
+  glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
+  g_assert_cmpint (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
 
-  /* Bind our framebuffer again and read from it */
-  gsk_gl_driver_begin_frame (self->gl_driver);
-  gsk_gl_driver_bind_render_target (self->gl_driver, self->texture_id);
-  glReadPixels (0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+  gsk_gl_renderer_clear (self);
   gsk_gl_driver_end_frame (self->gl_driver);
 
-  data2 = g_malloc (height * stride);
-  for (y = 0; y < height; y ++)
-    for (x = 0; x < stride; x ++)
-      data2[(height - 1 - y) * stride + x] = data[y * stride + x];
+  /* Render the actual scene */
+  gsk_gl_renderer_do_render (renderer, root, viewport, texture_id, 1);
 
-  g_free (data);
-  /* Create texture from the downloaded data */
-  texture = gdk_texture_new_for_data (g_steal_pointer (&data2), width, height, stride);
+  texture = gdk_texture_new_for_gl (self->gl_context,
+                                    texture_id,
+                                    width, height,
+                                    NULL, NULL);
 
-  gsk_gl_renderer_destroy_buffers (self);
   gsk_gl_renderer_clear_tree (self);
   return texture;
 }
@@ -2615,11 +2559,10 @@ gsk_gl_renderer_render (GskRenderer   *renderer,
   viewport.size.width = gdk_window_get_width (window) * self->scale_factor;
   viewport.size.height = gdk_window_get_height (window) * self->scale_factor;
 
-  gsk_gl_renderer_do_render (renderer, root, &viewport, self->scale_factor);
+  gsk_gl_renderer_do_render (renderer, root, &viewport, 0, self->scale_factor);
 
   gdk_gl_context_make_current (self->gl_context);
   gsk_gl_renderer_clear_tree (self);
-  gsk_gl_renderer_destroy_buffers (self);
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]