Compare commits

...

2 Commits

Author SHA1 Message Date
Matthias Clasen
5fa2d91558 Use damage rectangles for splitting
This is much better when the damage is 'reasonable',
for example the 3-4 rectangles in widget-factory. It
breaks down when we end up with 20 - 30 rectangles,
such as when switching pages in gtk4-demo.
2021-04-11 19:51:20 -04:00
Matthias Clasen
b23a03a44b ngl: Tiled rendering experiment
Render the tree 4 times, with clips to cut out one quarter
of the window. Not pushing things into threads yet. The
speedups are moderate at best, and there are some rendering
artifacts at tile boundaries.
2021-04-11 18:06:30 -04:00

View File

@@ -174,15 +174,14 @@ get_render_region (GdkSurface *surface,
damage = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (context));
if (cairo_region_contains_rectangle (damage, &whole_surface) == CAIRO_REGION_OVERLAP_IN)
return NULL;
return cairo_region_create_rectangle (&whole_surface);
/* If the extents match the full-scene, do the same as above */
cairo_region_get_extents (damage, &extents);
if (gdk_rectangle_equal (&extents, &whole_surface))
return NULL;
return cairo_region_create_rectangle (&whole_surface);
/* Draw clipped to the bounding-box of the region. */
return cairo_region_create_rectangle (&extents);
return cairo_region_copy (damage);
}
static void
@@ -196,6 +195,7 @@ gsk_ngl_renderer_render (GskRenderer *renderer,
GskNglRenderJob *job;
GdkSurface *surface;
float scale_factor;
gint64 start_time, end_time;
g_assert (GSK_IS_NGL_RENDERER (renderer));
g_assert (root != NULL);
@@ -215,15 +215,53 @@ gsk_ngl_renderer_render (GskRenderer *renderer,
render_region = get_render_region (surface, self->context);
gsk_ngl_driver_begin_frame (self->driver, self->command_queue);
start_time = g_get_monotonic_time ();
g_print ("tiled:");
end_time = start_time;
for (int i = 0; i < cairo_region_num_rectangles (render_region); i++)
{
cairo_rectangle_int_t rect;
cairo_region_t *region;
gint64 st = end_time;
cairo_region_get_rectangle (render_region, i, &rect);
region = cairo_region_create_rectangle (&rect);
job = gsk_ngl_render_job_new (self->driver, &viewport, scale_factor, region, 0);
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
gsk_ngl_render_job_set_debug_fallback (job, TRUE);
#endif
gsk_ngl_render_job_render (job, root);
gsk_ngl_render_job_free (job);
cairo_region_destroy (region);
end_time = g_get_monotonic_time ();
g_print ("%s %.2f", i > 0 ? " /" : "", (end_time - st) / 1000.0);
}
g_print (" ms");
start_time = g_get_monotonic_time ();
job = gsk_ngl_render_job_new (self->driver, &viewport, scale_factor, render_region, 0);
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
gsk_ngl_render_job_set_debug_fallback (job, TRUE);
#endif
gsk_ngl_render_job_render (job, root);
gsk_ngl_driver_end_frame (self->driver);
gsk_ngl_render_job_free (job);
end_time = g_get_monotonic_time ();
g_print (" non-tiled: %.2fms\n", (end_time - start_time) / 1000.0);
gsk_ngl_driver_end_frame (self->driver);
gdk_gl_context_make_current (self->context);
gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->context));