cogl: Turn CoglScanout into an object

We need an object to hold additional scanout related information, such
as scaling and positioning data. Turn CoglScanout into such an object,
moving the interface into CoglScanoutBuffer.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3177>
This commit is contained in:
Robert Mader 2023-08-26 12:39:58 +02:00 committed by Marge Bot
parent 82cdf90a71
commit 52c4b85161
9 changed files with 113 additions and 40 deletions

View File

@ -38,18 +38,20 @@ enum
static guint signals[N_SIGNALS]; static guint signals[N_SIGNALS];
G_DEFINE_INTERFACE (CoglScanout, cogl_scanout, G_TYPE_OBJECT) G_DEFINE_INTERFACE (CoglScanoutBuffer, cogl_scanout_buffer, G_TYPE_OBJECT)
struct _CoglScanout
{
GObject parent;
CoglScanoutBuffer *scanout_buffer;
};
G_DEFINE_FINAL_TYPE (CoglScanout, cogl_scanout, G_TYPE_OBJECT);
static void static void
cogl_scanout_default_init (CoglScanoutInterface *iface) cogl_scanout_buffer_default_init (CoglScanoutBufferInterface *iface)
{ {
signals[SCANOUT_FAILED] =
g_signal_new ("scanout-failed",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
COGL_TYPE_ONSCREEN);
} }
gboolean gboolean
@ -59,16 +61,16 @@ cogl_scanout_blit_to_framebuffer (CoglScanout *scanout,
int y, int y,
GError **error) GError **error)
{ {
CoglScanoutInterface *iface; CoglScanoutBufferInterface *iface =
COGL_SCANOUT_BUFFER_GET_IFACE (scanout->scanout_buffer);
g_return_val_if_fail (COGL_IS_SCANOUT (scanout), FALSE); return iface->blit_to_framebuffer (scanout, framebuffer, x, y, error);
}
iface = COGL_SCANOUT_GET_IFACE (scanout); CoglScanoutBuffer *
cogl_scanout_get_buffer (CoglScanout *scanout)
if (iface->blit_to_framebuffer) {
return iface->blit_to_framebuffer (scanout, framebuffer, x, y, error); return scanout->scanout_buffer;
else
return FALSE;
} }
void void
@ -77,3 +79,44 @@ cogl_scanout_notify_failed (CoglScanout *scanout,
{ {
g_signal_emit (scanout, signals[SCANOUT_FAILED], 0, onscreen); g_signal_emit (scanout, signals[SCANOUT_FAILED], 0, onscreen);
} }
CoglScanout *
cogl_scanout_new (CoglScanoutBuffer *scanout_buffer)
{
CoglScanout *scanout = g_object_new (COGL_TYPE_SCANOUT, NULL);
scanout->scanout_buffer = scanout_buffer;
return scanout;
}
static void
cogl_scanout_finalize (GObject *object)
{
CoglScanout *scanout = COGL_SCANOUT (object);
g_clear_object (&scanout->scanout_buffer);
G_OBJECT_CLASS (cogl_scanout_parent_class)->finalize (object);
}
static void
cogl_scanout_class_init (CoglScanoutClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = cogl_scanout_finalize;
signals[SCANOUT_FAILED] =
g_signal_new ("scanout-failed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1,
COGL_TYPE_ONSCREEN);
}
static void
cogl_scanout_init (CoglScanout *scanout)
{
}

View File

@ -35,10 +35,15 @@
#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ()) #define COGL_TYPE_SCANOUT (cogl_scanout_get_type ())
COGL_EXPORT COGL_EXPORT
G_DECLARE_INTERFACE (CoglScanout, cogl_scanout, G_DECLARE_FINAL_TYPE (CoglScanout, cogl_scanout,
COGL, SCANOUT, GObject) COGL, SCANOUT, GObject)
struct _CoglScanoutInterface #define COGL_TYPE_SCANOUT_BUFFER (cogl_scanout_buffer_get_type ())
COGL_EXPORT
G_DECLARE_INTERFACE (CoglScanoutBuffer, cogl_scanout_buffer,
COGL, SCANOUT_BUFFER, GObject)
struct _CoglScanoutBufferInterface
{ {
GTypeInterface parent_iface; GTypeInterface parent_iface;
@ -56,6 +61,12 @@ gboolean cogl_scanout_blit_to_framebuffer (CoglScanout *scanout,
int y, int y,
GError **error); GError **error);
COGL_EXPORT
CoglScanoutBuffer * cogl_scanout_get_buffer (CoglScanout *scanout);
COGL_EXPORT COGL_EXPORT
void cogl_scanout_notify_failed (CoglScanout *scanout, void cogl_scanout_notify_failed (CoglScanout *scanout,
CoglOnscreen *onscreen); CoglOnscreen *onscreen);
COGL_EXPORT
CoglScanout * cogl_scanout_new (CoglScanoutBuffer *scanout_buffer);

View File

@ -426,6 +426,7 @@ typedef enum
} CoglStereoMode; } CoglStereoMode;
typedef struct _CoglScanout CoglScanout; typedef struct _CoglScanout CoglScanout;
typedef struct _CoglScanoutBuffer CoglScanoutBuffer;
#define COGL_SCANOUT_ERROR (cogl_scanout_error_quark ()) #define COGL_SCANOUT_ERROR (cogl_scanout_error_quark ())

View File

@ -44,11 +44,11 @@ struct _MetaDrmBufferGbm
}; };
static void static void
cogl_scanout_iface_init (CoglScanoutInterface *iface); cogl_scanout_buffer_iface_init (CoglScanoutBufferInterface *iface);
G_DEFINE_TYPE_WITH_CODE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER, G_DEFINE_TYPE_WITH_CODE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER,
G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT, G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT_BUFFER,
cogl_scanout_iface_init)) cogl_scanout_buffer_iface_init))
struct gbm_bo * struct gbm_bo *
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm) meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
@ -236,7 +236,8 @@ meta_drm_buffer_gbm_blit_to_framebuffer (CoglScanout *scanout,
int y, int y,
GError **error) GError **error)
{ {
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (scanout); CoglScanoutBuffer *scanout_buffer = cogl_scanout_get_buffer (scanout);
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (scanout_buffer);
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_gbm); MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_gbm);
MetaDeviceFile *device_file = meta_drm_buffer_get_device_file (buffer); MetaDeviceFile *device_file = meta_drm_buffer_get_device_file (buffer);
MetaDevicePool *device_pool = meta_device_file_get_pool (device_file); MetaDevicePool *device_pool = meta_device_file_get_pool (device_file);
@ -357,7 +358,7 @@ out:
} }
static void static void
cogl_scanout_iface_init (CoglScanoutInterface *iface) cogl_scanout_buffer_iface_init (CoglScanoutBufferInterface *iface)
{ {
iface->blit_to_framebuffer = meta_drm_buffer_gbm_blit_to_framebuffer; iface->blit_to_framebuffer = meta_drm_buffer_gbm_blit_to_framebuffer;
} }

View File

@ -98,6 +98,8 @@ struct _MetaOnscreenNative
struct gbm_surface *surface; struct gbm_surface *surface;
MetaDrmBuffer *current_fb; MetaDrmBuffer *current_fb;
MetaDrmBuffer *next_fb; MetaDrmBuffer *next_fb;
CoglScanout *current_scanout;
CoglScanout *next_scanout;
} gbm; } gbm;
#ifdef HAVE_EGL_DEVICE #ifdef HAVE_EGL_DEVICE
@ -137,6 +139,7 @@ free_current_bo (CoglOnscreen *onscreen)
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
g_clear_object (&onscreen_native->gbm.current_fb); g_clear_object (&onscreen_native->gbm.current_fb);
g_clear_object (&onscreen_native->gbm.current_scanout);
} }
static void static void
@ -151,6 +154,9 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb); g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
g_clear_object (&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);
} }
static void static void
@ -159,6 +165,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_object (&onscreen_native->gbm.next_fb);
g_clear_object (&onscreen_native->gbm.next_scanout);
} }
static void static void
@ -1425,8 +1432,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
} }
gboolean gboolean
meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen, meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaDrmBuffer *fb) CoglScanout *scanout)
{ {
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaCrtc *crtc = onscreen_native->crtc; MetaCrtc *crtc = onscreen_native->crtc;
@ -1435,6 +1442,7 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaKmsDevice *kms_device; MetaKmsDevice *kms_device;
MetaKmsCrtc *kms_crtc; MetaKmsCrtc *kms_crtc;
MetaKmsUpdate *test_update; MetaKmsUpdate *test_update;
MetaDrmBuffer *buffer;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
MetaKmsFeedbackResult result; MetaKmsFeedbackResult result;
@ -1443,7 +1451,8 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
test_update = meta_kms_update_new (kms_device); test_update = meta_kms_update_new (kms_device);
assign_primary_plane (crtc_kms, fb, test_update, buffer = META_DRM_BUFFER (cogl_scanout_get_buffer (scanout));
assign_primary_plane (crtc_kms, buffer, test_update,
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT); META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT);
meta_topic (META_DEBUG_KMS, meta_topic (META_DEBUG_KMS,
@ -1480,7 +1489,7 @@ scanout_result_feedback (const MetaKmsFeedback *kms_feedback,
g_warning ("Direct scanout page flip failed: %s", error->message); g_warning ("Direct scanout page flip failed: %s", error->message);
cogl_scanout_notify_failed (COGL_SCANOUT (onscreen_native->gbm.next_fb), cogl_scanout_notify_failed (onscreen_native->gbm.next_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);
@ -1547,8 +1556,11 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
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_fb);
g_warn_if_fail (!onscreen_native->gbm.next_scanout);
g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (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)));
frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); frame_info->cpu_time_before_buffer_swap_us = g_get_monotonic_time ();
@ -2666,6 +2678,7 @@ meta_onscreen_native_dispose (GObject *object)
{ {
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_fb);
g_clear_object (&onscreen_native->gbm.next_scanout);
free_current_bo (onscreen); free_current_bo (onscreen);
break; break;
case META_RENDERER_NATIVE_MODE_SURFACELESS: case META_RENDERER_NATIVE_MODE_SURFACELESS:

View File

@ -45,8 +45,8 @@ void meta_onscreen_native_finish_frame (CoglOnscreen *onscreen,
void meta_onscreen_native_dummy_power_save_page_flip (CoglOnscreen *onscreen); void meta_onscreen_native_dummy_power_save_page_flip (CoglOnscreen *onscreen);
gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen, gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaDrmBuffer *fb); CoglScanout *scanout);
void meta_onscreen_native_set_view (CoglOnscreen *onscreen, void meta_onscreen_native_set_view (CoglOnscreen *onscreen,
MetaRendererView *view); MetaRendererView *view);

View File

@ -133,14 +133,16 @@ on_scanout_before_paint (ClutterStage *stage,
KmsRenderingTest *test) KmsRenderingTest *test)
{ {
CoglScanout *scanout; CoglScanout *scanout;
CoglScanoutBuffer *scanout_buffer;
MetaDrmBuffer *buffer; MetaDrmBuffer *buffer;
scanout = clutter_stage_view_peek_scanout (stage_view); scanout = clutter_stage_view_peek_scanout (stage_view);
if (!scanout) if (!scanout)
return; return;
g_assert_true (META_IS_DRM_BUFFER (scanout)); scanout_buffer = cogl_scanout_get_buffer (scanout);
buffer = META_DRM_BUFFER (scanout); g_assert_true (META_IS_DRM_BUFFER (scanout_buffer));
buffer = META_DRM_BUFFER (scanout_buffer);
test->scanout.fb_id = meta_drm_buffer_get_fb_id (buffer); test->scanout.fb_id = meta_drm_buffer_get_fb_id (buffer);
g_assert_cmpuint (test->scanout.fb_id, >, 0); g_assert_cmpuint (test->scanout.fb_id, >, 0);
} }

View File

@ -863,6 +863,7 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
struct gbm_bo *gbm_bo; struct gbm_bo *gbm_bo;
MetaDrmBufferFlags flags; MetaDrmBufferFlags flags;
g_autoptr (MetaDrmBufferGbm) fb = NULL; g_autoptr (MetaDrmBufferGbm) fb = NULL;
g_autoptr (CoglScanout) scanout = NULL;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native); gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
@ -887,11 +888,11 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
return NULL; return NULL;
} }
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout = cogl_scanout_new (COGL_SCANOUT_BUFFER (g_steal_pointer (&fb)));
META_DRM_BUFFER (fb))) if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout))
return NULL; return NULL;
return COGL_SCANOUT (g_steal_pointer (&fb)); return g_steal_pointer (&scanout);
#else #else
return NULL; return NULL;
#endif #endif

View File

@ -618,6 +618,7 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer,
MetaGpuKms *gpu_kms; MetaGpuKms *gpu_kms;
struct gbm_bo *gbm_bo; struct gbm_bo *gbm_bo;
g_autoptr (MetaDrmBufferGbm) fb = NULL; g_autoptr (MetaDrmBufferGbm) fb = NULL;
g_autoptr (CoglScanout) scanout = NULL;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
MetaDrmBufferFlags flags; MetaDrmBufferFlags flags;
gboolean use_modifier; gboolean use_modifier;
@ -662,15 +663,15 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer,
return NULL; return NULL;
} }
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout = cogl_scanout_new (COGL_SCANOUT_BUFFER (g_steal_pointer (&fb)));
META_DRM_BUFFER (fb))) if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout))
{ {
meta_topic (META_DEBUG_RENDER, meta_topic (META_DEBUG_RENDER,
"Buffer not scanout compatible (see also KMS debug topic)"); "Buffer not scanout compatible (see also KMS debug topic)");
return NULL; return NULL;
} }
return COGL_SCANOUT (g_steal_pointer (&fb)); return g_steal_pointer (&scanout);
#else #else
return NULL; return NULL;
#endif #endif