[mutter] cursor-renderer/native: Update HW state during frames
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] cursor-renderer/native: Update HW state during frames
- Date: Fri, 22 Jan 2021 17:08:31 +0000 (UTC)
commit c98575344295b715a0301c7319195b2724dc2bde
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Sat Oct 10 01:02:28 2020 +0200
cursor-renderer/native: Update HW state during frames
Before each frame is maybe redrawn, push any new cursor KMS state to the
pending update. It'll then either be posted during the next page flip,
or when the same frame finishes, in case nothing was redrawn.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
clutter/clutter/clutter-stage-view.c | 2 +
clutter/clutter/clutter-stage-window.c | 11 +
clutter/clutter/clutter-stage-window.h | 7 +
clutter/clutter/cogl/clutter-stage-cogl.c | 15 +
clutter/clutter/cogl/clutter-stage-cogl.h | 4 +
src/backends/meta-monitor.c | 22 ++
src/backends/meta-monitor.h | 4 +
src/backends/native/meta-cursor-renderer-native.c | 451 ++++++++++------------
src/backends/native/meta-cursor-renderer-native.h | 3 +
src/backends/native/meta-renderer-native.c | 75 +++-
src/backends/native/meta-renderer-native.h | 6 +-
src/backends/native/meta-stage-native.c | 24 +-
12 files changed, 363 insertions(+), 261 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 66d052ebe7..436ce40b29 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -1099,6 +1099,8 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
frame = CLUTTER_FRAME_INIT;
+ _clutter_stage_window_prepare_frame (stage_window, view, &frame);
+
if (clutter_stage_view_has_redraw_clip (view))
{
clutter_stage_emit_before_paint (stage, view);
diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
index 5f7c489675..9052a8c4bf 100644
--- a/clutter/clutter/clutter-stage-window.c
+++ b/clutter/clutter/clutter-stage-window.c
@@ -135,6 +135,17 @@ _clutter_stage_window_get_views (ClutterStageWindow *window)
return iface->get_views (window);
}
+void
+_clutter_stage_window_prepare_frame (ClutterStageWindow *window,
+ ClutterStageView *view,
+ ClutterFrame *frame)
+{
+ ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+ if (iface->prepare_frame)
+ iface->prepare_frame (window, view, frame);
+}
+
void
_clutter_stage_window_finish_frame (ClutterStageWindow *window,
ClutterStageView *view,
diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
index b1ebd2badf..5f0ae7ab16 100644
--- a/clutter/clutter/clutter-stage-window.h
+++ b/clutter/clutter/clutter-stage-window.h
@@ -52,6 +52,9 @@ struct _ClutterStageWindowInterface
GList *(* get_views) (ClutterStageWindow *stage_window);
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
+ void (* prepare_frame) (ClutterStageWindow *stage_window,
+ ClutterStageView *view,
+ ClutterFrame *frame);
void (* finish_frame) (ClutterStageWindow *stage_window,
ClutterStageView *view,
ClutterFrame *frame);
@@ -89,6 +92,10 @@ gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWin
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
+void _clutter_stage_window_prepare_frame (ClutterStageWindow *window,
+ ClutterStageView *view,
+ ClutterFrame *frame);
+
void _clutter_stage_window_finish_frame (ClutterStageWindow *window,
ClutterStageView *view,
ClutterFrame *frame);
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 90f428ec81..2e14ec9ebc 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -731,6 +731,21 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
clutter_stage_cogl_redraw_view_primary (stage_cogl, view, frame);
}
+void
+clutter_stage_cogl_add_onscreen_frame_info (ClutterStageCogl *stage_cogl,
+ ClutterStageView *view)
+{
+ ClutterStageCoglPrivate *priv =
+ _clutter_stage_cogl_get_instance_private (stage_cogl);
+ CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
+ CoglFrameInfo *frame_info;
+
+ frame_info = cogl_frame_info_new (priv->global_frame_counter);
+ priv->global_frame_counter++;
+
+ cogl_onscreen_add_frame_info (COGL_ONSCREEN (framebuffer), frame_info);
+}
+
static void
clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
{
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h
index a67ba96152..11aeaefe12 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.h
+++ b/clutter/clutter/cogl/clutter-stage-cogl.h
@@ -56,6 +56,10 @@ void _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
CoglFrameEvent frame_event,
ClutterFrameInfo *frame_info);
+CLUTTER_EXPORT
+void clutter_stage_cogl_add_onscreen_frame_info (ClutterStageCogl *stage_cogl,
+ ClutterStageView *view);
+
G_END_DECLS
#endif /* __CLUTTER_STAGE_COGL_H__ */
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 07c574de2b..0be7994ad5 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -1948,6 +1948,28 @@ meta_monitor_mode_foreach_output (MetaMonitor *monitor,
return TRUE;
}
+MetaMonitorCrtcMode *
+meta_monitor_get_crtc_mode_for_output (MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ MetaOutput *output)
+{
+ MetaMonitorPrivate *monitor_priv =
+ meta_monitor_get_instance_private (monitor);
+ GList *l;
+ int i;
+
+ for (l = monitor_priv->outputs, i = 0; l; l = l->next, i++)
+ {
+ MetaMonitorCrtcMode *monitor_crtc_mode = &mode->crtc_modes[i];
+
+ if (monitor_crtc_mode->output == output)
+ return monitor_crtc_mode;
+ }
+
+ g_warn_if_reached ();
+ return NULL;
+}
+
const char *
meta_monitor_get_display_name (MetaMonitor *monitor)
{
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index eb6b99fea1..96f280a89e 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -264,6 +264,10 @@ gboolean meta_monitor_mode_foreach_output (MetaMonitor *monitor,
gpointer user_data,
GError **error);
+MetaMonitorCrtcMode * meta_monitor_get_crtc_mode_for_output (MetaMonitor *monitor,
+ MetaMonitorMode *mode,
+ MetaOutput *output);
+
META_EXPORT_TEST
gboolean meta_monitor_mode_should_be_advertised (MetaMonitorMode *monitor_mode);
diff --git a/src/backends/native/meta-cursor-renderer-native.c
b/src/backends/native/meta-cursor-renderer-native.c
index ff175e8e2e..3899bd205c 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -80,6 +80,8 @@ static GQuark quark_cursor_sprite = 0;
typedef struct _CrtcCursorData
{
MetaDrmBuffer *buffer;
+ gboolean needs_sync_position;
+ gboolean hw_state_invalidated;
} CrtcCursorData;
struct _MetaCursorRendererNative
@@ -91,7 +93,6 @@ struct _MetaCursorRendererNativePrivate
{
MetaBackend *backend;
- gboolean hw_state_invalidated;
gboolean has_hw_cursor;
MetaCursorSprite *last_cursor;
@@ -137,6 +138,10 @@ static GQuark quark_cursor_renderer_native_gpu_data = 0;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native,
META_TYPE_CURSOR_RENDERER);
+static void
+on_kms_update_result (const MetaKmsFeedback *kms_feedback,
+ gpointer user_data);
+
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
@@ -266,6 +271,7 @@ ensure_crtc_cursor_data (MetaCrtcKms *crtc_kms)
if (!crtc_cursor_data)
{
crtc_cursor_data = g_new0 (CrtcCursorData, 1);
+ crtc_cursor_data->hw_state_invalidated = TRUE;
meta_crtc_kms_set_cursor_renderer_private (crtc_kms,
crtc_cursor_data,
g_free);
@@ -275,15 +281,12 @@ ensure_crtc_cursor_data (MetaCrtcKms *crtc_kms)
}
static void
-set_crtc_cursor (MetaCursorRendererNative *native,
- MetaKmsUpdate *kms_update,
- MetaCrtcKms *crtc_kms,
- int x,
- int y,
- MetaCursorSprite *cursor_sprite)
+assign_cursor_plane (MetaCursorRendererNative *native,
+ MetaCrtcKms *crtc_kms,
+ int x,
+ int y,
+ MetaCursorSprite *cursor_sprite)
{
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
MetaCrtc *crtc = META_CRTC (crtc_kms);
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
@@ -303,6 +306,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
CrtcCursorData *crtc_cursor_data;
int cursor_hotspot_x;
int cursor_hotspot_y;
+ MetaKmsUpdate *kms_update;
MetaKmsPlaneAssignment *plane_assignment;
if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
@@ -333,9 +337,12 @@ set_crtc_cursor (MetaCursorRendererNative *native,
flags = META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL;
crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
crtc_buffer = crtc_cursor_data->buffer;
- if (!priv->hw_state_invalidated && buffer == crtc_buffer)
+ if (!crtc_cursor_data->hw_state_invalidated && buffer == crtc_buffer)
flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
+ kms_update =
+ meta_kms_ensure_pending_update (meta_kms_device_get_kms (kms_device),
+ meta_kms_crtc_get_device (kms_crtc));
plane_assignment = meta_kms_update_assign_plane (kms_update,
kms_crtc,
cursor_plane,
@@ -351,6 +358,10 @@ set_crtc_cursor (MetaCursorRendererNative *native,
cursor_hotspot_x,
cursor_hotspot_y);
+ meta_kms_update_add_result_listener (kms_update,
+ on_kms_update_result,
+ native);
+
crtc_cursor_data->buffer = buffer;
if (cursor_gpu_state->pending_buffer_state == META_CURSOR_BUFFER_STATE_SET)
@@ -361,35 +372,6 @@ set_crtc_cursor (MetaCursorRendererNative *native,
}
}
-static void
-unset_crtc_cursor (MetaCursorRendererNative *native,
- MetaKmsUpdate *kms_update,
- MetaCrtcKms *crtc_kms)
-{
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- MetaKmsCrtc *kms_crtc;
- MetaKmsDevice *kms_device;
- MetaKmsPlane *cursor_plane;
- MetaDrmBuffer *crtc_buffer;
- CrtcCursorData *crtc_cursor_data;
-
- crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
- if (!priv->hw_state_invalidated && !crtc_buffer)
- return;
-
- kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
- kms_device = meta_kms_crtc_get_device (kms_crtc);
- cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
-
- if (cursor_plane)
- meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
-
- crtc_cursor_data = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
- if (crtc_cursor_data)
- crtc_cursor_data->buffer = NULL;
-}
-
static float
calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite,
MetaLogicalMonitor *logical_monitor)
@@ -405,139 +387,121 @@ calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite,
}
}
-typedef struct
-{
- MetaCursorRendererNative *in_cursor_renderer_native;
- MetaLogicalMonitor *in_logical_monitor;
- graphene_rect_t in_local_cursor_rect;
- MetaCursorSprite *in_cursor_sprite;
-
- gboolean out_painted;
-} UpdateCrtcCursorData;
-
-static gboolean
-update_monitor_crtc_cursor (MetaMonitor *monitor,
- MetaMonitorMode *monitor_mode,
- MetaMonitorCrtcMode *monitor_crtc_mode,
- gpointer user_data,
- GError **error)
+static void
+set_crtc_cursor (MetaCursorRendererNative *cursor_renderer_native,
+ MetaRendererView *view,
+ MetaCrtc *crtc,
+ MetaCursorSprite *cursor_sprite)
{
- UpdateCrtcCursorData *data = user_data;
- MetaCursorRendererNative *cursor_renderer_native =
- data->in_cursor_renderer_native;
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
- MetaCrtc *crtc;
- MetaGpuKms *gpu_kms;
- MetaKmsDevice *kms_device;
- MetaKms *kms;
- MetaKmsUpdate *kms_update;
+ MetaCursorRenderer *cursor_renderer =
+ META_CURSOR_RENDERER (cursor_renderer_native);
+ MetaOutput *output = meta_crtc_get_outputs (crtc)->data;
+ MetaMonitor *monitor = meta_output_get_monitor (output);
+ MetaLogicalMonitor *logical_monitor =
+ meta_monitor_get_logical_monitor (monitor);
+ const MetaCrtcConfig *crtc_config = meta_crtc_get_config (crtc);
+ graphene_rect_t rect;
+ graphene_rect_t local_crtc_rect;
+ graphene_rect_t local_cursor_rect;
+ float view_scale;
+ float crtc_cursor_x, crtc_cursor_y;
+ CoglTexture *texture;
+ int tex_width, tex_height;
+ float cursor_crtc_scale;
+ MetaRectangle cursor_rect;
MetaMonitorTransform transform;
+ MetaMonitorTransform inverted_transform;
+ MetaMonitorMode *monitor_mode;
+ MetaMonitorCrtcMode *monitor_crtc_mode;
const MetaCrtcModeInfo *crtc_mode_info;
- graphene_rect_t scaled_crtc_rect;
- float scale;
- int crtc_x, crtc_y;
- int crtc_width, crtc_height;
- if (meta_is_stage_views_scaled ())
- scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
- else
- scale = 1.0;
+ view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view));
- transform = meta_logical_monitor_get_transform (data->in_logical_monitor);
- transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
+ rect = meta_cursor_renderer_calculate_rect (cursor_renderer, cursor_sprite);
+ local_cursor_rect =
+ GRAPHENE_RECT_INIT (rect.origin.x - logical_monitor->rect.x,
+ rect.origin.y - logical_monitor->rect.y,
+ rect.size.width,
+ rect.size.height);
- meta_monitor_calculate_crtc_pos (monitor, monitor_mode,
- monitor_crtc_mode->output,
- transform,
- &crtc_x, &crtc_y);
-
- crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
+ local_crtc_rect = crtc_config->layout;
+ graphene_rect_offset (&local_crtc_rect,
+ -logical_monitor->rect.x,
+ -logical_monitor->rect.y);
- if (meta_monitor_transform_is_rotated (transform))
- {
- crtc_width = crtc_mode_info->height;
- crtc_height = crtc_mode_info->width;
- }
- else
- {
- crtc_width = crtc_mode_info->width;
- crtc_height = crtc_mode_info->height;
- }
+ crtc_cursor_x = (local_cursor_rect.origin.x -
+ local_crtc_rect.origin.x) * view_scale;
+ crtc_cursor_y = (local_cursor_rect.origin.y -
+ local_crtc_rect.origin.y) * view_scale;
- scaled_crtc_rect = (graphene_rect_t) {
- .origin = {
- .x = crtc_x / scale,
- .y = crtc_y / scale
- },
- .size = {
- .width = crtc_width / scale,
- .height = crtc_height / scale
- },
+ texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
+ tex_width = cogl_texture_get_width (texture);
+ tex_height = cogl_texture_get_height (texture);
+
+ cursor_crtc_scale =
+ calculate_cursor_crtc_sprite_scale (cursor_sprite,
+ logical_monitor);
+
+ cursor_rect = (MetaRectangle) {
+ .x = floorf (crtc_cursor_x),
+ .y = floorf (crtc_cursor_y),
+ .width = roundf (tex_width * cursor_crtc_scale),
+ .height = roundf (tex_height * cursor_crtc_scale)
};
- crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
- gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
- kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
- kms = meta_kms_device_get_kms (kms_device);
- kms_update = meta_kms_ensure_pending_update (kms, kms_device);
+ transform = meta_logical_monitor_get_transform (logical_monitor);
+ transform = meta_monitor_logical_to_crtc_transform (monitor, transform);
- if (priv->has_hw_cursor &&
- graphene_rect_intersection (&scaled_crtc_rect,
- &data->in_local_cursor_rect,
- NULL))
- {
- MetaMonitorTransform inverted_transform;
- MetaRectangle cursor_rect;
- CoglTexture *texture;
- float crtc_cursor_x, crtc_cursor_y;
- float cursor_crtc_scale;
- int tex_width, tex_height;
-
- crtc_cursor_x = (data->in_local_cursor_rect.origin.x -
- scaled_crtc_rect.origin.x) * scale;
- crtc_cursor_y = (data->in_local_cursor_rect.origin.y -
- scaled_crtc_rect.origin.y) * scale;
-
- texture = meta_cursor_sprite_get_cogl_texture (data->in_cursor_sprite);
- tex_width = cogl_texture_get_width (texture);
- tex_height = cogl_texture_get_height (texture);
-
- cursor_crtc_scale =
- calculate_cursor_crtc_sprite_scale (data->in_cursor_sprite,
- data->in_logical_monitor);
-
- cursor_rect = (MetaRectangle) {
- .x = floorf (crtc_cursor_x),
- .y = floorf (crtc_cursor_y),
- .width = roundf (tex_width * cursor_crtc_scale),
- .height = roundf (tex_height * cursor_crtc_scale)
- };
-
- inverted_transform = meta_monitor_transform_invert (transform);
- meta_rectangle_transform (&cursor_rect,
- inverted_transform,
- crtc_mode_info->width,
- crtc_mode_info->height,
- &cursor_rect);
-
- set_crtc_cursor (data->in_cursor_renderer_native,
- kms_update,
+ inverted_transform = meta_monitor_transform_invert (transform);
+
+ monitor_mode = meta_monitor_get_current_mode (monitor);
+ monitor_crtc_mode = meta_monitor_get_crtc_mode_for_output (monitor,
+ monitor_mode,
+ output);
+ crtc_mode_info = meta_crtc_mode_get_info (monitor_crtc_mode->crtc_mode);
+ meta_rectangle_transform (&cursor_rect,
+ inverted_transform,
+ crtc_mode_info->width,
+ crtc_mode_info->height,
+ &cursor_rect);
+
+ assign_cursor_plane (cursor_renderer_native,
META_CRTC_KMS (crtc),
cursor_rect.x,
cursor_rect.y,
- data->in_cursor_sprite);
+ cursor_sprite);
+}
- data->out_painted = data->out_painted || TRUE;
- }
- else
+static void
+unset_crtc_cursor (MetaCursorRendererNative *native,
+ MetaCrtc *crtc)
+{
+ MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
+ CrtcCursorData *crtc_cursor_data;
+ MetaKmsCrtc *kms_crtc;
+ MetaKmsDevice *kms_device;
+ MetaKmsPlane *cursor_plane;
+ MetaDrmBuffer *crtc_buffer;
+
+ crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
+ crtc_buffer = crtc_cursor_data->buffer;
+ if (!crtc_cursor_data->hw_state_invalidated && !crtc_buffer)
+ return;
+
+ kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
+ kms_device = meta_kms_crtc_get_device (kms_crtc);
+ cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
+
+ if (cursor_plane)
{
- unset_crtc_cursor (data->in_cursor_renderer_native,
- kms_update,
- META_CRTC_KMS (crtc));
+ MetaKms *kms = meta_kms_device_get_kms (kms_device);
+ MetaKmsUpdate *kms_update;
+
+ kms_update = meta_kms_ensure_pending_update (kms, kms_device);
+ meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
}
- return TRUE;
+ crtc_cursor_data->buffer = NULL;
}
static void
@@ -556,68 +520,61 @@ disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
cursor_renderer_gpu_data->hw_cursor_broken = TRUE;
}
-static void
-update_hw_cursor (MetaCursorRendererNative *native,
- MetaCursorSprite *cursor_sprite)
+void
+meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native,
+ MetaRendererView *view)
{
+ MetaCursorRenderer *cursor_renderer =
+ META_CURSOR_RENDERER (cursor_renderer_native);
MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
+ meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaBackend *backend = priv->backend;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
- GList *logical_monitors;
- GList *l;
- graphene_rect_t rect;
- gboolean painted = FALSE;
+ MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
+ MetaCursorSprite *cursor_sprite;
+ graphene_rect_t cursor_rect;
+ cairo_rectangle_int_t view_layout;
+ graphene_rect_t view_rect;
+ CrtcCursorData *crtc_cursor_data;
- if (cursor_sprite)
- rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
- else
- rect = GRAPHENE_RECT_INIT_ZERO;
+ if (meta_monitor_manager_get_power_save_mode (monitor_manager) !=
+ META_POWER_SAVE_ON)
+ return;
- logical_monitors =
- meta_monitor_manager_get_logical_monitors (monitor_manager);
- for (l = logical_monitors; l; l = l->next)
- {
- MetaLogicalMonitor *logical_monitor = l->data;
- UpdateCrtcCursorData data;
- GList *monitors;
- GList *k;
-
- data = (UpdateCrtcCursorData) {
- .in_cursor_renderer_native = native,
- .in_logical_monitor = logical_monitor,
- .in_local_cursor_rect = (graphene_rect_t) {
- .origin = {
- .x = rect.origin.x - logical_monitor->rect.x,
- .y = rect.origin.y - logical_monitor->rect.y
- },
- .size = rect.size
- },
- .in_cursor_sprite = cursor_sprite,
- };
+ crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc));
+ if (!crtc_cursor_data->hw_state_invalidated &&
+ !crtc_cursor_data->needs_sync_position)
+ return;
- monitors = meta_logical_monitor_get_monitors (logical_monitor);
- for (k = monitors; k; k = k->next)
- {
- MetaMonitor *monitor = k->data;
- MetaMonitorMode *monitor_mode;
-
- monitor_mode = meta_monitor_get_current_mode (monitor);
- meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
- update_monitor_crtc_cursor,
- &data,
- NULL);
- }
+ cursor_sprite = meta_cursor_renderer_get_cursor (cursor_renderer);
+ if (!cursor_sprite)
+ goto unset_cursor;
- painted = painted || data.out_painted;
- }
+ if (!priv->has_hw_cursor)
+ goto unset_cursor;
+
+ cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
+ cursor_sprite);
+ clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
+ view_rect = GRAPHENE_RECT_INIT (view_layout.x, view_layout.y,
+ view_layout.width, view_layout.height);
+ if (!graphene_rect_intersection (&cursor_rect, &view_rect, NULL))
+ goto unset_cursor;
- priv->hw_state_invalidated = FALSE;
+ set_crtc_cursor (cursor_renderer_native, view, crtc, cursor_sprite);
- if (painted)
- meta_cursor_renderer_emit_painted (renderer, cursor_sprite);
+ meta_cursor_renderer_emit_painted (cursor_renderer, cursor_sprite);
+
+ crtc_cursor_data->needs_sync_position = FALSE;
+ crtc_cursor_data->hw_state_invalidated = FALSE;
+ return;
+
+unset_cursor:
+ unset_crtc_cursor (cursor_renderer_native, crtc);
+
+ crtc_cursor_data = ensure_crtc_cursor_data (META_CRTC_KMS (crtc));
+ crtc_cursor_data->hw_state_invalidated = FALSE;
}
static gboolean
@@ -1074,6 +1031,29 @@ on_kms_update_result (const MetaKmsFeedback *kms_feedback,
}
}
+static void
+schedule_sync_position (MetaCursorRendererNative *cursor_renderer_native)
+{
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
+ GList *l;
+
+ for (l = meta_backend_get_gpus (priv->backend); l; l = l->next)
+ {
+ MetaGpu *gpu = l->data;
+ GList *l_crtc;
+
+ for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
+ {
+ MetaCrtcKms *crtc_kms = META_CRTC_KMS (l_crtc->data);
+ CrtcCursorData *crtc_cursor_data;
+
+ crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
+ crtc_cursor_data->needs_sync_position = TRUE;
+ }
+ }
+}
+
static gboolean
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
@@ -1081,10 +1061,7 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
- MetaRendererNative *renderer_native =
- META_RENDERER_NATIVE (meta_backend_get_renderer (priv->backend));
- MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend);
- MetaKms *kms = meta_backend_native_get_kms (backend_native);
+ ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (priv->backend));
g_autoptr (GList) gpus = NULL;
if (cursor_sprite)
@@ -1097,43 +1074,9 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite);
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus);
- update_hw_cursor (native, cursor_sprite);
-
- if (!meta_renderer_native_is_mode_set_pending (renderer_native))
- {
- GList *l;
- for (l = meta_kms_get_devices (kms); l; l = l->next)
- {
- MetaKmsDevice *kms_device = l->data;
- MetaKmsUpdateFlag flags;
- g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
-
- flags = META_KMS_UPDATE_FLAG_NONE;
- kms_feedback = meta_kms_post_pending_update_sync (kms,
- kms_device,
- flags);
- on_kms_update_result (kms_feedback, renderer);
- }
- }
- else
- {
- GList *l;
-
- for (l = meta_kms_get_devices (kms); l; l = l->next)
- {
- MetaKmsDevice *kms_device = l->data;
- MetaKmsUpdate *kms_update;
-
- kms_update = meta_kms_get_pending_update (kms, kms_device);
- if (!kms_update)
- continue;
-
- meta_kms_update_add_result_listener (kms_update,
- on_kms_update_result,
- renderer);
- }
- }
+ schedule_sync_position (native);
+ clutter_stage_schedule_update (stage);
return (priv->has_hw_cursor ||
!cursor_sprite ||
@@ -1779,8 +1722,23 @@ force_update_hw_cursor (MetaCursorRendererNative *native)
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
+ GList *l;
+
+ for (l = meta_backend_get_gpus (priv->backend); l; l = l->next)
+ {
+ MetaGpu *gpu = l->data;
+ GList *l_crtc;
+
+ for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next)
+ {
+ MetaCrtcKms *crtc_kms = META_CRTC_KMS (l_crtc->data);
+ CrtcCursorData *crtc_cursor_data;
+
+ crtc_cursor_data = ensure_crtc_cursor_data (crtc_kms);
+ crtc_cursor_data->hw_state_invalidated = TRUE;
+ }
+ }
- priv->hw_state_invalidated = TRUE;
meta_cursor_renderer_force_update (renderer);
}
@@ -1863,7 +1821,6 @@ meta_cursor_renderer_native_new (MetaBackend *backend,
G_CALLBACK (on_gpu_added_for_cursor), NULL);
priv->backend = backend;
- priv->hw_state_invalidated = TRUE;
init_hw_cursor_support (cursor_renderer_native);
diff --git a/src/backends/native/meta-cursor-renderer-native.h
b/src/backends/native/meta-cursor-renderer-native.h
index 26c698cda5..5113b96ce1 100644
--- a/src/backends/native/meta-cursor-renderer-native.h
+++ b/src/backends/native/meta-cursor-renderer-native.h
@@ -33,6 +33,9 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native,
META, CURSOR_RENDERER_NATIVE,
MetaCursorRenderer)
+void meta_cursor_renderer_native_prepare_frame (MetaCursorRendererNative *cursor_renderer_native,
+ MetaRendererView *view);
+
MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend,
ClutterInputDevice *device);
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 9efee2c1fe..f1b9c749b9 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -2345,12 +2345,6 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
return NULL;
}
-gboolean
-meta_renderer_native_is_mode_set_pending (MetaRendererNative *renderer_native)
-{
- return renderer_native->pending_mode_set;
-}
-
gboolean
meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
uint32_t drm_format,
@@ -3286,9 +3280,76 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
}
+static void
+add_onscreen_frame_info (MetaCrtc *crtc)
+{
+ MetaGpu *gpu = meta_crtc_get_gpu (crtc);
+ MetaBackend *backend = meta_gpu_get_backend (gpu);
+ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+ MetaStageNative *stage_native =
+ meta_clutter_backend_native_get_stage_native (clutter_backend);
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
+ MetaRendererView *view = meta_renderer_get_view_for_crtc (renderer, crtc);
+
+ clutter_stage_cogl_add_onscreen_frame_info (CLUTTER_STAGE_COGL (stage_native),
+ CLUTTER_STAGE_VIEW (view));
+}
+
void
-meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
+meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
+ MetaRendererView *view,
+ ClutterFrame *frame)
{
+ MetaRenderer *renderer = META_RENDERER (renderer_native);
+ MetaBackend *backend = meta_renderer_get_backend (renderer);
+ MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+ MetaKms *kms = meta_backend_native_get_kms (backend_native);
+
+ if (!clutter_frame_has_result (frame))
+ {
+ MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
+ MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
+ MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);;
+ MetaKmsUpdateFlag flags;
+ MetaKmsUpdate *kms_update;
+ g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
+ const GError *error;
+
+ kms_update = meta_kms_get_pending_update (kms, kms_device);
+ if (!kms_update)
+ {
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
+ return;
+ }
+
+ meta_kms_update_add_page_flip_listener (kms_update,
+ kms_crtc,
+ &page_flip_listener_vtable,
+ g_object_ref (view));
+
+ flags = META_KMS_UPDATE_FLAG_NONE;
+ kms_feedback = meta_kms_post_pending_update_sync (kms,
+ kms_device,
+ flags);
+ switch (meta_kms_feedback_get_result (kms_feedback))
+ {
+ case META_KMS_FEEDBACK_PASSED:
+ add_onscreen_frame_info (crtc);
+ clutter_frame_set_result (frame,
+ CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
+ break;
+ case META_KMS_FEEDBACK_FAILED:
+ clutter_frame_set_result (frame,
+ CLUTTER_FRAME_RESULT_IDLE);
+
+ error = meta_kms_feedback_get_error (kms_feedback);
+ if (!g_error_matches (error,
+ G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED))
+ g_warning ("Failed to post KMS update: %s", error->message);
+ break;
+ }
+ }
}
static gboolean
diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h
index e48712be83..786bd9d41b 100644
--- a/src/backends/native/meta-renderer-native.h
+++ b/src/backends/native/meta-renderer-native.h
@@ -53,14 +53,14 @@ struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms);
MetaGpuKms * meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native);
-void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native);
+void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
+ MetaRendererView *view,
+ ClutterFrame *frame);
void meta_renderer_native_reset_modes (MetaRendererNative *renderer_native);
gboolean meta_renderer_native_use_modifiers (MetaRendererNative *renderer_native);
-gboolean meta_renderer_native_is_mode_set_pending (MetaRendererNative *renderer_native);
-
gboolean meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
uint32_t drm_format,
uint64_t drm_modifier,
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
index 2a29f93127..3b27c99303 100644
--- a/src/backends/native/meta-stage-native.c
+++ b/src/backends/native/meta-stage-native.c
@@ -27,6 +27,7 @@
#include "backends/native/meta-stage-native.h"
#include "backends/meta-backend-private.h"
+#include "backends/native/meta-cursor-renderer-native.h"
#include "backends/native/meta-renderer-native.h"
#include "meta/meta-backend.h"
#include "meta/meta-monitor-manager.h"
@@ -105,6 +106,21 @@ meta_stage_native_get_views (ClutterStageWindow *stage_window)
return meta_renderer_get_views (renderer);
}
+static void
+meta_stage_native_prepare_frame (ClutterStageWindow *stage_window,
+ ClutterStageView *stage_view,
+ ClutterFrame *frame)
+{
+ MetaBackend *backend = meta_get_backend ();
+ MetaCursorRenderer *cursor_renderer =
+ meta_backend_get_cursor_renderer (backend);
+ MetaCursorRendererNative *cursor_renderer_native =
+ META_CURSOR_RENDERER_NATIVE (cursor_renderer);
+
+ meta_cursor_renderer_native_prepare_frame (cursor_renderer_native,
+ META_RENDERER_VIEW (stage_view));
+}
+
static void
meta_stage_native_finish_frame (ClutterStageWindow *stage_window,
ClutterStageView *stage_view,
@@ -113,10 +129,9 @@ meta_stage_native_finish_frame (ClutterStageWindow *stage_window,
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
- meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer));
-
- if (!clutter_frame_has_result (frame))
- clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
+ meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer),
+ META_RENDERER_VIEW (stage_view),
+ frame);
}
static void
@@ -139,5 +154,6 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
iface->get_geometry = meta_stage_native_get_geometry;
iface->get_views = meta_stage_native_get_views;
+ iface->prepare_frame = meta_stage_native_prepare_frame;
iface->finish_frame = meta_stage_native_finish_frame;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]