cogl/onscreen: Pass regions instead

Go one step further and pass regions. Sometimes the rectangles were
already a region, e.g. the swap-buffer case, and sometimes it still
potentially needs to pass through a rectangle array, e.g. damage with a
view transform.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4103>
This commit is contained in:
Jonas Ådahl 2024-10-25 17:15:14 +02:00 committed by Marge Bot
parent 3548faed03
commit c8fc1edea6
9 changed files with 173 additions and 207 deletions

View File

@ -260,24 +260,22 @@ cogl_onscreen_bind (CoglOnscreen *onscreen)
} }
void void
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen);
if (!klass->queue_damage_region) if (!klass->queue_damage_region)
return; return;
klass->queue_damage_region (onscreen, rectangles, n_rectangles); klass->queue_damage_region (onscreen, region);
} }
void void
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen);
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@ -300,11 +298,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_BUFFER_BIT_DEPTH | COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL); COGL_BUFFER_BIT_STENCIL);
klass->swap_buffers_with_damage (onscreen, klass->swap_buffers_with_damage (onscreen, region, info, user_data);
rectangles,
n_rectangles,
info,
user_data);
if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
{ {
@ -326,15 +320,14 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen,
CoglFrameInfo *info, CoglFrameInfo *info,
gpointer user_data) gpointer user_data)
{ {
cogl_onscreen_swap_buffers_with_damage (onscreen, NULL, 0, info, user_data); cogl_onscreen_swap_buffers_with_damage (onscreen, NULL, info, user_data);
} }
void void
cogl_onscreen_swap_region (CoglOnscreen *onscreen, cogl_onscreen_swap_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen);
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@ -361,11 +354,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
COGL_BUFFER_BIT_DEPTH | COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL); COGL_BUFFER_BIT_STENCIL);
klass->swap_region (onscreen, klass->swap_region (onscreen, region, info, user_data);
rectangles,
n_rectangles,
info,
user_data);
if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
{ {

View File

@ -58,21 +58,18 @@ struct _CoglOnscreenClass
void (* bind) (CoglOnscreen *onscreen); void (* bind) (CoglOnscreen *onscreen);
void (* swap_buffers_with_damage) (CoglOnscreen *onscreen, void (* swap_buffers_with_damage) (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data);
gpointer user_data);
void (* swap_region) (CoglOnscreen *onscreen, void (* swap_region) (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data);
gpointer user_data);
void (* queue_damage_region) (CoglOnscreen *onscreen, void (* queue_damage_region) (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region);
int n_rectangles);
gboolean (* direct_scanout) (CoglOnscreen *onscreen, gboolean (* direct_scanout) (CoglOnscreen *onscreen,
CoglScanout *scanout, CoglScanout *scanout,
@ -159,9 +156,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
/** /**
* cogl_onscreen_queue_damage_region: * cogl_onscreen_queue_damage_region:
* @onscreen: A #CoglOnscreen framebuffer * @onscreen: A #CoglOnscreen framebuffer
* @rectangles: (array length=n_rectangles): An array representing damaged * @region: A region representing damage
rectangles.
* @n_rectangles: The number of rectangles
* *
* Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt * Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt
* This immediately queues state to OpenGL that will be used for the * This immediately queues state to OpenGL that will be used for the
@ -172,16 +167,13 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
* the framebuffer. * the framebuffer.
*/ */
COGL_EXPORT void COGL_EXPORT void
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen, cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region);
int n_rectangles);
/** /**
* cogl_onscreen_swap_buffers_with_damage: * cogl_onscreen_swap_buffers_with_damage:
* @onscreen: A #CoglOnscreen framebuffer * @onscreen: A #CoglOnscreen framebuffer
* @rectangles: (array length=n_rectangles): An array of #MtkRectangle's * @region: A region representing damage
* representing damaged rectangles.
* @n_rectangles: The number of rectangles
* *
* Swaps the current back buffer being rendered too, to the front for * Swaps the current back buffer being rendered too, to the front for
* display and provides information to any system compositor about * display and provides information to any system compositor about
@ -190,10 +182,8 @@ cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
* *
* This function has the same semantics as * This function has the same semantics as
* cogl_framebuffer_swap_buffers() except that it additionally allows * cogl_framebuffer_swap_buffers() except that it additionally allows
* applications to pass a list of damaged rectangles which may be * applications to pass a damage region which may be used to minimize how much
* passed on to a compositor so that it can minimize how much of the * of the screen is redrawn.
* screen is redrawn in response to this applications newly swapped
* front buffer.
* *
* For example if your application is only animating a small object in * For example if your application is only animating a small object in
* the corner of the screen and everything else is remaining static * the corner of the screen and everything else is remaining static
@ -201,7 +191,7 @@ cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
* corner of your newly swapped buffer has really changed with respect * corner of your newly swapped buffer has really changed with respect
* to your previously swapped front buffer. * to your previously swapped front buffer.
* *
* If @n_rectangles is 0 then the whole buffer will implicitly be * If @region is NULL then the whole buffer will implicitly be
* reported as damaged as if cogl_onscreen_swap_buffers() had been * reported as damaged as if cogl_onscreen_swap_buffers() had been
* called. * called.
* *
@ -222,11 +212,10 @@ cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
* perform incremental rendering based on old back buffers. * perform incremental rendering based on old back buffers.
*/ */
COGL_EXPORT void COGL_EXPORT void
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data);
gpointer user_data);
/** /**
* cogl_onscreen_direct_scanout: * cogl_onscreen_direct_scanout:
@ -250,13 +239,10 @@ cogl_onscreen_add_frame_info (CoglOnscreen *onscreen,
/** /**
* cogl_onscreen_swap_region: * cogl_onscreen_swap_region:
* @onscreen: A #CoglOnscreen framebuffer * @onscreen: A #CoglOnscreen framebuffer
* @rectangles: (array length=n_rectangles): An array of integer 4-tuples * @region: A region
* representing rectangles as (x, y, width, height) tuples.
* @n_rectangles: The number of 4-tuples to be read from @rectangles
* *
* Swaps a region of the back buffer being rendered too, to the front for * Swaps a region of the back buffer being rendered too, to the front for
* display. @rectangles represents the region as array of @n_rectangles each * display.
* defined by 4 sequential (x, y, width, height) integers.
* *
* This function also implicitly discards the contents of the color, depth and * This function also implicitly discards the contents of the color, depth and
* stencil buffers as if cogl_framebuffer_discard_buffers() were used. The * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
@ -265,11 +251,10 @@ cogl_onscreen_add_frame_info (CoglOnscreen *onscreen,
* frame. * frame.
*/ */
COGL_EXPORT void COGL_EXPORT void
cogl_onscreen_swap_region (CoglOnscreen *onscreen, cogl_onscreen_swap_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data);
gpointer user_data);
/** /**
* CoglFrameEvent: * CoglFrameEvent:

View File

@ -83,21 +83,21 @@ _cogl_util_one_at_a_time_mix (unsigned int hash)
} }
static inline void static inline void
cogl_rectangles_to_flipped_array (const MtkRectangle *rectangles, cogl_region_to_flipped_array (const MtkRegion *region,
int n_rectangles, int height,
int height, int *rectangles)
int *rectangles_array)
{ {
int n_rectangles = mtk_region_num_rectangles (region);
int i; int i;
for (i = 0; i < n_rectangles; i++) for (i = 0; i < n_rectangles; i++)
{ {
const MtkRectangle *rect = &rectangles[i]; MtkRectangle rect = mtk_region_get_rectangle (region, i);
int *flip_rect = rectangles_array + 4 * i; int *flip_rect = rectangles + 4 * i;
flip_rect[0] = rect->x; flip_rect[0] = rect.x;
flip_rect[1] = height - rect->y - rect->height; flip_rect[1] = height - rect.y - rect.height;
flip_rect[2] = rect->width; flip_rect[2] = rect.width;
flip_rect[3] = rect->height; flip_rect[3] = rect.height;
} }
} }

View File

@ -201,11 +201,10 @@ cogl_onscreen_egl_get_buffer_age (CoglOnscreen *onscreen)
} }
static void static void
cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen, cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
CoglOnscreenEglPrivate *priv = CoglOnscreenEglPrivate *priv =
@ -214,12 +213,14 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
CoglContext *context = cogl_framebuffer_get_context (framebuffer); CoglContext *context = cogl_framebuffer_get_context (framebuffer);
CoglRenderer *renderer = context->display->renderer; CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
int n_rectangles;
int *egl_rectangles; int *egl_rectangles;
n_rectangles = mtk_region_num_rectangles (region);
egl_rectangles = g_alloca (n_rectangles * sizeof (int) * 4); egl_rectangles = g_alloca (n_rectangles * sizeof (int) * 4);
cogl_rectangles_to_flipped_array (rectangles, n_rectangles, cogl_region_to_flipped_array (region,
cogl_framebuffer_get_height (framebuffer), cogl_framebuffer_get_height (framebuffer),
egl_rectangles); egl_rectangles);
/* At least for eglSwapBuffers the EGL spec says that the surface to /* At least for eglSwapBuffers the EGL spec says that the surface to
swap must be bound to the current context. It looks like Mesa swap must be bound to the current context. It looks like Mesa
@ -238,9 +239,8 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
} }
static void static void
cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen, cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
CoglOnscreenEglPrivate *priv = CoglOnscreenEglPrivate *priv =
@ -249,17 +249,21 @@ cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
CoglContext *context = cogl_framebuffer_get_context (framebuffer); CoglContext *context = cogl_framebuffer_get_context (framebuffer);
CoglRenderer *renderer = context->display->renderer; CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
int n_rectangles;
int *egl_rectangles; int *egl_rectangles;
g_return_if_fail (n_rectangles > 0);
if (!egl_renderer->pf_eglSetDamageRegion) if (!egl_renderer->pf_eglSetDamageRegion)
return; return;
g_return_if_fail (region);
n_rectangles = mtk_region_num_rectangles (region);
g_return_if_fail (n_rectangles > 0);
egl_rectangles = g_alloca (n_rectangles * sizeof (int) * 4); egl_rectangles = g_alloca (n_rectangles * sizeof (int) * 4);
cogl_rectangles_to_flipped_array (rectangles, n_rectangles, cogl_region_to_flipped_array (region,
cogl_framebuffer_get_height (framebuffer), cogl_framebuffer_get_height (framebuffer),
egl_rectangles); egl_rectangles);
if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy, if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy,
priv->egl_surface, priv->egl_surface,
@ -290,11 +294,10 @@ cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen,
} }
static void static void
cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
CoglOnscreenEglPrivate *priv = CoglOnscreenEglPrivate *priv =
@ -317,14 +320,16 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
if (n_rectangles && priv->pf_eglSwapBuffersWithDamage) if (region && priv->pf_eglSwapBuffersWithDamage)
{ {
int n_rectangles;
int *egl_rectangles; int *egl_rectangles;
n_rectangles = mtk_region_num_rectangles (region);
egl_rectangles = alloca (n_rectangles * sizeof (int) * 4); egl_rectangles = alloca (n_rectangles * sizeof (int) * 4);
cogl_rectangles_to_flipped_array (rectangles, n_rectangles, cogl_region_to_flipped_array (region,
cogl_framebuffer_get_height (framebuffer), cogl_framebuffer_get_height (framebuffer),
egl_rectangles); egl_rectangles);
if (priv->pf_eglSwapBuffersWithDamage (egl_renderer->edpy, if (priv->pf_eglSwapBuffersWithDamage (egl_renderer->edpy,
priv->egl_surface, priv->egl_surface,

View File

@ -637,11 +637,10 @@ set_complete_pending (CoglOnscreen *onscreen)
} }
static void static void
cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen, cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
const MtkRectangle *user_rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen);
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
@ -666,35 +665,20 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
int framebuffer_width = cogl_framebuffer_get_width (framebuffer); int framebuffer_width = cogl_framebuffer_get_width (framebuffer);
int framebuffer_height = cogl_framebuffer_get_height (framebuffer); int framebuffer_height = cogl_framebuffer_get_height (framebuffer);
int n_rectangles = mtk_region_num_rectangles (region);
int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4);
int i; MtkRectangle extents;
extents = mtk_region_get_extents (region);
for (i = 0; i < n_rectangles; i++) x_min = extents.x;
{ y_min = extents.y;
const MtkRectangle *rect = &user_rectangles[i]; x_max = extents.x + extents.width;
y_max = extents.y + extents.height;
if (i == 0)
{
x_min = rect->x;
x_max = rect->x + rect->width;
y_min = rect->y;
y_max = rect->y + rect->height;
}
else
{
x_min = MIN (x_min, rect->x);
x_max = MAX (x_max, rect->x + rect->width);
y_min = MIN (y_min, rect->y);
y_max = MAX (y_max, rect->y + rect->height);
}
}
/* glXCopySubBuffer expects rectangles relative to the bottom left corner but /* glXCopySubBuffer expects rectangles relative to the bottom left corner but
* we are given rectangles relative to the top left so we need to flip * we are given rectangles relative to the top left so we need to flip
* them... */ * them... */
cogl_rectangles_to_flipped_array (user_rectangles, n_rectangles, cogl_region_to_flipped_array (region, framebuffer_height, rectangles);
framebuffer_height, rectangles);
cogl_context_flush_framebuffer_state (context, cogl_context_flush_framebuffer_state (context,
framebuffer, framebuffer,
@ -750,6 +734,7 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
{ {
Display *xdpy = xlib_renderer->xdpy; Display *xdpy = xlib_renderer->xdpy;
GLXDrawable drawable; GLXDrawable drawable;
int i;
drawable = drawable =
onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin;
@ -762,6 +747,8 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
} }
else if (context->glBlitFramebuffer) else if (context->glBlitFramebuffer)
{ {
int i;
/* XXX: checkout how this state interacts with the code to use /* XXX: checkout how this state interacts with the code to use
* glBlitFramebuffer in Neil's texture atlasing branch */ * glBlitFramebuffer in Neil's texture atlasing branch */
@ -837,11 +824,10 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
} }
static void static void
cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *info,
CoglFrameInfo *info, gpointer user_data)
gpointer user_data)
{ {
CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen);
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);

View File

@ -194,13 +194,9 @@ queue_damage_region (ClutterStageWindow *stage_window,
ClutterStageView *stage_view, ClutterStageView *stage_view,
MtkRegion *damage_region) MtkRegion *damage_region)
{ {
MtkRectangle *damage;
int n_rects, i;
g_autofree MtkRectangle *freeme = NULL;
CoglFramebuffer *framebuffer; CoglFramebuffer *framebuffer;
CoglOnscreen *onscreen; CoglOnscreen *onscreen;
int fb_width; MtkMonitorTransform view_transform;
int fb_height;
if (mtk_region_is_empty (damage_region)) if (mtk_region_is_empty (damage_region))
return; return;
@ -210,30 +206,47 @@ queue_damage_region (ClutterStageWindow *stage_window,
return; return;
onscreen = COGL_ONSCREEN (framebuffer); onscreen = COGL_ONSCREEN (framebuffer);
fb_width = cogl_framebuffer_get_width (framebuffer);
fb_height = cogl_framebuffer_get_height (framebuffer);
n_rects = mtk_region_num_rectangles (damage_region); view_transform = clutter_stage_view_get_transform (stage_view);
if (view_transform != MTK_MONITOR_TRANSFORM_NORMAL)
if (n_rects < MAX_STACK_RECTS)
damage = g_newa (MtkRectangle, n_rects);
else
damage = freeme = g_new0 (MtkRectangle, n_rects);
for (i = 0; i < n_rects; i++)
{ {
MtkRectangle rect; g_autoptr (MtkRegion) region = NULL;
int fb_width;
int fb_height;
int n_rects, i;
g_autofree MtkRectangle *freeme = NULL;
MtkRectangle *damage;
rect = mtk_region_get_rectangle (damage_region, i); fb_width = cogl_framebuffer_get_width (framebuffer);
fb_height = cogl_framebuffer_get_height (framebuffer);
mtk_rectangle_transform (&rect, n_rects = mtk_region_num_rectangles (damage_region);
clutter_stage_view_get_transform (stage_view),
fb_width, if (n_rects < MAX_STACK_RECTS)
fb_height, damage = g_newa (MtkRectangle, n_rects);
&damage[i]); else
damage = freeme = g_new0 (MtkRectangle, n_rects);
for (i = 0; i < n_rects; i++)
{
MtkRectangle rect;
rect = mtk_region_get_rectangle (damage_region, i);
mtk_rectangle_transform (&rect,
clutter_stage_view_get_transform (stage_view),
fb_width,
fb_height,
&damage[i]);
}
region = mtk_region_create_rectangles (damage, n_rects);
cogl_onscreen_queue_damage_region (onscreen, region);
}
else
{
cogl_onscreen_queue_damage_region (onscreen, damage_region);
} }
cogl_onscreen_queue_damage_region (onscreen, damage, n_rects);
} }
static void static void
@ -257,14 +270,9 @@ swap_framebuffer (ClutterStageWindow *stage_window,
{ {
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
int64_t target_presentation_time_us; int64_t target_presentation_time_us;
MtkRectangle *damage; int n_rects;
int n_rects, i;
CoglFrameInfo *frame_info; CoglFrameInfo *frame_info;
n_rects = mtk_region_num_rectangles (swap_region);
damage = g_newa (MtkRectangle, n_rects);
for (i = 0; i < n_rects; i++)
damage[i] = mtk_region_get_rectangle (swap_region, i);
frame_info = frame_info =
cogl_frame_info_new (cogl_context, priv->global_frame_counter); cogl_frame_info_new (cogl_context, priv->global_frame_counter);
@ -277,7 +285,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
target_presentation_time_us); target_presentation_time_us);
} }
/* push on the screen */ n_rects = mtk_region_num_rectangles (swap_region);
if (n_rects > 0 && !swap_with_damage) if (n_rects > 0 && !swap_with_damage)
{ {
meta_topic (META_DEBUG_BACKEND, meta_topic (META_DEBUG_BACKEND,
@ -285,7 +293,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
onscreen); onscreen);
cogl_onscreen_swap_region (onscreen, cogl_onscreen_swap_region (onscreen,
damage, n_rects, swap_region,
frame_info, frame_info,
frame); frame);
} }
@ -296,7 +304,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
onscreen); onscreen);
cogl_onscreen_swap_buffers_with_damage (onscreen, cogl_onscreen_swap_buffers_with_damage (onscreen,
damage, n_rects, swap_region,
frame_info, frame_info,
frame); frame);
} }

View File

@ -624,20 +624,23 @@ meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
void void
meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment, meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
MetaKmsFbDamage *fb_damage; MetaKmsFbDamage *fb_damage;
struct drm_mode_rect *mode_rects; struct drm_mode_rect *mode_rects;
int n_rectangles;
int i; int i;
n_rectangles = mtk_region_num_rectangles (region);
mode_rects = g_new0 (struct drm_mode_rect, n_rectangles); mode_rects = g_new0 (struct drm_mode_rect, n_rectangles);
for (i = 0; i < n_rectangles; ++i) for (i = 0; i < n_rectangles; ++i)
{ {
mode_rects[i].x1 = rectangles[i].x; MtkRectangle rectangle = mtk_region_get_rectangle (region, i);
mode_rects[i].y1 = rectangles[i].y;
mode_rects[i].x2 = rectangles[i].x + rectangles[i].width; mode_rects[i].x1 = rectangle.x;
mode_rects[i].y2 = rectangles[i].y + rectangles[i].height; mode_rects[i].y1 = rectangle.y;
mode_rects[i].x2 = rectangle.x + rectangle.width;
mode_rects[i].y2 = rectangle.y + rectangle.height;
} }
fb_damage = g_new0 (MetaKmsFbDamage, 1); fb_damage = g_new0 (MetaKmsFbDamage, 1);

View File

@ -165,8 +165,7 @@ meta_kms_update_set_sync_fd (MetaKmsUpdate *update,
int sync_fd); int sync_fd);
void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment, void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
const MtkRectangle *rectangles, const MtkRegion *region);
int n_rectangles);
META_EXPORT_TEST META_EXPORT_TEST
MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update, MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update,

View File

@ -513,8 +513,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaCrtc *crtc, MetaCrtc *crtc,
MetaKmsUpdate *kms_update, MetaKmsUpdate *kms_update,
MetaKmsAssignPlaneFlag flags, MetaKmsAssignPlaneFlag flags,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaRendererNative *renderer_native = onscreen_native->renderer_native; MetaRendererNative *renderer_native = onscreen_native->renderer_native;
@ -577,11 +576,8 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
&src_rect, &src_rect,
&dst_rect); &dst_rect);
if (rectangles != NULL && n_rectangles != 0) if (region && !mtk_region_is_empty (region))
{ meta_kms_plane_assignment_set_fb_damage (plane_assignment, region);
meta_kms_plane_assignment_set_fb_damage (plane_assignment,
rectangles, n_rectangles);
}
break; break;
case META_RENDERER_NATIVE_MODE_SURFACELESS: case META_RENDERER_NATIVE_MODE_SURFACELESS:
g_assert_not_reached (); g_assert_not_reached ();
@ -983,8 +979,7 @@ secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *seconda
static MetaDrmBuffer * static MetaDrmBuffer *
copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen, copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state, MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
@ -1000,6 +995,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
const MetaFormatInfo *format_info; const MetaFormatInfo *format_info;
uint64_t modifier; uint64_t modifier;
int n_rectangles;
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu, COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu,
"copy_shared_framebuffer_primary_gpu()"); "copy_shared_framebuffer_primary_gpu()");
@ -1056,6 +1052,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
/* Limit the number of individual copies to 16 */ /* Limit the number of individual copies to 16 */
#define MAX_RECTS 16 #define MAX_RECTS 16
n_rectangles = mtk_region_num_rectangles (region);
if (n_rectangles == 0 || n_rectangles > MAX_RECTS) if (n_rectangles == 0 || n_rectangles > MAX_RECTS)
{ {
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb), if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
@ -1073,10 +1070,12 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
for (i = 0; i < n_rectangles; ++i) for (i = 0; i < n_rectangles; ++i)
{ {
MtkRectangle rectangle = mtk_region_get_rectangle (region, i);
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb), if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
rectangles[i].x, rectangles[i].y, rectangle.x, rectangle.y,
rectangles[i].x, rectangles[i].y, rectangle.x, rectangle.y,
rectangles[i].width, rectangles[i].height, rectangle.width, rectangle.height,
&error)) &error))
{ {
g_object_unref (dmabuf_fb); g_object_unref (dmabuf_fb);
@ -1152,9 +1151,8 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
} }
static MetaDrmBuffer * static MetaDrmBuffer *
update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen, update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region)
int n_rectangles)
{ {
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
@ -1186,8 +1184,7 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY: case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
copy = copy_shared_framebuffer_primary_gpu (onscreen, copy = copy_shared_framebuffer_primary_gpu (onscreen,
secondary_gpu_state, secondary_gpu_state,
rectangles, region);
n_rectangles);
if (!copy) if (!copy)
{ {
if (!secondary_gpu_state->noted_primary_gpu_copy_failed) if (!secondary_gpu_state->noted_primary_gpu_copy_failed)
@ -1323,11 +1320,10 @@ static const MetaKmsResultListenerVtable swap_buffer_result_listener_vtable = {
}; };
static void static void
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
const MtkRectangle *rectangles, const MtkRegion *region,
int n_rectangles, CoglFrameInfo *frame_info,
CoglFrameInfo *frame_info, gpointer user_data)
gpointer user_data)
{ {
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer); CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
@ -1364,9 +1360,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
"Meta::OnscreenNative::swap_buffers_with_damage()"); "Meta::OnscreenNative::swap_buffers_with_damage()");
secondary_gpu_fb = secondary_gpu_fb =
update_secondary_gpu_state_pre_swap_buffers (onscreen, update_secondary_gpu_state_pre_swap_buffers (onscreen, region);
rectangles,
n_rectangles);
secondary_gpu_state = onscreen_native->secondary_gpu_state; secondary_gpu_state = onscreen_native->secondary_gpu_state;
if (secondary_gpu_state) if (secondary_gpu_state)
@ -1386,8 +1380,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
parent_class = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class); parent_class = COGL_ONSCREEN_CLASS (meta_onscreen_native_parent_class);
parent_class->swap_buffers_with_damage (onscreen, parent_class->swap_buffers_with_damage (onscreen,
rectangles, region,
n_rectangles,
frame_info, frame_info,
user_data); user_data);
@ -1467,8 +1460,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
onscreen_native->crtc, onscreen_native->crtc,
kms_update, kms_update,
META_KMS_ASSIGN_PLANE_FLAG_NONE, META_KMS_ASSIGN_PLANE_FLAG_NONE,
rectangles, region);
n_rectangles);
} }
else else
{ {
@ -1727,8 +1719,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
onscreen_native->crtc, onscreen_native->crtc,
kms_update, kms_update,
META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC, META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC,
NULL, NULL);
0);
meta_topic (META_DEBUG_KMS, meta_topic (META_DEBUG_KMS,
"Posting direct scanout update for CRTC %u (%s)", "Posting direct scanout update for CRTC %u (%s)",