From 0f57ab4a541b8d4a932eaea0a5b5f4ff7877d8d8 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 25 Apr 2016 11:29:14 +0100 Subject: [PATCH] gdk: Add utility for uploading Cairo surfaces to GL The surface-to-GL upload logic has become more complicated with the addition of the GLES code paths; it's more logical to have a public utility function that can be called from GDK users, instead of copy pasting the whole thing multiple times. --- gdk/gdkcairo.h | 7 +++++++ gdk/gdkgl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/gdk/gdkcairo.h b/gdk/gdkcairo.h index dd874f7c5b..8ba8baa4ca 100644 --- a/gdk/gdkcairo.h +++ b/gdk/gdkcairo.h @@ -83,6 +83,13 @@ void gdk_cairo_draw_from_gl (cairo_t *cr, GDK_AVAILABLE_IN_3_22 GdkDrawingContext * gdk_cairo_get_drawing_context (cairo_t *cr); +GDK_AVAILABLE_IN_3_22 +void gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface, + int target, + int width, + int height, + GdkGLContext *context); + G_END_DECLS #endif /* __GDK_CAIRO_H__ */ diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c index 51d2b029c6..58674c77c8 100644 --- a/gdk/gdkgl.c +++ b/gdk/gdkgl.c @@ -814,3 +814,51 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface, glDisable (GL_SCISSOR_TEST); glDeleteTextures (1, &texture_id); } + +/** + * gdk_cairo_surface_upload_to_gl: + * @surface: a Cairo surface + * @target: a GL texture target + * @width: the width of the texture @target + * @height: the height of the texture @target + * @context: (nullable): a #GdkGLContext, or %NULL to use the currently + * bound context + * + * Uploads the contents of a Cairo @surface to a GL texture @target. + * + * Since: 3.22 + */ +void +gdk_cairo_surface_upload_to_gl (cairo_surface_t *surface, + int target, + int width, + int height, + GdkGLContext *context) +{ + cairo_rectangle_int_t rect; + cairo_surface_t *tmp; + double sx, sy; + double device_x_offset, device_y_offset; + + g_return_if_fail (surface != NULL); + g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context)); + + if (context == NULL) + context = gdk_gl_context_get_current (); + + cairo_surface_flush (surface); + + sx = sy = 1; + cairo_surface_get_device_scale (surface, &sx, &sy); + cairo_surface_get_device_offset (surface, &device_x_offset, &device_y_offset); + + rect.x = (int) device_x_offset; + rect.y = (int) device_y_offset; + rect.width = width * sx; + rect.height = height * sx; + tmp = cairo_surface_map_to_image (surface, &rect); + + gdk_gl_context_upload_texture (context, tmp, rect.width, rect.height, target); + + cairo_surface_unmap_image (surface, tmp); +}