diff --git a/display.c b/display.c index f0cf52d..8eaa817 100644 --- a/display.c +++ b/display.c @@ -9,6 +9,26 @@ #include "log.h" #include "private.h" +ssize_t basic_property_index(const char *name) +{ + if (strcmp(name, "FB_ID") == 0) { + return LIFTOFF_PROP_FB_ID; + } else if (strcmp(name, "CRTC_ID") == 0) { + return LIFTOFF_PROP_CRTC_ID; + } else if (strcmp(name, "CRTC_X") == 0) { + return LIFTOFF_PROP_CRTC_X; + } else if (strcmp(name, "CRTC_Y") == 0) { + return LIFTOFF_PROP_CRTC_Y; + } else if (strcmp(name, "CRTC_W") == 0) { + return LIFTOFF_PROP_CRTC_W; + } else if (strcmp(name, "CRTC_H") == 0) { + return LIFTOFF_PROP_CRTC_H; + } else if (strcmp(name, "zpos") == 0) { + return LIFTOFF_PROP_ZPOS; + } + return -1; +} + struct liftoff_display *liftoff_display_create(int drm_fd) { struct liftoff_display *display; @@ -279,7 +299,7 @@ static void plane_step_init_next(struct alloc_step *step, zpos_prop = NULL; if (layer != NULL) { - zpos_prop = layer_get_property(layer, "zpos"); + zpos_prop = layer_get_property(layer, LIFTOFF_PROP_ZPOS); } if (zpos_prop != NULL && plane->type != DRM_PLANE_TYPE_PRIMARY) { step->last_layer_zpos = zpos_prop->value; @@ -310,7 +330,7 @@ static bool has_composited_layer_over(struct liftoff_output *output, struct liftoff_layer *other_layer; struct liftoff_layer_property *zpos_prop, *other_zpos_prop; - zpos_prop = layer_get_property(layer, "zpos"); + zpos_prop = layer_get_property(layer, LIFTOFF_PROP_ZPOS); if (zpos_prop == NULL) { return false; } @@ -320,7 +340,8 @@ static bool has_composited_layer_over(struct liftoff_output *output, continue; } - other_zpos_prop = layer_get_property(other_layer, "zpos"); + other_zpos_prop = layer_get_property(other_layer, + LIFTOFF_PROP_ZPOS); if (other_zpos_prop == NULL) { continue; } @@ -343,7 +364,7 @@ static bool has_allocated_layer_over(struct liftoff_output *output, struct liftoff_layer *other_layer; struct liftoff_layer_property *zpos_prop, *other_zpos_prop; - zpos_prop = layer_get_property(layer, "zpos"); + zpos_prop = layer_get_property(layer, LIFTOFF_PROP_ZPOS); if (zpos_prop == NULL) { return false; } @@ -363,7 +384,8 @@ static bool has_allocated_layer_over(struct liftoff_output *output, continue; } - other_zpos_prop = layer_get_property(other_layer, "zpos"); + other_zpos_prop = layer_get_property(other_layer, + LIFTOFF_PROP_ZPOS); if (other_zpos_prop == NULL) { continue; } @@ -493,7 +515,7 @@ bool output_choose_layers(struct liftoff_output *output, continue; } - zpos_prop = layer_get_property(layer, "zpos"); + zpos_prop = layer_get_property(layer, LIFTOFF_PROP_ZPOS); if (zpos_prop != NULL) { if ((int)zpos_prop->value > step->last_layer_zpos && has_allocated_layer_over(output, step, layer)) { diff --git a/include/private.h b/include/private.h index 5b293db..0c8b1e2 100644 --- a/include/private.h +++ b/include/private.h @@ -2,9 +2,21 @@ #define PRIVATE_H #include +#include #include "list.h" #include "log.h" +enum liftoff_basic_property { + LIFTOFF_PROP_FB_ID, + LIFTOFF_PROP_CRTC_ID, + LIFTOFF_PROP_CRTC_X, + LIFTOFF_PROP_CRTC_Y, + LIFTOFF_PROP_CRTC_W, + LIFTOFF_PROP_CRTC_H, + LIFTOFF_PROP_ZPOS, + LIFTOFF_PROP_LAST, /* keep last */ +}; + struct liftoff_display { int drm_fd; @@ -32,6 +44,7 @@ struct liftoff_layer { struct liftoff_layer_property *props; size_t props_len; + struct liftoff_layer_property *basic_props[LIFTOFF_PROP_LAST]; struct liftoff_plane *plane; }; @@ -51,6 +64,7 @@ struct liftoff_plane { struct liftoff_plane_property *props; size_t props_len; + struct liftoff_plane_property *basic_props[LIFTOFF_PROP_LAST]; struct liftoff_layer *layer; }; @@ -65,8 +79,10 @@ struct liftoff_rect { int width, height; }; +ssize_t basic_property_index(const char *name); + struct liftoff_layer_property *layer_get_property(struct liftoff_layer *layer, - const char *name); + enum liftoff_basic_property prop); void layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect); bool layer_intersects(struct liftoff_layer *a, struct liftoff_layer *b); diff --git a/layer.c b/layer.c index 0a4da9d..eb31b9c 100644 --- a/layer.c +++ b/layer.c @@ -27,16 +27,23 @@ void liftoff_layer_destroy(struct liftoff_layer *layer) } struct liftoff_layer_property *layer_get_property(struct liftoff_layer *layer, - const char *name) + enum liftoff_basic_property prop) +{ + return layer->basic_props[prop]; +} + +static void layer_invalidate_basic_props(struct liftoff_layer *layer) { size_t i; + ssize_t basic_prop_idx; + memset(layer->basic_props, 0, sizeof(layer->basic_props)); for (i = 0; i < layer->props_len; i++) { - if (strcmp(layer->props[i].name, name) == 0) { - return &layer->props[i]; + basic_prop_idx = basic_property_index(layer->props[i].name); + if (basic_prop_idx >= 0) { + layer->basic_props[basic_prop_idx] = &layer->props[i]; } } - return NULL; } void liftoff_layer_set_property(struct liftoff_layer *layer, const char *name, @@ -44,6 +51,8 @@ void liftoff_layer_set_property(struct liftoff_layer *layer, const char *name, { struct liftoff_layer_property *props; struct liftoff_layer_property *prop; + ssize_t basic_prop_idx; + size_t i; /* TODO: better error handling */ if (strcmp(name, "CRTC_ID") == 0) { @@ -52,7 +61,19 @@ void liftoff_layer_set_property(struct liftoff_layer *layer, const char *name, return; } - prop = layer_get_property(layer, name); + basic_prop_idx = basic_property_index(name); + if (basic_prop_idx >= 0) { + prop = layer_get_property(layer, basic_prop_idx); + } else { + prop = NULL; + for (i = 0; i < layer->props_len; i++) { + if (strcmp(layer->props[i].name, name) == 0) { + prop = &layer->props[i]; + break; + } + } + } + if (prop == NULL) { props = realloc(layer->props, (layer->props_len + 1) * sizeof(struct liftoff_layer_property)); @@ -60,12 +81,21 @@ void liftoff_layer_set_property(struct liftoff_layer *layer, const char *name, perror("realloc"); return; } - layer->props = props; - layer->props_len++; + if (layer->props != props) { + layer->props = props; + layer_invalidate_basic_props(layer); + } else { + layer->props = props; + } - prop = &layer->props[layer->props_len - 1]; + prop = &layer->props[layer->props_len]; memset(prop, 0, sizeof(*prop)); strncpy(prop->name, name, sizeof(prop->name) - 1); + layer->props_len++; + + if (basic_prop_idx >= 0) { + layer->basic_props[basic_prop_idx] = prop; + } } prop->value = value; @@ -83,10 +113,10 @@ void layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect) { struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop; - x_prop = layer_get_property(layer, "CRTC_X"); - y_prop = layer_get_property(layer, "CRTC_Y"); - w_prop = layer_get_property(layer, "CRTC_W"); - h_prop = layer_get_property(layer, "CRTC_H"); + x_prop = layer_get_property(layer, LIFTOFF_PROP_CRTC_X); + y_prop = layer_get_property(layer, LIFTOFF_PROP_CRTC_Y); + w_prop = layer_get_property(layer, LIFTOFF_PROP_CRTC_W); + h_prop = layer_get_property(layer, LIFTOFF_PROP_CRTC_H); rect->x = x_prop != NULL ? x_prop->value : 0; rect->y = y_prop != NULL ? y_prop->value : 0; diff --git a/plane.c b/plane.c index a445dc5..ab659a4 100644 --- a/plane.c +++ b/plane.c @@ -39,6 +39,7 @@ struct liftoff_plane *plane_create(struct liftoff_display *display, uint32_t id) drmModePropertyRes *drm_prop; struct liftoff_plane_property *prop; uint64_t value; + ssize_t basic_prop_idx; bool has_type = false, has_zpos = false; plane = calloc(1, sizeof(*plane)); @@ -78,6 +79,11 @@ struct liftoff_plane *plane_create(struct liftoff_display *display, uint32_t id) drmModeFreeProperty(drm_prop); plane->props_len++; + basic_prop_idx = basic_property_index(prop->name); + if (basic_prop_idx >= 0) { + plane->basic_props[basic_prop_idx] = prop; + } + value = drm_props->prop_values[i]; if (strcmp(prop->name, "type") == 0) { plane->type = value;