diff options
author | Timm Bäder <mail@baedert.org> | 2018-02-03 19:35:25 +0100 |
---|---|---|
committer | Timm Bäder <mail@baedert.org> | 2018-02-04 13:10:51 +0100 |
commit | c739db0e29e3752d52218e31a87beeaac6dbf6b3 (patch) | |
tree | 859db54995e6732f57d581d1d7b20e69bdd9ad7f /gsk/gl | |
parent | 676e2e088ee5fc4483b8c1e1f50a098a2c4b746e (diff) | |
download | gtk+-c739db0e29e3752d52218e31a87beeaac6dbf6b3.tar.gz |
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.
Diffstat (limited to 'gsk/gl')
-rw-r--r-- | 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 1bd311b1ff..b9b5805cf9 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 |