onscreen/native: Track next and presenting buffers via ClutterFrame
Let the ClutterFrame (or rather MetaFrameNative) own both the scanout object and the framebuffer object, and let the frame itself live for as long as it's needed. This allows to place fields that is related to a single frame together, aiming to help reasoning about the lifetime of the fields that were previously directly stored in MetaOnscreenNative. Also take the opportunity to rename "current" to "presenting", to make it clearer that frame's buffer is what is currently presenting to the user. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3799>
This commit is contained in:
parent
42102006b0
commit
2e2c54e356
3 changed files with 89 additions and 47 deletions
|
@ -27,6 +27,9 @@ struct _MetaFrameNative
|
|||
{
|
||||
ClutterFrame base;
|
||||
|
||||
MetaDrmBuffer *buffer;
|
||||
CoglScanout *scanout;
|
||||
|
||||
MetaKmsUpdate *kms_update;
|
||||
};
|
||||
|
||||
|
@ -35,6 +38,9 @@ meta_frame_native_release (ClutterFrame *frame)
|
|||
{
|
||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
||||
|
||||
g_clear_object (&frame_native->buffer);
|
||||
g_clear_object (&frame_native->scanout);
|
||||
|
||||
g_return_if_fail (!frame_native->kms_update);
|
||||
}
|
||||
|
||||
|
@ -76,3 +82,29 @@ meta_frame_native_has_kms_update (MetaFrameNative *frame_native)
|
|||
{
|
||||
return !!frame_native->kms_update;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_native_set_buffer (MetaFrameNative *frame_native,
|
||||
MetaDrmBuffer *buffer)
|
||||
{
|
||||
g_set_object (&frame_native->buffer, buffer);
|
||||
}
|
||||
|
||||
MetaDrmBuffer *
|
||||
meta_frame_native_get_buffer (MetaFrameNative *frame_native)
|
||||
{
|
||||
return frame_native->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
meta_frame_native_set_scanout (MetaFrameNative *frame_native,
|
||||
CoglScanout *scanout)
|
||||
{
|
||||
g_set_object (&frame_native->scanout, scanout);
|
||||
}
|
||||
|
||||
CoglScanout *
|
||||
meta_frame_native_get_scanout (MetaFrameNative *frame_native)
|
||||
{
|
||||
return frame_native->scanout;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "backends/native/meta-backend-native-types.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
#include "clutter/clutter.h"
|
||||
#include "core/util-private.h"
|
||||
|
@ -36,3 +37,13 @@ MetaKmsUpdate * meta_frame_native_steal_kms_update (MetaFrameNative *frame_nativ
|
|||
|
||||
META_EXPORT_TEST
|
||||
gboolean meta_frame_native_has_kms_update (MetaFrameNative *frame_native);
|
||||
|
||||
void meta_frame_native_set_buffer (MetaFrameNative *frame_native,
|
||||
MetaDrmBuffer *buffer);
|
||||
|
||||
MetaDrmBuffer * meta_frame_native_get_buffer (MetaFrameNative *frame_native);
|
||||
|
||||
void meta_frame_native_set_scanout (MetaFrameNative *frame_native,
|
||||
CoglScanout *scanout);
|
||||
|
||||
CoglScanout * meta_frame_native_get_scanout (MetaFrameNative *frame_native);
|
||||
|
|
|
@ -95,12 +95,11 @@ struct _MetaOnscreenNative
|
|||
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||
|
||||
ClutterFrame *presented_frame;
|
||||
ClutterFrame *next_frame;
|
||||
|
||||
struct {
|
||||
struct gbm_surface *surface;
|
||||
MetaDrmBuffer *current_fb;
|
||||
MetaDrmBuffer *next_fb;
|
||||
CoglScanout *current_scanout;
|
||||
CoglScanout *next_scanout;
|
||||
} gbm;
|
||||
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
|
@ -137,30 +136,17 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
|
|||
CoglOnscreen *onscreen,
|
||||
GError **error);
|
||||
|
||||
static void
|
||||
free_current_bo (CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
g_clear_object (&onscreen_native->gbm.current_fb);
|
||||
g_clear_object (&onscreen_native->gbm.current_scanout);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
if (!onscreen_native->gbm.next_fb)
|
||||
if (!onscreen_native->next_frame)
|
||||
return;
|
||||
|
||||
free_current_bo (onscreen);
|
||||
|
||||
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_set_object (&onscreen_native->gbm.current_scanout,
|
||||
onscreen_native->gbm.next_scanout);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
|
||||
onscreen_native->presented_frame =
|
||||
g_steal_pointer (&onscreen_native->next_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -168,8 +154,7 @@ meta_onscreen_native_clear_next_fb (CoglOnscreen *onscreen)
|
|||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -298,7 +283,7 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
|
|||
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
|
||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
||||
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_fb);
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
|
||||
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||
}
|
||||
|
@ -495,16 +480,19 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
MetaKmsUpdate *kms_update,
|
||||
MetaKmsAssignPlaneFlag flags,
|
||||
const int *rectangles,
|
||||
int n_rectangles)
|
||||
int n_rectangles,
|
||||
ClutterFrame *frame)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaDrmBuffer *buffer;
|
||||
CoglScanout *scanout;
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
graphene_rect_t src_rect;
|
||||
MtkRectangle dst_rect;
|
||||
|
@ -521,14 +509,13 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
buffer = onscreen_native->gbm.next_fb;
|
||||
buffer = meta_frame_native_get_buffer (frame_native);
|
||||
scanout = meta_frame_native_get_scanout (frame_native);
|
||||
|
||||
if (onscreen_native->gbm.next_scanout)
|
||||
if (scanout)
|
||||
{
|
||||
cogl_scanout_get_src_rect (onscreen_native->gbm.next_scanout,
|
||||
&src_rect);
|
||||
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout,
|
||||
&dst_rect);
|
||||
cogl_scanout_get_src_rect (scanout, &src_rect);
|
||||
cogl_scanout_get_dst_rect (scanout, &dst_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1299,6 +1286,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
MetaDrmBufferGbm *buffer_gbm;
|
||||
g_autoptr (MetaDrmBuffer) primary_gpu_fb = NULL;
|
||||
g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL;
|
||||
MetaDrmBuffer *buffer;
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
|
||||
|
@ -1376,16 +1364,20 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
primary_gpu_fb,
|
||||
&secondary_gpu_fb);
|
||||
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
onscreen_native->next_frame = clutter_frame_ref (frame);
|
||||
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
|
||||
if (onscreen_native->secondary_gpu_state)
|
||||
g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb);
|
||||
buffer = secondary_gpu_fb;
|
||||
else
|
||||
g_set_object (&onscreen_native->gbm.next_fb, primary_gpu_fb);
|
||||
buffer = primary_gpu_fb;
|
||||
|
||||
if (!meta_drm_buffer_ensure_fb_id (onscreen_native->gbm.next_fb, &error))
|
||||
meta_frame_native_set_buffer (frame_native, buffer);
|
||||
|
||||
if (!meta_drm_buffer_ensure_fb_id (buffer, &error))
|
||||
{
|
||||
g_warning ("Failed to ensure KMS FB ID on %s: %s",
|
||||
meta_device_file_get_path (render_device_file),
|
||||
|
@ -1434,7 +1426,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
kms_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_NONE,
|
||||
rectangles,
|
||||
n_rectangles);
|
||||
n_rectangles,
|
||||
frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1577,11 +1570,15 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
|
|||
G_IO_ERROR_PERMISSION_DENIED))
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view);
|
||||
ClutterFrame *next_frame = onscreen_native->next_frame;
|
||||
MetaFrameNative *next_frame_native =
|
||||
meta_frame_native_from_frame (next_frame);
|
||||
CoglScanout *scanout =
|
||||
meta_frame_native_get_scanout (next_frame_native);
|
||||
|
||||
g_warning ("Direct scanout page flip failed: %s", error->message);
|
||||
|
||||
cogl_scanout_notify_failed (onscreen_native->gbm.next_scanout,
|
||||
onscreen);
|
||||
cogl_scanout_notify_failed (scanout, onscreen);
|
||||
clutter_stage_view_add_redraw_clip (view, NULL);
|
||||
clutter_stage_view_schedule_update_now (view);
|
||||
}
|
||||
|
@ -1646,12 +1643,13 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
|||
render_gpu);
|
||||
|
||||
g_warn_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_fb);
|
||||
g_warn_if_fail (!onscreen_native->gbm.next_scanout);
|
||||
|
||||
g_set_object (&onscreen_native->gbm.next_scanout, scanout);
|
||||
g_set_object (&onscreen_native->gbm.next_fb,
|
||||
META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)));
|
||||
g_warn_if_fail (!onscreen_native->next_frame);
|
||||
onscreen_native->next_frame = clutter_frame_ref (frame);
|
||||
|
||||
meta_frame_native_set_scanout (frame_native, scanout);
|
||||
meta_frame_native_set_buffer (frame_native,
|
||||
META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)));
|
||||
|
||||
frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time ();
|
||||
|
||||
|
@ -1674,7 +1672,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
|||
kms_update,
|
||||
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
|
||||
NULL,
|
||||
0);
|
||||
0,
|
||||
frame);
|
||||
|
||||
meta_topic (META_DEBUG_KMS,
|
||||
"Posting direct scanout update for CRTC %u (%s)",
|
||||
|
@ -2823,15 +2822,15 @@ meta_onscreen_native_dispose (GObject *object)
|
|||
|
||||
meta_onscreen_native_detach (onscreen_native);
|
||||
|
||||
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref);
|
||||
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
|
||||
|
||||
renderer_gpu_data =
|
||||
meta_renderer_native_get_gpu_data (renderer_native,
|
||||
onscreen_native->render_gpu);
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
||||
free_current_bo (onscreen);
|
||||
break;
|
||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||
g_assert_not_reached ();
|
||||
|
|
Loading…
Reference in a new issue