From c8fc1edea68446519a0821dd3ec2b37e48cb8405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 25 Oct 2024 17:15:14 +0200 Subject: [PATCH] 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: --- cogl/cogl/cogl-onscreen.c | 39 ++++-------- cogl/cogl/cogl-onscreen.h | 69 ++++++++------------ cogl/cogl/cogl-util.h | 20 +++--- cogl/cogl/winsys/cogl-onscreen-egl.c | 55 ++++++++-------- cogl/cogl/winsys/cogl-onscreen-glx.c | 52 ++++++--------- src/backends/meta-stage-impl.c | 74 ++++++++++++---------- src/backends/native/meta-kms-update.c | 15 +++-- src/backends/native/meta-kms-update.h | 3 +- src/backends/native/meta-onscreen-native.c | 53 +++++++--------- 9 files changed, 173 insertions(+), 207 deletions(-) diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c index fdd9a5ff8..2ecb28a4f 100644 --- a/cogl/cogl/cogl-onscreen.c +++ b/cogl/cogl/cogl-onscreen.c @@ -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)) { diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h index 809dec85a..c6ca0a3d0 100644 --- a/cogl/cogl/cogl-onscreen.h +++ b/cogl/cogl/cogl-onscreen.h @@ -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: diff --git a/cogl/cogl/cogl-util.h b/cogl/cogl/cogl-util.h index b7c93394e..9d791a3d9 100644 --- a/cogl/cogl/cogl-util.h +++ b/cogl/cogl/cogl-util.h @@ -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; } } diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c index 64a668a2e..b2d2d86a2 100644 --- a/cogl/cogl/winsys/cogl-onscreen-egl.c +++ b/cogl/cogl/winsys/cogl-onscreen-egl.c @@ -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, diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c index e61919b3e..79657d57e 100644 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ b/cogl/cogl/winsys/cogl-onscreen-glx.c @@ -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); diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c index ca09afeac..c8d202680 100644 --- a/src/backends/meta-stage-impl.c +++ b/src/backends/meta-stage-impl.c @@ -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); } diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c index 785046296..b1001e243 100644 --- a/src/backends/native/meta-kms-update.c +++ b/src/backends/native/meta-kms-update.c @@ -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); diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h index 33e92f283..cf08245af 100644 --- a/src/backends/native/meta-kms-update.h +++ b/src/backends/native/meta-kms-update.h @@ -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, diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 0af97cdfe..86f4b7cbc 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -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)",