diff --git a/alloc.c b/alloc.c index 28ae8ee..578ef25 100644 --- a/alloc.c +++ b/alloc.c @@ -119,7 +119,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; @@ -150,7 +150,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; } @@ -160,7 +160,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; } @@ -183,7 +184,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; } @@ -203,7 +204,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; } @@ -265,7 +267,7 @@ bool check_layer_plane_compatible(struct alloc_step *step, return false; } - 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/display.c b/display.c index 3b20d7f..57a6091 100644 --- a/display.c +++ b/display.c @@ -4,6 +4,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; diff --git a/include/private.h b/include/private.h index 481e0ae..c74d29c 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; }; @@ -52,6 +65,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; }; @@ -66,8 +80,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); void layer_mark_clean(struct liftoff_layer *layer); diff --git a/layer.c b/layer.c index 8460afa..452a26d 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, liftoff_log_errno(LIFTOFF_ERROR, "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->changed = true; } else { @@ -87,10 +117,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 00d52e8..081a449 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)); @@ -83,6 +84,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;