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
@ -27,6 +27,9 @@ struct _MetaFrameNative
|
|||||||
{
|
{
|
||||||
ClutterFrame base;
|
ClutterFrame base;
|
||||||
|
|
||||||
|
MetaDrmBuffer *buffer;
|
||||||
|
CoglScanout *scanout;
|
||||||
|
|
||||||
MetaKmsUpdate *kms_update;
|
MetaKmsUpdate *kms_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +38,9 @@ meta_frame_native_release (ClutterFrame *frame)
|
|||||||
{
|
{
|
||||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (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);
|
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;
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include "backends/native/meta-backend-native-types.h"
|
||||||
#include "backends/native/meta-kms-types.h"
|
#include "backends/native/meta-kms-types.h"
|
||||||
#include "clutter/clutter.h"
|
#include "clutter/clutter.h"
|
||||||
#include "core/util-private.h"
|
#include "core/util-private.h"
|
||||||
@ -36,3 +37,13 @@ MetaKmsUpdate * meta_frame_native_steal_kms_update (MetaFrameNative *frame_nativ
|
|||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
gboolean meta_frame_native_has_kms_update (MetaFrameNative *frame_native);
|
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;
|
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||||
|
|
||||||
|
ClutterFrame *presented_frame;
|
||||||
|
ClutterFrame *next_frame;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct gbm_surface *surface;
|
struct gbm_surface *surface;
|
||||||
MetaDrmBuffer *current_fb;
|
|
||||||
MetaDrmBuffer *next_fb;
|
|
||||||
CoglScanout *current_scanout;
|
|
||||||
CoglScanout *next_scanout;
|
|
||||||
} gbm;
|
} gbm;
|
||||||
|
|
||||||
#ifdef HAVE_EGL_DEVICE
|
#ifdef HAVE_EGL_DEVICE
|
||||||
@ -137,30 +136,17 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
|
|||||||
CoglOnscreen *onscreen,
|
CoglOnscreen *onscreen,
|
||||||
GError **error);
|
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
|
static void
|
||||||
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||||
|
|
||||||
if (!onscreen_native->gbm.next_fb)
|
if (!onscreen_native->next_frame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_current_bo (onscreen);
|
g_clear_pointer (&onscreen_native->presented_frame, clutter_frame_unref);
|
||||||
|
onscreen_native->presented_frame =
|
||||||
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
|
g_steal_pointer (&onscreen_native->next_frame);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -168,8 +154,7 @@ meta_onscreen_native_clear_next_fb (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||||
|
|
||||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
g_clear_pointer (&onscreen_native->next_frame, clutter_frame_unref);
|
||||||
g_clear_object (&onscreen_native->gbm.next_scanout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -298,7 +283,7 @@ page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
|
|||||||
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
|
frame_info = cogl_onscreen_peek_head_frame_info (onscreen);
|
||||||
frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
|
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);
|
meta_onscreen_native_notify_frame_complete (onscreen);
|
||||||
}
|
}
|
||||||
@ -495,16 +480,19 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||||||
MetaKmsUpdate *kms_update,
|
MetaKmsUpdate *kms_update,
|
||||||
MetaKmsAssignPlaneFlag flags,
|
MetaKmsAssignPlaneFlag flags,
|
||||||
const int *rectangles,
|
const int *rectangles,
|
||||||
int n_rectangles)
|
int n_rectangles,
|
||||||
|
ClutterFrame *frame)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
||||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||||
MetaGpuKms *gpu_kms;
|
MetaGpuKms *gpu_kms;
|
||||||
MetaDrmBuffer *buffer;
|
MetaDrmBuffer *buffer;
|
||||||
|
CoglScanout *scanout;
|
||||||
MetaKmsPlaneAssignment *plane_assignment;
|
MetaKmsPlaneAssignment *plane_assignment;
|
||||||
graphene_rect_t src_rect;
|
graphene_rect_t src_rect;
|
||||||
MtkRectangle dst_rect;
|
MtkRectangle dst_rect;
|
||||||
@ -521,14 +509,13 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
|||||||
switch (renderer_gpu_data->mode)
|
switch (renderer_gpu_data->mode)
|
||||||
{
|
{
|
||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
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,
|
cogl_scanout_get_src_rect (scanout, &src_rect);
|
||||||
&src_rect);
|
cogl_scanout_get_dst_rect (scanout, &dst_rect);
|
||||||
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout,
|
|
||||||
&dst_rect);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1299,6 +1286,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
MetaDrmBufferGbm *buffer_gbm;
|
MetaDrmBufferGbm *buffer_gbm;
|
||||||
g_autoptr (MetaDrmBuffer) primary_gpu_fb = NULL;
|
g_autoptr (MetaDrmBuffer) primary_gpu_fb = NULL;
|
||||||
g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL;
|
g_autoptr (MetaDrmBuffer) secondary_gpu_fb = NULL;
|
||||||
|
MetaDrmBuffer *buffer;
|
||||||
MetaKmsCrtc *kms_crtc;
|
MetaKmsCrtc *kms_crtc;
|
||||||
MetaKmsDevice *kms_device;
|
MetaKmsDevice *kms_device;
|
||||||
|
|
||||||
@ -1376,16 +1364,20 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
primary_gpu_fb,
|
primary_gpu_fb,
|
||||||
&secondary_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)
|
switch (renderer_gpu_data->mode)
|
||||||
{
|
{
|
||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
|
|
||||||
if (onscreen_native->secondary_gpu_state)
|
if (onscreen_native->secondary_gpu_state)
|
||||||
g_set_object (&onscreen_native->gbm.next_fb, secondary_gpu_fb);
|
buffer = secondary_gpu_fb;
|
||||||
else
|
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",
|
g_warning ("Failed to ensure KMS FB ID on %s: %s",
|
||||||
meta_device_file_get_path (render_device_file),
|
meta_device_file_get_path (render_device_file),
|
||||||
@ -1434,7 +1426,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
kms_update,
|
kms_update,
|
||||||
META_KMS_ASSIGN_PLANE_FLAG_NONE,
|
META_KMS_ASSIGN_PLANE_FLAG_NONE,
|
||||||
rectangles,
|
rectangles,
|
||||||
n_rectangles);
|
n_rectangles,
|
||||||
|
frame);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1577,11 +1570,15 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
|
|||||||
G_IO_ERROR_PERMISSION_DENIED))
|
G_IO_ERROR_PERMISSION_DENIED))
|
||||||
{
|
{
|
||||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (onscreen_native->view);
|
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);
|
g_warning ("Direct scanout page flip failed: %s", error->message);
|
||||||
|
|
||||||
cogl_scanout_notify_failed (onscreen_native->gbm.next_scanout,
|
cogl_scanout_notify_failed (scanout, onscreen);
|
||||||
onscreen);
|
|
||||||
clutter_stage_view_add_redraw_clip (view, NULL);
|
clutter_stage_view_add_redraw_clip (view, NULL);
|
||||||
clutter_stage_view_schedule_update_now (view);
|
clutter_stage_view_schedule_update_now (view);
|
||||||
}
|
}
|
||||||
@ -1646,12 +1643,13 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
|||||||
render_gpu);
|
render_gpu);
|
||||||
|
|
||||||
g_warn_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
|
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_warn_if_fail (!onscreen_native->next_frame);
|
||||||
g_set_object (&onscreen_native->gbm.next_fb,
|
onscreen_native->next_frame = clutter_frame_ref (frame);
|
||||||
META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)));
|
|
||||||
|
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 ();
|
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,
|
kms_update,
|
||||||
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
|
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0,
|
||||||
|
frame);
|
||||||
|
|
||||||
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)",
|
||||||
@ -2823,15 +2822,15 @@ meta_onscreen_native_dispose (GObject *object)
|
|||||||
|
|
||||||
meta_onscreen_native_detach (onscreen_native);
|
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 =
|
renderer_gpu_data =
|
||||||
meta_renderer_native_get_gpu_data (renderer_native,
|
meta_renderer_native_get_gpu_data (renderer_native,
|
||||||
onscreen_native->render_gpu);
|
onscreen_native->render_gpu);
|
||||||
switch (renderer_gpu_data->mode)
|
switch (renderer_gpu_data->mode)
|
||||||
{
|
{
|
||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
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;
|
break;
|
||||||
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
case META_RENDERER_NATIVE_MODE_SURFACELESS:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user