Change the type of cursor_plane from a weston_plane (base tracking
structure) to a drm_plane (wrapper containing additional DRM-specific
details), and make it a dynamically-allocated pointer.

Using the standard drm_plane allows us to reuse code which already deals
with drm_planes, e.g. a common cleanup function.

v2: Add legacy cursor_planes to plane_list so they get cleaned up
    properly.

Signed-off-by: Daniel Stone <dani...@collabora.com>
---
 src/compositor-drm.c | 90 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 75 insertions(+), 15 deletions(-)

diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index d0d419f..c9071d2 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -262,7 +262,7 @@ struct drm_output {
 
        struct gbm_surface *surface;
        struct gbm_bo *cursor_bo[2];
-       struct weston_plane cursor_plane;
+       struct drm_plane *cursor_plane;
        struct weston_plane fb_plane;
        struct weston_view *cursor_view;
        int current_cursor;
@@ -1038,7 +1038,8 @@ drm_output_repaint(struct weston_output *output_base,
 
        output->page_flip_pending = 1;
 
-       drm_output_set_cursor(output);
+       if (output->cursor_plane)
+               drm_output_set_cursor(output);
 
        /*
         * Now, update all the sprite surfaces
@@ -1402,6 +1403,8 @@ drm_output_prepare_cursor_view(struct drm_output *output,
 
        if (c->gbm == NULL)
                return NULL;
+       if (output->cursor_plane == NULL)
+               return NULL;
        if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
                return NULL;
        if (viewport->buffer.scale != output->base.current_scale)
@@ -1422,7 +1425,7 @@ drm_output_prepare_cursor_view(struct drm_output *output,
 
        output->cursor_view = ev;
 
-       return &output->cursor_plane;
+       return &output->cursor_plane->base;
 }
 
 static void
@@ -1466,6 +1469,8 @@ drm_output_set_cursor(struct drm_output *output)
        struct gbm_bo *bo;
        int x, y;
 
+       assert(output->cursor_plane);
+
        output->cursor_view = NULL;
        if (ev == NULL) {
                drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
@@ -1475,9 +1480,9 @@ drm_output_set_cursor(struct drm_output *output)
        buffer = ev->surface->buffer_ref.buffer;
 
        if (buffer &&
-           pixman_region32_not_empty(&output->cursor_plane.damage)) {
-               pixman_region32_fini(&output->cursor_plane.damage);
-               pixman_region32_init(&output->cursor_plane.damage);
+           pixman_region32_not_empty(&output->cursor_plane->base.damage)) {
+               pixman_region32_fini(&output->cursor_plane->base.damage);
+               pixman_region32_init(&output->cursor_plane->base.damage);
                output->current_cursor ^= 1;
                bo = output->cursor_bo[output->current_cursor];
 
@@ -1492,14 +1497,15 @@ drm_output_set_cursor(struct drm_output *output)
 
        x = (ev->geometry.x - output->base.x) * output->base.current_scale;
        y = (ev->geometry.y - output->base.y) * output->base.current_scale;
-       if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
+       if (output->cursor_plane->base.x != x ||
+           output->cursor_plane->base.y != y) {
                if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
                        weston_log("failed to move cursor: %m\n");
                        c->cursors_are_broken = 1;
                }
 
-               output->cursor_plane.x = x;
-               output->cursor_plane.y = y;
+               output->cursor_plane->base.x = x;
+               output->cursor_plane->base.y = y;
        }
 }
 
@@ -1571,7 +1577,8 @@ drm_assign_planes(struct weston_output *output_base)
                                              &ev->transform.boundingbox);
 
                if (next_plane == primary ||
-                   next_plane == &output->cursor_plane) {
+                   (output->cursor_plane &&
+                    next_plane == &output->cursor_plane->base)) {
                        /* cursor plane involves a copy */
                        ev->psf_flags = 0;
                } else {
@@ -1628,7 +1635,6 @@ drm_output_destroy(struct weston_output *output_base)
        }
 
        weston_plane_release(&output->fb_plane);
-       weston_plane_release(&output->cursor_plane);
 
        weston_output_destroy(&output->base);
 
@@ -2565,6 +2571,59 @@ connector_get_current_mode(drmModeConnector *connector, 
int drm_fd,
        return 0;
 }
 
+static void
+drm_output_init_cursor(struct drm_output *output)
+{
+       struct drm_compositor *ec =
+               (struct drm_compositor *) output->base.compositor;
+       struct drm_plane *plane;
+
+       if (ec->universal_planes) {
+               wl_list_for_each(plane, &ec->plane_list, link) {
+                       if (plane->type != WDRM_PLANE_TYPE_CURSOR)
+                               continue;
+                       if (plane->output)
+                               continue;
+                       if (!drm_plane_crtc_supported(output,
+                                                     plane->possible_crtcs))
+                               continue;
+
+                       plane->output = output;
+                       output->cursor_plane = plane;
+                       break;
+               }
+       }
+       else {
+               /* XXX: Gross open-coding ... ? */
+               plane = zalloc(sizeof(*plane) + sizeof(uint32_t));
+               if (!plane) {
+                       weston_log("%s: out of memory\n", __func__);
+                       return;
+               }
+
+               weston_plane_init(&plane->base, &ec->base, 0, 0);
+               wl_list_insert(&ec->plane_list, &plane->link);
+
+               plane->plane_id = 0;
+               plane->possible_crtcs = 0;
+               plane->output = output;
+               plane->current = NULL;
+               plane->next = NULL;
+               plane->compositor = ec;
+               plane->count_formats = 1;
+               plane->formats[0] = GBM_FORMAT_ARGB8888;
+               plane->type = WDRM_PLANE_TYPE_CURSOR;
+
+               output->cursor_plane = plane;
+       }
+
+       if (!output->cursor_plane)
+               return;
+
+       weston_compositor_stack_plane(&ec->base, &output->cursor_plane->base,
+                                     NULL);
+}
+
 static int
 create_output_for_connector(struct drm_compositor *ec,
                            drmModeRes *resources,
@@ -2672,6 +2731,8 @@ create_output_for_connector(struct drm_compositor *ec,
                           connector->mmWidth, connector->mmHeight,
                           transform, scale);
 
+       drm_output_init_cursor(output);
+
        if (ec->use_pixman) {
                if (drm_output_init_pixman(output, ec) < 0) {
                        weston_log("Failed to init output pixman state\n");
@@ -2709,10 +2770,7 @@ create_output_for_connector(struct drm_compositor *ec,
        output->base.gamma_size = output->original_crtc->gamma_size;
        output->base.set_gamma = drm_output_set_gamma;
 
-       weston_plane_init(&output->cursor_plane, &ec->base, 0, 0);
        weston_plane_init(&output->fb_plane, &ec->base, 0, 0);
-
-       weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
        weston_compositor_stack_plane(&ec->base, &output->fb_plane,
                                      &ec->base.primary_plane);
 
@@ -3142,7 +3200,9 @@ session_notify(struct wl_listener *listener, void *data)
 
                wl_list_for_each(output, &ec->base.output_list, base.link) {
                        output->base.repaint_needed = 0;
-                       drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
+                       if (output->cursor_plane)
+                               drmModeSetCursor(ec->drm.fd, output->crtc_id,
+                                                0, 0, 0);
                }
 
                output = container_of(ec->base.output_list.next,
-- 
2.4.3

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to