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