summaryrefslogtreecommitdiff
path: root/gtk/gtkglarea.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-01-17 07:25:51 -0500
committerMatthias Clasen <mclasen@redhat.com>2018-01-17 12:00:13 -0500
commit5711fb9b26dbf516e74de34527d77dad2a64c4d5 (patch)
tree65f20b575caf416c06ef5508490116b77e19ae74 /gtk/gtkglarea.c
parent31fcf5b3a72ac6a7013f517fe501348c002429cd (diff)
downloadgtk+-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.c105
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);