From ec27271492cc3ad86db31436f5aa38032f99a16f Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 5 Jun 2014 11:22:25 +0300 Subject: [PATCH] compositor-drm: Refactor sprite create/destroy into helpers This moves the single sprite creation code from create_sprites() into a new function. The readability clean-up is small, but my intention is to write an alternate version of create_sprites(), and sharing the single sprite creation code is useful. The removal code now actually removes the plane from the list. In doing this, the gymnastics required to exact the CRTC ID the plane was last on when making a disabling drmModeSetPlane call have been removed; specifying the CRTC is not necessary when disabling a plane. (The atomic API goes a step further, mandating it be zero.) [daniels: Genericised from drm_sprite to drm_plane, moving some of the logic back into create_sprites(), also symmetrical drm_plane_destroy.] Signed-off-by: Daniel Stone Reviewed-by: Pekka Paalanen Reviewed-by: Emre Ucan --- libweston/compositor-drm.c | 188 +++++++++++++++++++++++-------------- 1 file changed, 117 insertions(+), 71 deletions(-) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 8e1e788f..decd586f 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -1826,6 +1826,123 @@ init_pixman(struct drm_backend *b) return pixman_renderer_init(b->compositor); } +/** + * Create a drm_plane for a hardware plane + * + * Creates one drm_plane structure for a hardware plane, and initialises its + * properties and formats. + * + * This function does not add the plane to the list of usable planes in Weston + * itself; the caller is responsible for this. + * + * Call drm_plane_destroy to clean up the plane. + * + * @param b DRM compositor backend + * @param kplane DRM plane to create + */ +static struct drm_plane * +drm_plane_create(struct drm_backend *b, const drmModePlane *kplane) +{ + struct drm_plane *plane; + + plane = zalloc(sizeof(*plane) + ((sizeof(uint32_t)) * + kplane->count_formats)); + if (!plane) { + weston_log("%s: out of memory\n", __func__); + return NULL; + } + + plane->backend = b; + plane->possible_crtcs = kplane->possible_crtcs; + plane->plane_id = kplane->plane_id; + plane->count_formats = kplane->count_formats; + memcpy(plane->formats, kplane->formats, + kplane->count_formats * sizeof(kplane->formats[0])); + + weston_plane_init(&plane->base, b->compositor, 0, 0); + wl_list_insert(&b->sprite_list, &plane->link); + + return plane; +} + +/** + * Destroy one DRM plane + * + * Destroy a DRM plane, removing it from screen and releasing its retained + * buffers in the process. The counterpart to drm_plane_create. + * + * @param plane Plane to deallocate (will be freed) + */ +static void +drm_plane_destroy(struct drm_plane *plane) +{ + drmModeSetPlane(plane->backend->drm.fd, plane->plane_id, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0); + assert(!plane->fb_last); + assert(!plane->fb_pending); + drm_fb_unref(plane->fb_current); + weston_plane_release(&plane->base); + wl_list_remove(&plane->link); + free(plane); +} + +/** + * Initialise sprites (overlay planes) + * + * Walk the list of provided DRM planes, and add overlay planes. + * + * Call destroy_sprites to free these planes. + * + * @param b DRM compositor backend + */ +static void +create_sprites(struct drm_backend *b) +{ + drmModePlaneRes *kplane_res; + drmModePlane *kplane; + struct drm_plane *drm_plane; + uint32_t i; + + kplane_res = drmModeGetPlaneResources(b->drm.fd); + if (!kplane_res) { + weston_log("failed to get plane resources: %s\n", + strerror(errno)); + return; + } + + for (i = 0; i < kplane_res->count_planes; i++) { + kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]); + if (!kplane) + continue; + + drm_plane = drm_plane_create(b, kplane); + drmModeFreePlane(kplane); + if (!drm_plane) + continue; + + weston_compositor_stack_plane(b->compositor, &drm_plane->base, + &b->compositor->primary_plane); + } + + drmModeFreePlaneResources(kplane_res); +} + +/** + * Clean up sprites (overlay planes) + * + * The counterpart to create_sprites. + * + * @param b DRM compositor backend + */ +static void +destroy_sprites(struct drm_backend *b) +{ + struct drm_plane *plane, *next; + + wl_list_for_each_safe(plane, next, &b->sprite_list, link) + drm_plane_destroy(plane); +} + /** * Add a mode to output's mode list * @@ -2862,77 +2979,6 @@ err: return -1; } -static void -create_sprites(struct drm_backend *b) -{ - struct drm_plane *plane; - drmModePlaneRes *kplane_res; - drmModePlane *kplane; - uint32_t i; - - kplane_res = drmModeGetPlaneResources(b->drm.fd); - if (!kplane_res) { - weston_log("failed to get plane resources: %s\n", - strerror(errno)); - return; - } - - for (i = 0; i < kplane_res->count_planes; i++) { - kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]); - if (!kplane) - continue; - - plane = zalloc(sizeof(*plane) + ((sizeof(uint32_t)) * - kplane->count_formats)); - if (!plane) { - weston_log("%s: out of memory\n", - __func__); - drmModeFreePlane(kplane); - continue; - } - - plane->possible_crtcs = kplane->possible_crtcs; - plane->plane_id = kplane->plane_id; - plane->fb_last = NULL; - plane->fb_current = NULL; - plane->fb_pending = NULL; - plane->backend = b; - plane->count_formats = kplane->count_formats; - memcpy(plane->formats, kplane->formats, - kplane->count_formats * sizeof(kplane->formats[0])); - drmModeFreePlane(kplane); - weston_plane_init(&plane->base, b->compositor, 0, 0); - weston_compositor_stack_plane(b->compositor, &plane->base, - &b->compositor->primary_plane); - - wl_list_insert(&b->sprite_list, &plane->link); - } - - drmModeFreePlaneResources(kplane_res); -} - -static void -destroy_sprites(struct drm_backend *backend) -{ - struct drm_plane *plane, *next; - struct drm_output *output; - - output = container_of(backend->compositor->output_list.next, - struct drm_output, base.link); - - wl_list_for_each_safe(plane, next, &backend->sprite_list, link) { - drmModeSetPlane(backend->drm.fd, - plane->plane_id, - output->crtc_id, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0); - assert(!plane->fb_last); - assert(!plane->fb_pending); - drm_fb_unref(plane->fb_current); - weston_plane_release(&plane->base); - free(plane); - } -} - static int create_outputs(struct drm_backend *b, struct udev_device *drm_device) {