mirror of
https://github.com/brl/mutter.git
synced 2025-01-22 09:29:25 +00:00
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:
parent
82cdf90a71
commit
52c4b85161
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -426,6 +426,7 @@ typedef enum
|
||||
} CoglStereoMode;
|
||||
|
||||
typedef struct _CoglScanout CoglScanout;
|
||||
typedef struct _CoglScanoutBuffer CoglScanoutBuffer;
|
||||
|
||||
#define COGL_SCANOUT_ERROR (cogl_scanout_error_quark ())
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user