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:
parent
3548faed03
commit
c8fc1edea6
@ -260,24 +260,22 @@ cogl_onscreen_bind (CoglOnscreen *onscreen)
|
||||
}
|
||||
|
||||
void
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region)
|
||||
{
|
||||
CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen);
|
||||
|
||||
if (!klass->queue_damage_region)
|
||||
return;
|
||||
|
||||
klass->queue_damage_region (onscreen, rectangles, n_rectangles);
|
||||
klass->queue_damage_region (onscreen, region);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (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_STENCIL);
|
||||
|
||||
klass->swap_buffers_with_damage (onscreen,
|
||||
rectangles,
|
||||
n_rectangles,
|
||||
info,
|
||||
user_data);
|
||||
klass->swap_buffers_with_damage (onscreen, region, info, user_data);
|
||||
|
||||
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,
|
||||
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
|
||||
cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen);
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
@ -361,11 +354,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
COGL_BUFFER_BIT_DEPTH |
|
||||
COGL_BUFFER_BIT_STENCIL);
|
||||
|
||||
klass->swap_region (onscreen,
|
||||
rectangles,
|
||||
n_rectangles,
|
||||
info,
|
||||
user_data);
|
||||
klass->swap_region (onscreen, region, info, user_data);
|
||||
|
||||
if (!cogl_context_has_winsys_feature (context, COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
|
||||
{
|
||||
|
@ -58,21 +58,18 @@ struct _CoglOnscreenClass
|
||||
|
||||
void (* bind) (CoglOnscreen *onscreen);
|
||||
|
||||
void (* swap_buffers_with_damage) (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
void (* swap_buffers_with_damage) (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void (* swap_region) (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
void (* swap_region) (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void (* queue_damage_region) (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles);
|
||||
void (* queue_damage_region) (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region);
|
||||
|
||||
gboolean (* direct_scanout) (CoglOnscreen *onscreen,
|
||||
CoglScanout *scanout,
|
||||
@ -159,9 +156,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
|
||||
/**
|
||||
* cogl_onscreen_queue_damage_region:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
* @rectangles: (array length=n_rectangles): An array representing damaged
|
||||
rectangles.
|
||||
* @n_rectangles: The number of rectangles
|
||||
* @region: A region representing damage
|
||||
*
|
||||
* 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
|
||||
@ -172,16 +167,13 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
|
||||
* the framebuffer.
|
||||
*/
|
||||
COGL_EXPORT void
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles);
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_swap_buffers_with_damage:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
* @rectangles: (array length=n_rectangles): An array of #MtkRectangle's
|
||||
* representing damaged rectangles.
|
||||
* @n_rectangles: The number of rectangles
|
||||
* @region: A region representing damage
|
||||
*
|
||||
* Swaps the current back buffer being rendered too, to the front for
|
||||
* 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
|
||||
* cogl_framebuffer_swap_buffers() except that it additionally allows
|
||||
* applications to pass a list of damaged rectangles which may be
|
||||
* passed on to a compositor so that it can minimize how much of the
|
||||
* screen is redrawn in response to this applications newly swapped
|
||||
* front buffer.
|
||||
* applications to pass a damage region which may be used to minimize how much
|
||||
* of the screen is redrawn.
|
||||
*
|
||||
* For example if your application is only animating a small object in
|
||||
* 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
|
||||
* 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
|
||||
* called.
|
||||
*
|
||||
@ -222,11 +212,10 @@ cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
* perform incremental rendering based on old back buffers.
|
||||
*/
|
||||
COGL_EXPORT void
|
||||
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_direct_scanout:
|
||||
@ -250,13 +239,10 @@ cogl_onscreen_add_frame_info (CoglOnscreen *onscreen,
|
||||
/**
|
||||
* cogl_onscreen_swap_region:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
* @rectangles: (array length=n_rectangles): An array of integer 4-tuples
|
||||
* representing rectangles as (x, y, width, height) tuples.
|
||||
* @n_rectangles: The number of 4-tuples to be read from @rectangles
|
||||
* @region: A region
|
||||
*
|
||||
* 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
|
||||
* defined by 4 sequential (x, y, width, height) integers.
|
||||
* display.
|
||||
*
|
||||
* This function also implicitly discards the contents of the color, depth and
|
||||
* stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
|
||||
@ -265,11 +251,10 @@ cogl_onscreen_add_frame_info (CoglOnscreen *onscreen,
|
||||
* frame.
|
||||
*/
|
||||
COGL_EXPORT void
|
||||
cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* CoglFrameEvent:
|
||||
|
@ -83,21 +83,21 @@ _cogl_util_one_at_a_time_mix (unsigned int hash)
|
||||
}
|
||||
|
||||
static inline void
|
||||
cogl_rectangles_to_flipped_array (const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
int height,
|
||||
int *rectangles_array)
|
||||
cogl_region_to_flipped_array (const MtkRegion *region,
|
||||
int height,
|
||||
int *rectangles)
|
||||
{
|
||||
int n_rectangles = mtk_region_num_rectangles (region);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
const MtkRectangle *rect = &rectangles[i];
|
||||
int *flip_rect = rectangles_array + 4 * i;
|
||||
MtkRectangle rect = mtk_region_get_rectangle (region, i);
|
||||
int *flip_rect = rectangles + 4 * i;
|
||||
|
||||
flip_rect[0] = rect->x;
|
||||
flip_rect[1] = height - rect->y - rect->height;
|
||||
flip_rect[2] = rect->width;
|
||||
flip_rect[3] = rect->height;
|
||||
flip_rect[0] = rect.x;
|
||||
flip_rect[1] = height - rect.y - rect.height;
|
||||
flip_rect[2] = rect.width;
|
||||
flip_rect[3] = rect.height;
|
||||
}
|
||||
}
|
||||
|
@ -201,11 +201,10 @@ cogl_onscreen_egl_get_buffer_age (CoglOnscreen *onscreen)
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
|
||||
CoglOnscreenEglPrivate *priv =
|
||||
@ -214,12 +213,14 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
|
||||
CoglContext *context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglRenderer *renderer = context->display->renderer;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
int n_rectangles;
|
||||
int *egl_rectangles;
|
||||
|
||||
n_rectangles = mtk_region_num_rectangles (region);
|
||||
egl_rectangles = g_alloca (n_rectangles * sizeof (int) * 4);
|
||||
cogl_rectangles_to_flipped_array (rectangles, n_rectangles,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
cogl_region_to_flipped_array (region,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
|
||||
/* At least for eglSwapBuffers the EGL spec says that the surface to
|
||||
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
|
||||
cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region)
|
||||
{
|
||||
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
|
||||
CoglOnscreenEglPrivate *priv =
|
||||
@ -249,17 +249,21 @@ cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
|
||||
CoglContext *context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglRenderer *renderer = context->display->renderer;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
int n_rectangles;
|
||||
int *egl_rectangles;
|
||||
|
||||
g_return_if_fail (n_rectangles > 0);
|
||||
|
||||
if (!egl_renderer->pf_eglSetDamageRegion)
|
||||
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);
|
||||
cogl_rectangles_to_flipped_array (rectangles, n_rectangles,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
cogl_region_to_flipped_array (region,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
|
||||
if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy,
|
||||
priv->egl_surface,
|
||||
@ -290,11 +294,10 @@ cogl_onscreen_egl_maybe_create_timestamp_query (CoglOnscreen *onscreen,
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
|
||||
CoglOnscreenEglPrivate *priv =
|
||||
@ -317,14 +320,16 @@ cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
|
||||
if (n_rectangles && priv->pf_eglSwapBuffersWithDamage)
|
||||
if (region && priv->pf_eglSwapBuffersWithDamage)
|
||||
{
|
||||
int n_rectangles;
|
||||
int *egl_rectangles;
|
||||
|
||||
n_rectangles = mtk_region_num_rectangles (region);
|
||||
egl_rectangles = alloca (n_rectangles * sizeof (int) * 4);
|
||||
cogl_rectangles_to_flipped_array (rectangles, n_rectangles,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
cogl_region_to_flipped_array (region,
|
||||
cogl_framebuffer_get_height (framebuffer),
|
||||
egl_rectangles);
|
||||
|
||||
if (priv->pf_eglSwapBuffersWithDamage (egl_renderer->edpy,
|
||||
priv->egl_surface,
|
||||
|
@ -637,11 +637,10 @@ set_complete_pending (CoglOnscreen *onscreen)
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *user_rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (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_height = cogl_framebuffer_get_height (framebuffer);
|
||||
int n_rectangles = mtk_region_num_rectangles (region);
|
||||
int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4);
|
||||
int i;
|
||||
MtkRectangle extents;
|
||||
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
const MtkRectangle *rect = &user_rectangles[i];
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
extents = mtk_region_get_extents (region);
|
||||
x_min = extents.x;
|
||||
y_min = extents.y;
|
||||
x_max = extents.x + extents.width;
|
||||
y_max = extents.y + extents.height;
|
||||
|
||||
/* glXCopySubBuffer expects rectangles relative to the bottom left corner but
|
||||
* we are given rectangles relative to the top left so we need to flip
|
||||
* them... */
|
||||
cogl_rectangles_to_flipped_array (user_rectangles, n_rectangles,
|
||||
framebuffer_height, rectangles);
|
||||
cogl_region_to_flipped_array (region, framebuffer_height, rectangles);
|
||||
|
||||
cogl_context_flush_framebuffer_state (context,
|
||||
framebuffer,
|
||||
@ -750,6 +734,7 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
|
||||
{
|
||||
Display *xdpy = xlib_renderer->xdpy;
|
||||
GLXDrawable drawable;
|
||||
int i;
|
||||
|
||||
drawable =
|
||||
onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin;
|
||||
@ -762,6 +747,8 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
|
||||
}
|
||||
else if (context->glBlitFramebuffer)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* XXX: checkout how this state interacts with the code to use
|
||||
* glBlitFramebuffer in Neil's texture atlasing branch */
|
||||
|
||||
@ -837,11 +824,10 @@ cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen,
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen);
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
|
@ -194,13 +194,9 @@ queue_damage_region (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *stage_view,
|
||||
MtkRegion *damage_region)
|
||||
{
|
||||
MtkRectangle *damage;
|
||||
int n_rects, i;
|
||||
g_autofree MtkRectangle *freeme = NULL;
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglOnscreen *onscreen;
|
||||
int fb_width;
|
||||
int fb_height;
|
||||
MtkMonitorTransform view_transform;
|
||||
|
||||
if (mtk_region_is_empty (damage_region))
|
||||
return;
|
||||
@ -210,30 +206,47 @@ queue_damage_region (ClutterStageWindow *stage_window,
|
||||
return;
|
||||
|
||||
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);
|
||||
|
||||
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++)
|
||||
view_transform = clutter_stage_view_get_transform (stage_view);
|
||||
if (view_transform != MTK_MONITOR_TRANSFORM_NORMAL)
|
||||
{
|
||||
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,
|
||||
clutter_stage_view_get_transform (stage_view),
|
||||
fb_width,
|
||||
fb_height,
|
||||
&damage[i]);
|
||||
n_rects = mtk_region_num_rectangles (damage_region);
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
@ -257,14 +270,9 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
{
|
||||
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||
int64_t target_presentation_time_us;
|
||||
MtkRectangle *damage;
|
||||
int n_rects, i;
|
||||
int n_rects;
|
||||
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 =
|
||||
cogl_frame_info_new (cogl_context, priv->global_frame_counter);
|
||||
@ -277,7 +285,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
target_presentation_time_us);
|
||||
}
|
||||
|
||||
/* push on the screen */
|
||||
n_rects = mtk_region_num_rectangles (swap_region);
|
||||
if (n_rects > 0 && !swap_with_damage)
|
||||
{
|
||||
meta_topic (META_DEBUG_BACKEND,
|
||||
@ -285,7 +293,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
onscreen);
|
||||
|
||||
cogl_onscreen_swap_region (onscreen,
|
||||
damage, n_rects,
|
||||
swap_region,
|
||||
frame_info,
|
||||
frame);
|
||||
}
|
||||
@ -296,7 +304,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
|
||||
onscreen);
|
||||
|
||||
cogl_onscreen_swap_buffers_with_damage (onscreen,
|
||||
damage, n_rects,
|
||||
swap_region,
|
||||
frame_info,
|
||||
frame);
|
||||
}
|
||||
|
@ -624,20 +624,23 @@ meta_kms_update_set_custom_page_flip (MetaKmsUpdate *update,
|
||||
|
||||
void
|
||||
meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
const MtkRegion *region)
|
||||
{
|
||||
MetaKmsFbDamage *fb_damage;
|
||||
struct drm_mode_rect *mode_rects;
|
||||
int n_rectangles;
|
||||
int i;
|
||||
|
||||
n_rectangles = mtk_region_num_rectangles (region);
|
||||
mode_rects = g_new0 (struct drm_mode_rect, n_rectangles);
|
||||
for (i = 0; i < n_rectangles; ++i)
|
||||
{
|
||||
mode_rects[i].x1 = rectangles[i].x;
|
||||
mode_rects[i].y1 = rectangles[i].y;
|
||||
mode_rects[i].x2 = rectangles[i].x + rectangles[i].width;
|
||||
mode_rects[i].y2 = rectangles[i].y + rectangles[i].height;
|
||||
MtkRectangle rectangle = mtk_region_get_rectangle (region, i);
|
||||
|
||||
mode_rects[i].x1 = rectangle.x;
|
||||
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);
|
||||
|
@ -165,8 +165,7 @@ meta_kms_update_set_sync_fd (MetaKmsUpdate *update,
|
||||
int sync_fd);
|
||||
|
||||
void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles);
|
||||
const MtkRegion *region);
|
||||
|
||||
META_EXPORT_TEST
|
||||
MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate *update,
|
||||
|
@ -513,8 +513,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
MetaCrtc *crtc,
|
||||
MetaKmsUpdate *kms_update,
|
||||
MetaKmsAssignPlaneFlag flags,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
const MtkRegion *region)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
@ -577,11 +576,8 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
&src_rect,
|
||||
&dst_rect);
|
||||
|
||||
if (rectangles != NULL && n_rectangles != 0)
|
||||
{
|
||||
meta_kms_plane_assignment_set_fb_damage (plane_assignment,
|
||||
rectangles, n_rectangles);
|
||||
}
|
||||
if (region && !mtk_region_is_empty (region))
|
||||
meta_kms_plane_assignment_set_fb_damage (plane_assignment, region);
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
g_assert_not_reached ();
|
||||
@ -983,8 +979,7 @@ secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *seconda
|
||||
static MetaDrmBuffer *
|
||||
copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscreen,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
const MtkRegion *region)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
@ -1000,6 +995,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
g_autoptr (GError) error = NULL;
|
||||
const MetaFormatInfo *format_info;
|
||||
uint64_t modifier;
|
||||
int n_rectangles;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferPrimaryGpu,
|
||||
"copy_shared_framebuffer_primary_gpu()");
|
||||
@ -1056,6 +1052,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
/* Limit the number of individual copies to 16 */
|
||||
#define MAX_RECTS 16
|
||||
|
||||
n_rectangles = mtk_region_num_rectangles (region);
|
||||
if (n_rectangles == 0 || n_rectangles > MAX_RECTS)
|
||||
{
|
||||
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)
|
||||
{
|
||||
MtkRectangle rectangle = mtk_region_get_rectangle (region, i);
|
||||
|
||||
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
|
||||
rectangles[i].x, rectangles[i].y,
|
||||
rectangles[i].x, rectangles[i].y,
|
||||
rectangles[i].width, rectangles[i].height,
|
||||
rectangle.x, rectangle.y,
|
||||
rectangle.x, rectangle.y,
|
||||
rectangle.width, rectangle.height,
|
||||
&error))
|
||||
{
|
||||
g_object_unref (dmabuf_fb);
|
||||
@ -1152,9 +1151,8 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
||||
}
|
||||
|
||||
static MetaDrmBuffer *
|
||||
update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||
@ -1186,8 +1184,7 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen,
|
||||
case META_SHARED_FRAMEBUFFER_COPY_MODE_PRIMARY:
|
||||
copy = copy_shared_framebuffer_primary_gpu (onscreen,
|
||||
secondary_gpu_state,
|
||||
rectangles,
|
||||
n_rectangles);
|
||||
region);
|
||||
if (!copy)
|
||||
{
|
||||
if (!secondary_gpu_state->noted_primary_gpu_copy_failed)
|
||||
@ -1323,11 +1320,10 @@ static const MetaKmsResultListenerVtable swap_buffer_result_listener_vtable = {
|
||||
};
|
||||
|
||||
static void
|
||||
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
CoglFrameInfo *frame_info,
|
||||
gpointer user_data)
|
||||
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const MtkRegion *region,
|
||||
CoglFrameInfo *frame_info,
|
||||
gpointer user_data)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
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()");
|
||||
|
||||
secondary_gpu_fb =
|
||||
update_secondary_gpu_state_pre_swap_buffers (onscreen,
|
||||
rectangles,
|
||||
n_rectangles);
|
||||
update_secondary_gpu_state_pre_swap_buffers (onscreen, region);
|
||||
|
||||
secondary_gpu_state = onscreen_native->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->swap_buffers_with_damage (onscreen,
|
||||
rectangles,
|
||||
n_rectangles,
|
||||
region,
|
||||
frame_info,
|
||||
user_data);
|
||||
|
||||
@ -1467,8 +1460,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
onscreen_native->crtc,
|
||||
kms_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_NONE,
|
||||
rectangles,
|
||||
n_rectangles);
|
||||
region);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1727,8 +1719,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||
onscreen_native->crtc,
|
||||
kms_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DISABLE_IMPLICIT_SYNC,
|
||||
NULL,
|
||||
0);
|
||||
NULL);
|
||||
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
"Posting direct scanout update for CRTC %u (%s)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user