ClutterStage: Use clutter_region_t for swap_region

We use `clutter_region_t` for the clip now, so lets also use it
for the swap region.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/692
This commit is contained in:
Robert Mader 2019-07-27 18:39:04 +02:00
parent a7f4f5b291
commit 3078394951

View File

@ -395,40 +395,47 @@ valid_buffer_age (ClutterStageViewCogl *view_cogl,
static void static void
paint_damage_region (ClutterStageWindow *stage_window, paint_damage_region (ClutterStageWindow *stage_window,
ClutterStageView *view, ClutterStageView *view,
cairo_rectangle_int_t *swap_region) cairo_region_t *swap_region)
{ {
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
static CoglPipeline *overlay_blue = NULL; static CoglPipeline *overlay_blue = NULL;
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper); ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper);
float x_1 = swap_region->x; CoglMatrix transform;
float x_2 = swap_region->x + swap_region->width; int n_rects, i;
float y_1 = swap_region->y;
float y_2 = swap_region->y + swap_region->height;
CoglMatrix modelview;
cogl_framebuffer_push_matrix (framebuffer);
clutter_actor_get_transform (actor, &transform);
cogl_framebuffer_transform (framebuffer, &transform);
/* Blue for the swap region */
if (G_UNLIKELY (overlay_blue == NULL)) if (G_UNLIKELY (overlay_blue == NULL))
{ {
overlay_blue = cogl_pipeline_new (ctx); overlay_blue = cogl_pipeline_new (ctx);
cogl_pipeline_set_color4ub (overlay_blue, 0x00, 0x00, 0x33, 0x33); cogl_pipeline_set_color4ub (overlay_blue, 0x00, 0x00, 0x33, 0x33);
} }
cogl_framebuffer_push_matrix (framebuffer); n_rects = cairo_region_num_rectangles (swap_region);
cogl_matrix_init_identity (&modelview); for (i = 0; i < n_rects; i++)
_clutter_actor_apply_modelview_transform (actor, &modelview); {
cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview); cairo_rectangle_int_t rect;
float x_1, x_2, y_1, y_2;
cairo_region_get_rectangle (swap_region, i, &rect);
x_1 = rect.x;
x_2 = rect.x + rect.width;
y_1 = rect.y;
y_2 = rect.y + rect.height;
/* Blue for the swap region */
cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2); cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2);
}
/* Red for the clip */ /* Red for the clip */
if (stage_cogl->initialized_redraw_clip && if (stage_cogl->initialized_redraw_clip &&
stage_cogl->redraw_clip) stage_cogl->redraw_clip)
{ {
static CoglPipeline *overlay_red = NULL; static CoglPipeline *overlay_red = NULL;
cairo_rectangle_int_t *rects;
int n_rects, i;
if (G_UNLIKELY (overlay_red == NULL)) if (G_UNLIKELY (overlay_red == NULL))
{ {
@ -439,11 +446,14 @@ paint_damage_region (ClutterStageWindow *stage_window,
n_rects = cairo_region_num_rectangles (stage_cogl->redraw_clip); n_rects = cairo_region_num_rectangles (stage_cogl->redraw_clip);
for (i = 0; i < n_rects; i++) for (i = 0; i < n_rects; i++)
{ {
cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rects[i]); cairo_rectangle_int_t rect;
x_1 = rects[i].x; float x_1, x_2, y_1, y_2;
x_2 = rects[i].x + rects[i].width;
y_1 = rects[i].y; cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rect);
y_2 = rects[i].y + rects[i].height; x_1 = rect.x;
x_2 = rect.x + rect.width;
y_1 = rect.y;
y_2 = rect.y + rect.height;
cogl_framebuffer_draw_rectangle (framebuffer, overlay_red, x_1, y_1, x_2, y_2); cogl_framebuffer_draw_rectangle (framebuffer, overlay_red, x_1, y_1, x_2, y_2);
} }
@ -455,41 +465,41 @@ paint_damage_region (ClutterStageWindow *stage_window,
static gboolean static gboolean
swap_framebuffer (ClutterStageWindow *stage_window, swap_framebuffer (ClutterStageWindow *stage_window,
ClutterStageView *view, ClutterStageView *view,
cairo_rectangle_int_t *swap_region, cairo_region_t *swap_region,
gboolean swap_with_damage) gboolean swap_with_damage)
{ {
CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view); CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
int damage[4], ndamage; int *damage, n_rects, i;
damage[0] = swap_region->x;
damage[1] = swap_region->y;
damage[2] = swap_region->width;
damage[3] = swap_region->height;
if (swap_region->width != 0)
ndamage = 1;
else
ndamage = 0;
if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))) if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
paint_damage_region (stage_window, view, swap_region); paint_damage_region (stage_window, view, swap_region);
n_rects = cairo_region_num_rectangles (swap_region);
damage = g_newa (int, n_rects * 4);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (swap_region, i, &rect);
damage[i * 4] = rect.x;
damage[i * 4 + 1] = rect.y;
damage[i * 4 + 2] = rect.width;
damage[i * 4 + 3] = rect.height;
}
if (cogl_is_onscreen (framebuffer)) if (cogl_is_onscreen (framebuffer))
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
/* push on the screen */ /* push on the screen */
if (ndamage == 1 && !swap_with_damage) if (n_rects > 0 && !swap_with_damage)
{ {
CLUTTER_NOTE (BACKEND, CLUTTER_NOTE (BACKEND,
"cogl_onscreen_swap_region (onscreen: %p, " "cogl_onscreen_swap_region (onscreen: %p)",
"x: %d, y: %d, " onscreen);
"width: %d, height: %d)",
onscreen,
damage[0], damage[1], damage[2], damage[3]);
cogl_onscreen_swap_region (onscreen, cogl_onscreen_swap_region (onscreen,
damage, ndamage); damage, n_rects);
return FALSE; return FALSE;
} }
@ -499,7 +509,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
onscreen); onscreen);
cogl_onscreen_swap_buffers_with_damage (onscreen, cogl_onscreen_swap_buffers_with_damage (onscreen,
damage, ndamage); damage, n_rects);
return TRUE; return TRUE;
} }
@ -562,40 +572,52 @@ fill_current_damage_history_rectangle (ClutterStageView *view,
cairo_region_destroy (damage); cairo_region_destroy (damage);
} }
static void static cairo_region_t *
transform_swap_region_to_onscreen (ClutterStageView *view, transform_swap_region_to_onscreen (ClutterStageView *view,
cairo_rectangle_int_t *swap_region) cairo_region_t *swap_region)
{ {
CoglFramebuffer *framebuffer; CoglFramebuffer *framebuffer;
cairo_rectangle_int_t layout; cairo_rectangle_int_t layout;
gfloat x1, y1, x2, y2;
gint width, height; gint width, height;
int n_rects, i;
cairo_rectangle_int_t *rects;
cairo_region_t *transformed_region;
framebuffer = clutter_stage_view_get_onscreen (view); framebuffer = clutter_stage_view_get_onscreen (view);
clutter_stage_view_get_layout (view, &layout); clutter_stage_view_get_layout (view, &layout);
x1 = (float) swap_region->x / layout.width; width = cogl_framebuffer_get_width (framebuffer);
y1 = (float) swap_region->y / layout.height; height = cogl_framebuffer_get_height (framebuffer);
x2 = (float) (swap_region->x + swap_region->width) / layout.width;
y2 = (float) (swap_region->y + swap_region->height) / layout.height; n_rects = cairo_region_num_rectangles (swap_region);
rects = g_newa (cairo_rectangle_int_t, n_rects);
for (i = 0; i < n_rects; i++)
{
gfloat x1, y1, x2, y2;
cairo_region_get_rectangle (swap_region, i, &rects[i]);
x1 = (float) rects[i].x / layout.width;
y1 = (float) rects[i].y / layout.height;
x2 = (float) (rects[i].x + rects[i].width) / layout.width;
y2 = (float) (rects[i].y + rects[i].height) / layout.height;
clutter_stage_view_transform_to_onscreen (view, &x1, &y1); clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
clutter_stage_view_transform_to_onscreen (view, &x2, &y2); clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
width = cogl_framebuffer_get_width (framebuffer);
height = cogl_framebuffer_get_height (framebuffer);
x1 = floor (x1 * width); x1 = floor (x1 * width);
y1 = floor (height - (y1 * height)); y1 = floor (height - (y1 * height));
x2 = ceil (x2 * width); x2 = ceil (x2 * width);
y2 = ceil (height - (y2 * height)); y2 = ceil (height - (y2 * height));
*swap_region = (cairo_rectangle_int_t) { rects[i].x = x1;
.x = x1, rects[i].y = y1;
.y = y1, rects[i].width = x2 - x1;
.width = x2 - x1, rects[i].height = y2 - y1;
.height = y2 - y1 }
}; transformed_region = cairo_region_create_rectangles (rects, n_rects);
return transformed_region;
} }
static void static void
@ -661,7 +683,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
ClutterActor *wrapper; ClutterActor *wrapper;
cairo_region_t *redraw_clip; cairo_region_t *redraw_clip;
cairo_region_t *fb_clip_region; cairo_region_t *fb_clip_region;
cairo_rectangle_int_t swap_region; cairo_region_t *swap_region;
cairo_rectangle_int_t clip_rect; cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t redraw_rect; cairo_rectangle_int_t redraw_rect;
gboolean clip_region_empty; gboolean clip_region_empty;
@ -980,14 +1002,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
} }
else else
{ {
cairo_region_get_extents (fb_clip_region, &swap_region); swap_region = cairo_region_copy (fb_clip_region);
g_assert (swap_region.width > 0);
do_swap_buffer = TRUE; do_swap_buffer = TRUE;
} }
} }
else else
{ {
swap_region = (cairo_rectangle_int_t) { 0 }; swap_region = cairo_region_create ();
do_swap_buffer = TRUE; do_swap_buffer = TRUE;
} }
@ -998,19 +1019,30 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
if (do_swap_buffer) if (do_swap_buffer)
{ {
gboolean res;
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer, COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
"Paint (swap framebuffer)"); "Paint (swap framebuffer)");
if (clutter_stage_view_get_onscreen (view) != if (clutter_stage_view_get_onscreen (view) !=
clutter_stage_view_get_framebuffer (view)) clutter_stage_view_get_framebuffer (view))
{ {
transform_swap_region_to_onscreen (view, &swap_region); cairo_region_t *transformed_swap_region;
transformed_swap_region =
transform_swap_region_to_onscreen (view, swap_region);
cairo_region_destroy (swap_region);
swap_region = transformed_swap_region;
} }
return swap_framebuffer (stage_window, res = swap_framebuffer (stage_window,
view, view,
&swap_region, swap_region,
swap_with_damage); swap_with_damage);
cairo_region_destroy (swap_region);
return res;
} }
else else
{ {