From: Benjamin Otte Date: Sat, 24 Mar 2018 19:42:42 +0000 (+0100) Subject: rendernode: Create Cairo surfaces as recording surfaces X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~22^2~814 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=df600669a28f180c4a4958e7651ef2ae203beab4;p=gtk4.git rendernode: Create Cairo surfaces as recording surfaces This way, we can postpone the actual rendeing of the node until the renderer. This allows the renderer to choose the right scale to render at, so it can decide to use 2x scale for hidpi on its own. Last but not least, it makes all nodes independent of the context they are created in, because they do not need to know at snapshot time what they will ultimately be rendered into. --- diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 5faf5ed950..07aaecf713 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -1721,7 +1721,7 @@ gsk_cairo_node_draw (GskRenderNode *node, if (self->surface == NULL) return; - cairo_set_source_surface (cr, self->surface, node->bounds.origin.x, node->bounds.origin.y); + cairo_set_source_surface (cr, self->surface, 0, 0); cairo_paint (cr); } @@ -1731,6 +1731,8 @@ static GVariant * gsk_cairo_node_serialize (GskRenderNode *node) { GskCairoNode *self = (GskCairoNode *) node; + cairo_surface_t *image; + GVariant *result; if (self->surface == NULL) { @@ -1740,30 +1742,38 @@ gsk_cairo_node_serialize (GskRenderNode *node) (guint32) 0, (guint32) 0, g_variant_new_array (G_VARIANT_TYPE ("u"), NULL, 0)); } - else if (cairo_image_surface_get_width (self->surface) * 4 == cairo_image_surface_get_stride (self->surface)) + + image = cairo_surface_map_to_image (self->surface, + &(cairo_rectangle_int_t) { + (double) node->bounds.origin.x, + (double) node->bounds.origin.y, + (double) node->bounds.size.width, + (double) node->bounds.size.height + }); + + if (cairo_image_surface_get_width (image) * 4 == cairo_image_surface_get_stride (image)) { - return g_variant_new ("(dddduu@au)", - (double) node->bounds.origin.x, (double) node->bounds.origin.y, - (double) node->bounds.size.width, (double) node->bounds.size.height, - (guint32) cairo_image_surface_get_width (self->surface), - (guint32) cairo_image_surface_get_height (self->surface), - g_variant_new_fixed_array (G_VARIANT_TYPE ("u"), - cairo_image_surface_get_data (self->surface), - cairo_image_surface_get_width (self->surface) - * cairo_image_surface_get_height (self->surface), - sizeof (guint32))); + result = g_variant_new ("(dddduu@au)", + (double) node->bounds.origin.x, (double) node->bounds.origin.y, + (double) node->bounds.size.width, (double) node->bounds.size.height, + (guint32) cairo_image_surface_get_width (image), + (guint32) cairo_image_surface_get_height (image), + g_variant_new_fixed_array (G_VARIANT_TYPE ("u"), + cairo_image_surface_get_data (image), + cairo_image_surface_get_width (image) + * cairo_image_surface_get_height (image), + sizeof (guint32))); } else { int width, height; int stride, i; guchar *mem_surface, *data; - GVariant *result; - width = cairo_image_surface_get_width (self->surface); - height = cairo_image_surface_get_height (self->surface); - stride = cairo_image_surface_get_stride (self->surface); - data = cairo_image_surface_get_data (self->surface); + width = cairo_image_surface_get_width (image); + height = cairo_image_surface_get_height (image); + stride = cairo_image_surface_get_stride (image); + data = cairo_image_surface_get_data (image); mem_surface = (guchar *) g_malloc (width * height * 4); @@ -1780,9 +1790,11 @@ gsk_cairo_node_serialize (GskRenderNode *node) width * height, sizeof (guint32))); g_free (mem_surface); - - return result; } + + cairo_surface_unmap_image (self->surface, image); + + return result; } const cairo_user_data_key_t gsk_surface_variant_key; @@ -1923,19 +1935,13 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node, } else if (self->surface == NULL) { - if (renderer) - { - self->surface = gsk_renderer_create_cairo_surface (renderer, - CAIRO_FORMAT_ARGB32, - ceilf (node->bounds.size.width), - ceilf (node->bounds.size.height)); - } - else - { - self->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - ceilf (node->bounds.size.width), - ceilf (node->bounds.size.height)); - } + self->surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, + &(cairo_rectangle_t) { + node->bounds.origin.x, + node->bounds.origin.y, + node->bounds.size.width, + node->bounds.size.height + }); res = cairo_create (self->surface); } else @@ -1943,8 +1949,6 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node, res = cairo_create (self->surface); } - cairo_translate (res, -node->bounds.origin.x, -node->bounds.origin.y); - cairo_rectangle (res, node->bounds.origin.x, node->bounds.origin.y, node->bounds.size.width, node->bounds.size.height);