diff --git a/display.c b/display.c index 756e081..f0cf52d 100644 --- a/display.c +++ b/display.c @@ -9,134 +9,6 @@ #include "log.h" #include "private.h" -static int guess_plane_zpos_from_type(struct liftoff_display *display, - uint32_t plane_id, uint32_t type) -{ - struct liftoff_plane *primary; - - /* From far to close to the eye: primary, overlay, cursor. Unless - * the overlay ID < primary ID. */ - switch (type) { - case DRM_PLANE_TYPE_PRIMARY: - return 0; - case DRM_PLANE_TYPE_CURSOR: - return 2; - case DRM_PLANE_TYPE_OVERLAY: - if (liftoff_list_empty(&display->planes)) { - return 0; /* No primary plane, shouldn't happen */ - } - primary = liftoff_container_of(display->planes.next, - primary, link); - if (plane_id < primary->id) { - return -1; - } else { - return 1; - } - } - return 0; -} - -static struct liftoff_plane *plane_create(struct liftoff_display *display, - uint32_t id) -{ - struct liftoff_plane *plane, *cur; - drmModePlane *drm_plane; - drmModeObjectProperties *drm_props; - uint32_t i; - drmModePropertyRes *drm_prop; - struct liftoff_plane_property *prop; - uint64_t value; - bool has_type = false, has_zpos = false; - - plane = calloc(1, sizeof(*plane)); - if (plane == NULL) { - return NULL; - } - - drm_plane = drmModeGetPlane(display->drm_fd, id); - if (drm_plane == NULL) { - return NULL; - } - plane->id = drm_plane->plane_id; - plane->possible_crtcs = drm_plane->possible_crtcs; - drmModeFreePlane(drm_plane); - - drm_props = drmModeObjectGetProperties(display->drm_fd, id, - DRM_MODE_OBJECT_PLANE); - if (drm_props == NULL) { - return NULL; - } - plane->props = calloc(drm_props->count_props, - sizeof(struct liftoff_plane_property)); - if (plane->props == NULL) { - drmModeFreeObjectProperties(drm_props); - return NULL; - } - for (i = 0; i < drm_props->count_props; i++) { - drm_prop = drmModeGetProperty(display->drm_fd, - drm_props->props[i]); - if (drm_prop == NULL) { - drmModeFreeObjectProperties(drm_props); - return NULL; - } - prop = &plane->props[i]; - memcpy(prop->name, drm_prop->name, sizeof(prop->name)); - prop->id = drm_prop->prop_id; - drmModeFreeProperty(drm_prop); - plane->props_len++; - - value = drm_props->prop_values[i]; - if (strcmp(prop->name, "type") == 0) { - plane->type = value; - has_type = true; - } else if (strcmp(prop->name, "zpos") == 0) { - plane->zpos = value; - has_zpos = true; - } - } - drmModeFreeObjectProperties(drm_props); - - if (!has_type) { - liftoff_log(LIFTOFF_ERROR, - "plane %"PRIu32" is missing the 'type' property", - plane->id); - free(plane); - return NULL; - } else if (!has_zpos) { - plane->zpos = guess_plane_zpos_from_type(display, plane->id, - plane->type); - } - - /* During plane allocation, we will use the plane list order to fill - * planes with FBs. Primary planes need to be filled first, then planes - * far from the primary planes, then planes closer and closer to the - * primary plane. */ - if (plane->type == DRM_PLANE_TYPE_PRIMARY) { - liftoff_list_insert(&display->planes, &plane->link); - } else { - liftoff_list_for_each(cur, &display->planes, link) { - if (cur->type != DRM_PLANE_TYPE_PRIMARY && - plane->zpos >= cur->zpos) { - liftoff_list_insert(cur->link.prev, &plane->link); - break; - } - } - - if (plane->link.next == NULL) { /* not inserted */ - liftoff_list_insert(display->planes.prev, &plane->link); - } - } - - return plane; -} - -static void plane_destroy(struct liftoff_plane *plane) -{ - liftoff_list_remove(&plane->link); - free(plane->props); - free(plane); -} - struct liftoff_display *liftoff_display_create(int drm_fd) { struct liftoff_display *display; diff --git a/include/private.h b/include/private.h index 287dec2..5b293db 100644 --- a/include/private.h +++ b/include/private.h @@ -70,4 +70,7 @@ struct liftoff_layer_property *layer_get_property(struct liftoff_layer *layer, void layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect); bool layer_intersects(struct liftoff_layer *a, struct liftoff_layer *b); +struct liftoff_plane *plane_create(struct liftoff_display *display, uint32_t id); +void plane_destroy(struct liftoff_plane *plane); + #endif diff --git a/meson.build b/meson.build index 0a42bf7..d6f5fe7 100644 --- a/meson.build +++ b/meson.build @@ -32,6 +32,7 @@ liftoff_lib = library( 'list.c', 'log.c', 'output.c', + 'plane.c', ), include_directories: liftoff_inc, version: meson.project_version(), diff --git a/plane.c b/plane.c new file mode 100644 index 0000000..a445dc5 --- /dev/null +++ b/plane.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include "private.h" + +static int guess_plane_zpos_from_type(struct liftoff_display *display, + uint32_t plane_id, uint32_t type) +{ + struct liftoff_plane *primary; + + /* From far to close to the eye: primary, overlay, cursor. Unless + * the overlay ID < primary ID. */ + switch (type) { + case DRM_PLANE_TYPE_PRIMARY: + return 0; + case DRM_PLANE_TYPE_CURSOR: + return 2; + case DRM_PLANE_TYPE_OVERLAY: + if (liftoff_list_empty(&display->planes)) { + return 0; /* No primary plane, shouldn't happen */ + } + primary = liftoff_container_of(display->planes.next, + primary, link); + if (plane_id < primary->id) { + return -1; + } else { + return 1; + } + } + return 0; +} + +struct liftoff_plane *plane_create(struct liftoff_display *display, uint32_t id) +{ + struct liftoff_plane *plane, *cur; + drmModePlane *drm_plane; + drmModeObjectProperties *drm_props; + uint32_t i; + drmModePropertyRes *drm_prop; + struct liftoff_plane_property *prop; + uint64_t value; + bool has_type = false, has_zpos = false; + + plane = calloc(1, sizeof(*plane)); + if (plane == NULL) { + return NULL; + } + + drm_plane = drmModeGetPlane(display->drm_fd, id); + if (drm_plane == NULL) { + return NULL; + } + plane->id = drm_plane->plane_id; + plane->possible_crtcs = drm_plane->possible_crtcs; + drmModeFreePlane(drm_plane); + + drm_props = drmModeObjectGetProperties(display->drm_fd, id, + DRM_MODE_OBJECT_PLANE); + if (drm_props == NULL) { + return NULL; + } + plane->props = calloc(drm_props->count_props, + sizeof(struct liftoff_plane_property)); + if (plane->props == NULL) { + drmModeFreeObjectProperties(drm_props); + return NULL; + } + for (i = 0; i < drm_props->count_props; i++) { + drm_prop = drmModeGetProperty(display->drm_fd, + drm_props->props[i]); + if (drm_prop == NULL) { + drmModeFreeObjectProperties(drm_props); + return NULL; + } + prop = &plane->props[i]; + memcpy(prop->name, drm_prop->name, sizeof(prop->name)); + prop->id = drm_prop->prop_id; + drmModeFreeProperty(drm_prop); + plane->props_len++; + + value = drm_props->prop_values[i]; + if (strcmp(prop->name, "type") == 0) { + plane->type = value; + has_type = true; + } else if (strcmp(prop->name, "zpos") == 0) { + plane->zpos = value; + has_zpos = true; + } + } + drmModeFreeObjectProperties(drm_props); + + if (!has_type) { + liftoff_log(LIFTOFF_ERROR, + "plane %"PRIu32" is missing the 'type' property", + plane->id); + free(plane); + return NULL; + } else if (!has_zpos) { + plane->zpos = guess_plane_zpos_from_type(display, plane->id, + plane->type); + } + + /* During plane allocation, we will use the plane list order to fill + * planes with FBs. Primary planes need to be filled first, then planes + * far from the primary planes, then planes closer and closer to the + * primary plane. */ + if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + liftoff_list_insert(&display->planes, &plane->link); + } else { + liftoff_list_for_each(cur, &display->planes, link) { + if (cur->type != DRM_PLANE_TYPE_PRIMARY && + plane->zpos >= cur->zpos) { + liftoff_list_insert(cur->link.prev, &plane->link); + break; + } + } + + if (plane->link.next == NULL) { /* not inserted */ + liftoff_list_insert(display->planes.prev, &plane->link); + } + } + + return plane; +} + +void plane_destroy(struct liftoff_plane *plane) +{ + liftoff_list_remove(&plane->link); + free(plane->props); + free(plane); +}