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];
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
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
@ -59,16 +61,16 @@ cogl_scanout_blit_to_framebuffer (CoglScanout *scanout,
int y,
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);
if (iface->blit_to_framebuffer)
return iface->blit_to_framebuffer (scanout, framebuffer, x, y, error);
else
return FALSE;
CoglScanoutBuffer *
cogl_scanout_get_buffer (CoglScanout *scanout)
{
return scanout->scanout_buffer;
}
void
@ -77,3 +79,44 @@ cogl_scanout_notify_failed (CoglScanout *scanout,
{
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 ())
COGL_EXPORT
G_DECLARE_INTERFACE (CoglScanout, cogl_scanout,
COGL, SCANOUT, GObject)
G_DECLARE_FINAL_TYPE (CoglScanout, cogl_scanout,
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;
@ -56,6 +61,12 @@ gboolean cogl_scanout_blit_to_framebuffer (CoglScanout *scanout,
int y,
GError **error);
COGL_EXPORT
CoglScanoutBuffer * cogl_scanout_get_buffer (CoglScanout *scanout);
COGL_EXPORT
void cogl_scanout_notify_failed (CoglScanout *scanout,
CoglOnscreen *onscreen);
COGL_EXPORT
CoglScanout * cogl_scanout_new (CoglScanoutBuffer *scanout_buffer);

View File

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

View File

@ -44,11 +44,11 @@ struct _MetaDrmBufferGbm
};
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_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT,
cogl_scanout_iface_init))
G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT_BUFFER,
cogl_scanout_buffer_iface_init))
struct gbm_bo *
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
@ -236,7 +236,8 @@ meta_drm_buffer_gbm_blit_to_framebuffer (CoglScanout *scanout,
int y,
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);
MetaDeviceFile *device_file = meta_drm_buffer_get_device_file (buffer);
MetaDevicePool *device_pool = meta_device_file_get_pool (device_file);
@ -357,7 +358,7 @@ out:
}
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;
}

View File

@ -98,6 +98,8 @@ struct _MetaOnscreenNative
struct gbm_surface *surface;
MetaDrmBuffer *current_fb;
MetaDrmBuffer *next_fb;
CoglScanout *current_scanout;
CoglScanout *next_scanout;
} gbm;
#ifdef HAVE_EGL_DEVICE
@ -137,6 +139,7 @@ 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
@ -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_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
@ -159,6 +165,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);
}
static void
@ -1425,8 +1432,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
}
gboolean
meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaDrmBuffer *fb)
meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
CoglScanout *scanout)
{
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
MetaCrtc *crtc = onscreen_native->crtc;
@ -1435,6 +1442,7 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaKmsDevice *kms_device;
MetaKmsCrtc *kms_crtc;
MetaKmsUpdate *test_update;
MetaDrmBuffer *buffer;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
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);
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_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);
cogl_scanout_notify_failed (COGL_SCANOUT (onscreen_native->gbm.next_fb),
cogl_scanout_notify_failed (onscreen_native->gbm.next_scanout,
onscreen);
clutter_stage_view_add_redraw_clip (view, NULL);
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 (!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 ();
@ -2666,6 +2678,7 @@ meta_onscreen_native_dispose (GObject *object)
{
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:

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);
gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaDrmBuffer *fb);
gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
CoglScanout *scanout);
void meta_onscreen_native_set_view (CoglOnscreen *onscreen,
MetaRendererView *view);

View File

@ -133,14 +133,16 @@ on_scanout_before_paint (ClutterStage *stage,
KmsRenderingTest *test)
{
CoglScanout *scanout;
CoglScanoutBuffer *scanout_buffer;
MetaDrmBuffer *buffer;
scanout = clutter_stage_view_peek_scanout (stage_view);
if (!scanout)
return;
g_assert_true (META_IS_DRM_BUFFER (scanout));
buffer = META_DRM_BUFFER (scanout);
scanout_buffer = cogl_scanout_get_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);
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;
MetaDrmBufferFlags flags;
g_autoptr (MetaDrmBufferGbm) fb = NULL;
g_autoptr (CoglScanout) scanout = NULL;
g_autoptr (GError) error = NULL;
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
@ -887,11 +888,11 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
return NULL;
}
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen,
META_DRM_BUFFER (fb)))
scanout = cogl_scanout_new (COGL_SCANOUT_BUFFER (g_steal_pointer (&fb)));
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout))
return NULL;
return COGL_SCANOUT (g_steal_pointer (&fb));
return g_steal_pointer (&scanout);
#else
return NULL;
#endif

View File

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