forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
f680d5d130
commit
df600669a2
@ -1721,7 +1721,7 @@ gsk_cairo_node_draw (GskRenderNode *node,
|
|||||||
if (self->surface == NULL)
|
if (self->surface == NULL)
|
||||||
return;
|
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);
|
cairo_paint (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1731,6 +1731,8 @@ static GVariant *
|
|||||||
gsk_cairo_node_serialize (GskRenderNode *node)
|
gsk_cairo_node_serialize (GskRenderNode *node)
|
||||||
{
|
{
|
||||||
GskCairoNode *self = (GskCairoNode *) node;
|
GskCairoNode *self = (GskCairoNode *) node;
|
||||||
|
cairo_surface_t *image;
|
||||||
|
GVariant *result;
|
||||||
|
|
||||||
if (self->surface == NULL)
|
if (self->surface == NULL)
|
||||||
{
|
{
|
||||||
@ -1740,30 +1742,38 @@ gsk_cairo_node_serialize (GskRenderNode *node)
|
|||||||
(guint32) 0, (guint32) 0,
|
(guint32) 0, (guint32) 0,
|
||||||
g_variant_new_array (G_VARIANT_TYPE ("u"), NULL, 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)",
|
result = g_variant_new ("(dddduu@au)",
|
||||||
(double) node->bounds.origin.x, (double) node->bounds.origin.y,
|
(double) node->bounds.origin.x, (double) node->bounds.origin.y,
|
||||||
(double) node->bounds.size.width, (double) node->bounds.size.height,
|
(double) node->bounds.size.width, (double) node->bounds.size.height,
|
||||||
(guint32) cairo_image_surface_get_width (self->surface),
|
(guint32) cairo_image_surface_get_width (image),
|
||||||
(guint32) cairo_image_surface_get_height (self->surface),
|
(guint32) cairo_image_surface_get_height (image),
|
||||||
g_variant_new_fixed_array (G_VARIANT_TYPE ("u"),
|
g_variant_new_fixed_array (G_VARIANT_TYPE ("u"),
|
||||||
cairo_image_surface_get_data (self->surface),
|
cairo_image_surface_get_data (image),
|
||||||
cairo_image_surface_get_width (self->surface)
|
cairo_image_surface_get_width (image)
|
||||||
* cairo_image_surface_get_height (self->surface),
|
* cairo_image_surface_get_height (image),
|
||||||
sizeof (guint32)));
|
sizeof (guint32)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
int stride, i;
|
int stride, i;
|
||||||
guchar *mem_surface, *data;
|
guchar *mem_surface, *data;
|
||||||
GVariant *result;
|
|
||||||
|
|
||||||
width = cairo_image_surface_get_width (self->surface);
|
width = cairo_image_surface_get_width (image);
|
||||||
height = cairo_image_surface_get_height (self->surface);
|
height = cairo_image_surface_get_height (image);
|
||||||
stride = cairo_image_surface_get_stride (self->surface);
|
stride = cairo_image_surface_get_stride (image);
|
||||||
data = cairo_image_surface_get_data (self->surface);
|
data = cairo_image_surface_get_data (image);
|
||||||
|
|
||||||
mem_surface = (guchar *) g_malloc (width * height * 4);
|
mem_surface = (guchar *) g_malloc (width * height * 4);
|
||||||
|
|
||||||
@ -1780,9 +1790,11 @@ gsk_cairo_node_serialize (GskRenderNode *node)
|
|||||||
width * height,
|
width * height,
|
||||||
sizeof (guint32)));
|
sizeof (guint32)));
|
||||||
g_free (mem_surface);
|
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;
|
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)
|
else if (self->surface == NULL)
|
||||||
{
|
{
|
||||||
if (renderer)
|
self->surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
{
|
&(cairo_rectangle_t) {
|
||||||
self->surface = gsk_renderer_create_cairo_surface (renderer,
|
node->bounds.origin.x,
|
||||||
CAIRO_FORMAT_ARGB32,
|
node->bounds.origin.y,
|
||||||
ceilf (node->bounds.size.width),
|
node->bounds.size.width,
|
||||||
ceilf (node->bounds.size.height));
|
node->bounds.size.height
|
||||||
}
|
});
|
||||||
else
|
|
||||||
{
|
|
||||||
self->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
|
||||||
ceilf (node->bounds.size.width),
|
|
||||||
ceilf (node->bounds.size.height));
|
|
||||||
}
|
|
||||||
res = cairo_create (self->surface);
|
res = cairo_create (self->surface);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1943,8 +1949,6 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node,
|
|||||||
res = cairo_create (self->surface);
|
res = cairo_create (self->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_translate (res, -node->bounds.origin.x, -node->bounds.origin.y);
|
|
||||||
|
|
||||||
cairo_rectangle (res,
|
cairo_rectangle (res,
|
||||||
node->bounds.origin.x, node->bounds.origin.y,
|
node->bounds.origin.x, node->bounds.origin.y,
|
||||||
node->bounds.size.width, node->bounds.size.height);
|
node->bounds.size.width, node->bounds.size.height);
|
||||||
|
Loading…
Reference in New Issue
Block a user