diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-01-17 07:25:51 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2018-01-17 12:00:13 -0500 |
commit | 5711fb9b26dbf516e74de34527d77dad2a64c4d5 (patch) | |
tree | 65f20b575caf416c06ef5508490116b77e19ae74 /gtk/gtkglarea.c | |
parent | 31fcf5b3a72ac6a7013f517fe501348c002429cd (diff) | |
download | gtk+-5711fb9b26dbf516e74de34527d77dad2a64c4d5.tar.gz |
Convert gtkglarea to use snapshots
Just append a texture node.
Note that this is not 100% done yet. The GL area really
needs to keep a pool of textures, and only reuse them
once the GdkTexture object is gone.
Diffstat (limited to 'gtk/gtkglarea.c')
-rw-r--r-- | gtk/gtkglarea.c | 105 |
1 files changed, 41 insertions, 64 deletions
diff --git a/gtk/gtkglarea.c b/gtk/gtkglarea.c index 27157a0acc..7a1c17414c 100644 --- a/gtk/gtkglarea.c +++ b/gtk/gtkglarea.c @@ -27,6 +27,7 @@ #include "gtkmarshalers.h" #include "gtkprivate.h" #include "gtkrender.h" +#include "gtksnapshot.h" #include <epoxy/gl.h> @@ -150,7 +151,6 @@ typedef struct { int required_gl_version; guint frame_buffer; - guint render_buffer; guint texture; guint depth_stencil_buffer; @@ -377,31 +377,9 @@ gtk_gl_area_ensure_buffers (GtkGLArea *area) glGenFramebuffersEXT (1, &priv->frame_buffer); - if (priv->has_alpha) + if (priv->texture == 0) { - /* For alpha we use textures as that is required for blending to work */ - if (priv->texture == 0) - glGenTextures (1, &priv->texture); - - /* Delete old render buffer if any */ - if (priv->render_buffer != 0) - { - glDeleteRenderbuffersEXT(1, &priv->render_buffer); - priv->render_buffer = 0; - } - } - else - { - /* For non-alpha we use render buffers so we can blit instead of texture the result */ - if (priv->render_buffer == 0) - glGenRenderbuffersEXT (1, &priv->render_buffer); - - /* Delete old texture if any */ - if (priv->texture != 0) - { - glDeleteTextures(1, &priv->texture); - priv->texture = 0; - } + glGenTextures (1, &priv->texture); } if ((priv->has_depth_buffer || priv->has_stencil_buffer)) @@ -450,12 +428,6 @@ gtk_gl_area_allocate_buffers (GtkGLArea *area) glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } - if (priv->render_buffer) - { - glBindRenderbuffer (GL_RENDERBUFFER, priv->render_buffer); - glRenderbufferStorage (GL_RENDERBUFFER, GL_RGB8, width, height); - } - if (priv->has_depth_buffer || priv->has_stencil_buffer) { glBindRenderbuffer (GL_RENDERBUFFER, priv->depth_stencil_buffer); @@ -504,9 +476,6 @@ gtk_gl_area_attach_buffers (GtkGLArea *area) if (priv->texture) glFramebufferTexture2D (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, priv->texture, 0); - else if (priv->render_buffer) - glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, priv->render_buffer); if (priv->depth_stencil_buffer) { @@ -529,15 +498,9 @@ gtk_gl_area_delete_buffers (GtkGLArea *area) priv->have_buffers = FALSE; - if (priv->render_buffer != 0) - { - glDeleteRenderbuffersEXT (1, &priv->render_buffer); - priv->render_buffer = 0; - } - if (priv->texture != 0) { - glDeleteTextures(1, &priv->texture); + glDeleteTextures (1, &priv->texture); priv->texture = 0; } @@ -596,10 +559,10 @@ gtk_gl_area_size_allocate (GtkWidget *widget, } static void -gtk_gl_area_draw_error_screen (GtkGLArea *area, - cairo_t *cr, - gint width, - gint height) +gtk_gl_area_draw_error_screen (GtkGLArea *area, + GtkSnapshot *snapshot, + gint width, + gint height) { GtkGLAreaPrivate *priv = gtk_gl_area_get_instance_private (area); PangoLayout *layout; @@ -610,17 +573,18 @@ gtk_gl_area_draw_error_screen (GtkGLArea *area, pango_layout_set_width (layout, width * PANGO_SCALE); pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); pango_layout_get_pixel_size (layout, NULL, &layout_height); - gtk_render_layout (gtk_widget_get_style_context (GTK_WIDGET (area)), - cr, - 0, (height - layout_height) / 2, - layout); + + gtk_snapshot_render_layout (snapshot, + gtk_widget_get_style_context (GTK_WIDGET (area)), + 0, (height - layout_height) / 2, + layout); g_object_unref (layout); } -static gboolean -gtk_gl_area_draw (GtkWidget *widget, - cairo_t *cr) +static void +gtk_gl_area_snapshot (GtkWidget *widget, + GtkSnapshot *snapshot) { GtkGLArea *area = GTK_GL_AREA (widget); GtkGLAreaPrivate *priv = gtk_gl_area_get_instance_private (area); @@ -631,14 +595,14 @@ gtk_gl_area_draw (GtkWidget *widget, if (priv->error != NULL) { gtk_gl_area_draw_error_screen (area, - cr, + snapshot, gtk_widget_get_width (widget), gtk_widget_get_height (widget)); - return FALSE; + return; } if (priv->context == NULL) - return FALSE; + return; gtk_gl_area_make_current (area); @@ -656,6 +620,8 @@ gtk_gl_area_draw (GtkWidget *widget, status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status == GL_FRAMEBUFFER_COMPLETE_EXT) { + GdkTexture *texture; + if (priv->needs_render || priv->auto_render) { if (priv->needs_resize) @@ -669,19 +635,30 @@ gtk_gl_area_draw (GtkWidget *widget, priv->needs_render = FALSE; - gdk_cairo_draw_from_gl (cr, - gtk_widget_get_window (widget), - priv->texture ? priv->texture : priv->render_buffer, - priv->texture ? GL_TEXTURE : GL_RENDERBUFFER, - scale, 0, 0, w, h); - gtk_gl_area_make_current (area); + /* FIXME: the texture may be kept in use for a longer time (eg by + * the backend, or by the inspector, so we really need a pool of + * GL textures here, and use a destroy notify on the texture to + * put the GL texture back in the pool when it is no longer in use. + */ + texture = gdk_texture_new_for_gl (priv->context, + priv->texture, + gtk_widget_get_width (widget), + gtk_widget_get_height (widget), + NULL, NULL); + + gtk_snapshot_append_texture (snapshot, + texture, + &GRAPHENE_RECT_INIT (0, 0, + gtk_widget_get_width (widget), + gtk_widget_get_height (widget)), + "GL Area"); + + g_object_unref (texture); } else { g_warning ("fb setup not supported"); } - - return TRUE; } static gboolean @@ -708,7 +685,7 @@ gtk_gl_area_class_init (GtkGLAreaClass *klass) widget_class->realize = gtk_gl_area_realize; widget_class->unrealize = gtk_gl_area_unrealize; widget_class->size_allocate = gtk_gl_area_size_allocate; - widget_class->draw = gtk_gl_area_draw; + widget_class->snapshot = gtk_gl_area_snapshot; gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_DRAWING_AREA); |