[mutter] cursor-renderer-native: Port to transactional KMS api
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] cursor-renderer-native: Port to transactional KMS api
- Date: Tue, 11 Feb 2020 17:44:38 +0000 (UTC)
commit ae00f5653e55d3c5a8d263494270ac18a04b2595
Author: Jonas Ådahl <jadahl gmail com>
Date: Sat Nov 9 00:19:51 2019 +0100
cursor-renderer-native: Port to transactional KMS api
Turns the cursor setting and movement into cursor plane assignment
primitives. In the current simple implementation, this in turn
translates into legacy drmModeSetCursor() and drmModeMoveCursor() calls.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
src/backends/native/meta-cursor-renderer-native.c | 205 +++++++++++++++-------
1 file changed, 137 insertions(+), 68 deletions(-)
---
diff --git a/src/backends/native/meta-cursor-renderer-native.c
b/src/backends/native/meta-cursor-renderer-native.c
index 687fa9925..2f1996dcc 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -37,6 +37,10 @@
#include "backends/meta-monitor.h"
#include "backends/meta-monitor-manager-private.h"
#include "backends/meta-output.h"
+#include "backends/native/meta-crtc-kms.h"
+#include "backends/native/meta-kms-device.h"
+#include "backends/native/meta-kms-update.h"
+#include "backends/native/meta-kms.h"
#include "backends/native/meta-renderer-native.h"
#include "core/boxes-private.h"
#include "meta/boxes.h"
@@ -211,74 +215,100 @@ set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
static void
set_crtc_cursor (MetaCursorRendererNative *native,
+ MetaKmsUpdate *kms_update,
MetaCrtc *crtc,
+ int x,
+ int y,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
- MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
- MetaGpuKms *gpu_kms;
- int kms_fd;
-
- gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
- cursor_renderer_gpu_data =
+ MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
+ MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
+ MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
- kms_fd = meta_gpu_kms_get_fd (gpu_kms);
+ MetaCursorNativeGpuState *cursor_gpu_state =
+ get_cursor_gpu_state (cursor_priv, gpu_kms);
+ MetaKmsCrtc *kms_crtc;
+ MetaKmsDevice *kms_device;
+ MetaKmsPlane *cursor_plane;
+ struct gbm_bo *bo;
+ union gbm_bo_handle handle;
+ int cursor_width, cursor_height;
+ MetaFixed16Rectangle src_rect;
+ MetaFixed16Rectangle dst_rect;
+ MetaKmsAssignPlaneFlag flags;
+
+ if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
+ bo = get_pending_cursor_sprite_gbm_bo (cursor_gpu_state);
+ else
+ bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state);
+
+ kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
+ kms_device = meta_kms_crtc_get_device (kms_crtc);
+ cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
+ g_return_if_fail (cursor_plane);
+
+ handle = gbm_bo_get_handle (bo);
+
+ cursor_width = cursor_renderer_gpu_data->cursor_width;
+ cursor_height = cursor_renderer_gpu_data->cursor_height;
+ src_rect = (MetaFixed16Rectangle) {
+ .x = meta_fixed_16_from_int (0),
+ .y = meta_fixed_16_from_int (0),
+ .width = meta_fixed_16_from_int (cursor_width),
+ .height = meta_fixed_16_from_int (cursor_height),
+ };
+ dst_rect = (MetaFixed16Rectangle) {
+ .x = meta_fixed_16_from_int (x),
+ .y = meta_fixed_16_from_int (y),
+ .width = meta_fixed_16_from_int (cursor_width),
+ .height = meta_fixed_16_from_int (cursor_height),
+ };
- if (cursor_sprite)
- {
- MetaCursorNativePrivate *cursor_priv;
- MetaCursorNativeGpuState *cursor_gpu_state;
- struct gbm_bo *bo;
- union gbm_bo_handle handle;
- int hot_x, hot_y;
+ flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
+ if (!priv->hw_state_invalidated && bo == crtc->cursor_renderer_private)
+ flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
- cursor_priv = get_cursor_priv (cursor_sprite);
- cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
+ meta_kms_update_assign_plane (kms_update,
+ kms_crtc,
+ cursor_plane,
+ handle.u32,
+ src_rect,
+ dst_rect,
+ flags);
- if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
- bo = get_pending_cursor_sprite_gbm_bo (cursor_gpu_state);
- else
- bo = get_active_cursor_sprite_gbm_bo (cursor_gpu_state);
+ crtc->cursor_renderer_private = bo;
- if (!priv->hw_state_invalidated && bo == crtc->cursor_renderer_private)
- return;
+ if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
+ {
+ cursor_gpu_state->active_bo =
+ (cursor_gpu_state->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
+ cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
+ }
+}
- crtc->cursor_renderer_private = bo;
+static void
+unset_crtc_cursor (MetaCursorRendererNative *native,
+ MetaKmsUpdate *kms_update,
+ MetaCrtc *crtc)
+{
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (native);
+ MetaKmsCrtc *kms_crtc;
+ MetaKmsDevice *kms_device;
+ MetaKmsPlane *cursor_plane;
- handle = gbm_bo_get_handle (bo);
- meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
+ kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
+ kms_device = meta_kms_crtc_get_device (kms_crtc);
+ cursor_plane = meta_kms_device_get_cursor_plane_for (kms_device, kms_crtc);
+ g_return_if_fail (cursor_plane);
- if (drmModeSetCursor2 (kms_fd, crtc->crtc_id, handle.u32,
- cursor_renderer_gpu_data->cursor_width,
- cursor_renderer_gpu_data->cursor_height,
- hot_x, hot_y) < 0)
- {
- if (errno != EACCES)
- {
- g_warning ("drmModeSetCursor2 failed with (%s), "
- "drawing cursor with OpenGL from now on",
- strerror (errno));
- priv->has_hw_cursor = FALSE;
- cursor_renderer_gpu_data->hw_cursor_broken = TRUE;
- }
- }
+ if (!priv->hw_state_invalidated && !crtc->cursor_renderer_private)
+ return;
- if (cursor_gpu_state->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
- {
- cursor_gpu_state->active_bo =
- (cursor_gpu_state->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
- cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
- }
- }
- else
- {
- if (priv->hw_state_invalidated || crtc->cursor_renderer_private != NULL)
- {
- drmModeSetCursor2 (kms_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
- crtc->cursor_renderer_private = NULL;
- }
- }
+ meta_kms_update_unassign_plane (kms_update, kms_crtc, cursor_plane);
+ crtc->cursor_renderer_private = NULL;
}
typedef struct
@@ -287,6 +317,7 @@ typedef struct
MetaLogicalMonitor *in_logical_monitor;
graphene_rect_t in_local_cursor_rect;
MetaCursorSprite *in_cursor_sprite;
+ MetaKmsUpdate *in_kms_update;
gboolean out_painted;
} UpdateCrtcCursorData;
@@ -351,35 +382,47 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
&data->in_local_cursor_rect,
NULL))
{
- MetaGpuKms *gpu_kms;
- int kms_fd;
float crtc_cursor_x, crtc_cursor_y;
- set_crtc_cursor (data->in_cursor_renderer_native,
- crtc,
- data->in_cursor_sprite);
-
- gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor));
- kms_fd = meta_gpu_kms_get_fd (gpu_kms);
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;
- drmModeMoveCursor (kms_fd,
- crtc->crtc_id,
- floorf (crtc_cursor_x),
- floorf (crtc_cursor_y));
+
+ set_crtc_cursor (data->in_cursor_renderer_native,
+ data->in_kms_update,
+ crtc,
+ (int) floorf (crtc_cursor_x),
+ (int) floorf (crtc_cursor_y),
+ data->in_cursor_sprite);
data->out_painted = data->out_painted || TRUE;
}
else
{
- set_crtc_cursor (data->in_cursor_renderer_native, crtc, NULL);
+ unset_crtc_cursor (data->in_cursor_renderer_native,
+ data->in_kms_update,
+ crtc);
}
return TRUE;
}
+static void
+disable_hw_cursor_for_crtc (MetaKmsCrtc *kms_crtc,
+ const GError *error)
+{
+ MetaCrtc *crtc = meta_crtc_kms_from_kms_crtc (kms_crtc);
+ MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
+ MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data =
+ meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
+
+ g_warning ("Failed to set hardware cursor (%s), "
+ "using OpenGL from now on",
+ error->message);
+ cursor_renderer_gpu_data->hw_cursor_broken = TRUE;
+}
+
static void
update_hw_cursor (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite)
@@ -388,12 +431,18 @@ update_hw_cursor (MetaCursorRendererNative *native,
meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaBackend *backend = priv->backend;
+ MetaBackendNative *backend_native = META_BACKEND_NATIVE (priv->backend);
+ MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
+ MetaKmsUpdate *kms_update;
GList *logical_monitors;
GList *l;
graphene_rect_t rect;
gboolean painted = FALSE;
+ g_autoptr (MetaKmsFeedback) feedback = NULL;
+
+ kms_update = meta_kms_ensure_pending_update (kms);
if (cursor_sprite)
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
@@ -419,7 +468,8 @@ update_hw_cursor (MetaCursorRendererNative *native,
},
.size = rect.size
},
- .in_cursor_sprite = cursor_sprite
+ .in_cursor_sprite = cursor_sprite,
+ .in_kms_update = kms_update,
};
monitors = meta_logical_monitor_get_monitors (logical_monitor);
@@ -438,6 +488,25 @@ update_hw_cursor (MetaCursorRendererNative *native,
painted = painted || data.out_painted;
}
+ feedback = meta_kms_post_pending_update_sync (kms);
+ if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
+ {
+ for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next)
+ {
+ MetaKmsPlaneFeedback *plane_feedback = l->data;
+
+ if (!g_error_matches (plane_feedback->error,
+ G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED))
+ {
+ disable_hw_cursor_for_crtc (plane_feedback->crtc,
+ plane_feedback->error);
+ }
+ }
+
+ priv->has_hw_cursor = FALSE;
+ }
+
priv->hw_state_invalidated = FALSE;
if (painted)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]