mirror of
https://gitlab.freedesktop.org/emersion/libliftoff.git
synced 2024-11-16 19:47:55 +01:00
Introduce core properties
This is a set of well-known KMS standard properties, either used by libliftoff itself or commonly used by compositors. Adding special cases for these allows us to access them without having to iterate over a list. This roughly improves performance by ~50% when leaving out the atomic test-only commits. Closes: https://gitlab.freedesktop.org/emersion/libliftoff/-/issues/1
This commit is contained in:
parent
17a558d3e0
commit
b5b921ea85
5 changed files with 152 additions and 38 deletions
22
alloc.c
22
alloc.c
|
@ -154,7 +154,7 @@ plane_step_init_next(struct alloc_step *step, struct alloc_step *prev,
|
||||||
|
|
||||||
zpos_prop = NULL;
|
zpos_prop = NULL;
|
||||||
if (layer != NULL) {
|
if (layer != NULL) {
|
||||||
zpos_prop = layer_get_property(layer, "zpos");
|
zpos_prop = layer_get_core_property(layer, LIFTOFF_PROP_ZPOS);
|
||||||
}
|
}
|
||||||
if (zpos_prop != NULL && plane->type != DRM_PLANE_TYPE_PRIMARY) {
|
if (zpos_prop != NULL && plane->type != DRM_PLANE_TYPE_PRIMARY) {
|
||||||
step->last_layer_zpos = zpos_prop->value;
|
step->last_layer_zpos = zpos_prop->value;
|
||||||
|
@ -204,7 +204,7 @@ has_composited_layer_over(struct liftoff_output *output,
|
||||||
struct liftoff_layer *other_layer;
|
struct liftoff_layer *other_layer;
|
||||||
struct liftoff_layer_property *zpos_prop, *other_zpos_prop;
|
struct liftoff_layer_property *zpos_prop, *other_zpos_prop;
|
||||||
|
|
||||||
zpos_prop = layer_get_property(layer, "zpos");
|
zpos_prop = layer_get_core_property(layer, LIFTOFF_PROP_ZPOS);
|
||||||
if (zpos_prop == NULL) {
|
if (zpos_prop == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,8 @@ has_composited_layer_over(struct liftoff_output *output,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
other_zpos_prop = layer_get_property(other_layer, "zpos");
|
other_zpos_prop = layer_get_core_property(other_layer,
|
||||||
|
LIFTOFF_PROP_ZPOS);
|
||||||
if (other_zpos_prop == NULL) {
|
if (other_zpos_prop == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +238,7 @@ has_allocated_layer_over(struct liftoff_output *output, struct alloc_step *step,
|
||||||
struct liftoff_layer *other_layer;
|
struct liftoff_layer *other_layer;
|
||||||
struct liftoff_layer_property *zpos_prop, *other_zpos_prop;
|
struct liftoff_layer_property *zpos_prop, *other_zpos_prop;
|
||||||
|
|
||||||
zpos_prop = layer_get_property(layer, "zpos");
|
zpos_prop = layer_get_core_property(layer, LIFTOFF_PROP_ZPOS);
|
||||||
if (zpos_prop == NULL) {
|
if (zpos_prop == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -257,7 +258,8 @@ has_allocated_layer_over(struct liftoff_output *output, struct alloc_step *step,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
other_zpos_prop = layer_get_property(other_layer, "zpos");
|
other_zpos_prop = layer_get_core_property(other_layer,
|
||||||
|
LIFTOFF_PROP_ZPOS);
|
||||||
if (other_zpos_prop == NULL) {
|
if (other_zpos_prop == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +322,7 @@ check_layer_plane_compatible(struct alloc_step *step,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
zpos_prop = layer_get_property(layer, "zpos");
|
zpos_prop = layer_get_core_property(layer, LIFTOFF_PROP_ZPOS);
|
||||||
if (zpos_prop != NULL) {
|
if (zpos_prop != NULL) {
|
||||||
if ((int)zpos_prop->value > step->last_layer_zpos &&
|
if ((int)zpos_prop->value > step->last_layer_zpos &&
|
||||||
has_allocated_layer_over(output, step, layer)) {
|
has_allocated_layer_over(output, step, layer)) {
|
||||||
|
@ -644,7 +646,7 @@ layer_needs_realloc(struct liftoff_layer *layer, struct liftoff_output *output)
|
||||||
* If FB_ID changes from non-zero to non-zero and the FB
|
* If FB_ID changes from non-zero to non-zero and the FB
|
||||||
* attributes didn't change, we can try to re-use the previous
|
* attributes didn't change, we can try to re-use the previous
|
||||||
* allocation. */
|
* allocation. */
|
||||||
if (strcmp(prop->name, "FB_ID") == 0) {
|
if (prop->core_index == LIFTOFF_PROP_FB_ID) {
|
||||||
if (prop->value == 0 && prop->prev_value == 0) {
|
if (prop->value == 0 && prop->prev_value == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -674,7 +676,7 @@ layer_needs_realloc(struct liftoff_layer *layer, struct liftoff_output *output)
|
||||||
/* If the layer was or becomes completely transparent or
|
/* If the layer was or becomes completely transparent or
|
||||||
* completely opaque, we might be able to find a better
|
* completely opaque, we might be able to find a better
|
||||||
* allocation. Otherwise, we can keep the current one. */
|
* allocation. Otherwise, we can keep the current one. */
|
||||||
if (strcmp(prop->name, "alpha") == 0) {
|
if (prop->core_index == LIFTOFF_PROP_ALPHA) {
|
||||||
if (prop->value == 0 || prop->prev_value == 0 ||
|
if (prop->value == 0 || prop->prev_value == 0 ||
|
||||||
prop->value == 0xFFFF || prop->prev_value == 0xFFFF) {
|
prop->value == 0xFFFF || prop->prev_value == 0xFFFF) {
|
||||||
liftoff_log(LIFTOFF_DEBUG, "Cannot re-use previous allocation: "
|
liftoff_log(LIFTOFF_DEBUG, "Cannot re-use previous allocation: "
|
||||||
|
@ -750,8 +752,8 @@ layer_is_higher_priority(struct liftoff_layer *this, struct liftoff_layer *other
|
||||||
// overall priority, since the top layer needs to be offloaded in order
|
// overall priority, since the top layer needs to be offloaded in order
|
||||||
// to offload the bottom layer.
|
// to offload the bottom layer.
|
||||||
|
|
||||||
this_zpos = layer_get_property(this, "zpos");
|
this_zpos = layer_get_core_property(this, LIFTOFF_PROP_ZPOS);
|
||||||
other_zpos = layer_get_property(other, "zpos");
|
other_zpos = layer_get_core_property(other, LIFTOFF_PROP_ZPOS);
|
||||||
intersects = layer_intersects(this, other);
|
intersects = layer_intersects(this, other);
|
||||||
|
|
||||||
if (this_zpos != NULL && other_zpos != NULL) {
|
if (this_zpos != NULL && other_zpos != NULL) {
|
||||||
|
|
33
device.c
33
device.c
|
@ -122,3 +122,36 @@ device_test_commit(struct liftoff_device *device, drmModeAtomicReq *req,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
core_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, "SRC_X") == 0) {
|
||||||
|
return LIFTOFF_PROP_SRC_X;
|
||||||
|
} else if (strcmp(name, "SRC_Y") == 0) {
|
||||||
|
return LIFTOFF_PROP_SRC_Y;
|
||||||
|
} else if (strcmp(name, "SRC_W") == 0) {
|
||||||
|
return LIFTOFF_PROP_SRC_W;
|
||||||
|
} else if (strcmp(name, "SRC_H") == 0) {
|
||||||
|
return LIFTOFF_PROP_SRC_H;
|
||||||
|
} else if (strcmp(name, "zpos") == 0) {
|
||||||
|
return LIFTOFF_PROP_ZPOS;
|
||||||
|
} else if (strcmp(name, "alpha") == 0) {
|
||||||
|
return LIFTOFF_PROP_ALPHA;
|
||||||
|
} else if (strcmp(name, "rotation") == 0) {
|
||||||
|
return LIFTOFF_PROP_ROTATION;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define PRIVATE_H
|
#define PRIVATE_H
|
||||||
|
|
||||||
#include <libliftoff.h>
|
#include <libliftoff.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
@ -9,6 +10,28 @@
|
||||||
* given number of page-flips */
|
* given number of page-flips */
|
||||||
#define LIFTOFF_PRIORITY_PERIOD 60
|
#define LIFTOFF_PRIORITY_PERIOD 60
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of well-known KMS properties.
|
||||||
|
*
|
||||||
|
* Keep core_property_index() in sync.
|
||||||
|
*/
|
||||||
|
enum liftoff_core_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_SRC_X,
|
||||||
|
LIFTOFF_PROP_SRC_Y,
|
||||||
|
LIFTOFF_PROP_SRC_W,
|
||||||
|
LIFTOFF_PROP_SRC_H,
|
||||||
|
LIFTOFF_PROP_ZPOS,
|
||||||
|
LIFTOFF_PROP_ALPHA,
|
||||||
|
LIFTOFF_PROP_ROTATION,
|
||||||
|
LIFTOFF_PROP_LAST, /* keep last */
|
||||||
|
};
|
||||||
|
|
||||||
struct liftoff_device {
|
struct liftoff_device {
|
||||||
int drm_fd;
|
int drm_fd;
|
||||||
|
|
||||||
|
@ -45,6 +68,7 @@ struct liftoff_layer {
|
||||||
|
|
||||||
struct liftoff_layer_property *props;
|
struct liftoff_layer_property *props;
|
||||||
size_t props_len;
|
size_t props_len;
|
||||||
|
ssize_t core_props[LIFTOFF_PROP_LAST]; /* indices into the props array */
|
||||||
|
|
||||||
bool force_composition; /* FB needs to be composited */
|
bool force_composition; /* FB needs to be composited */
|
||||||
|
|
||||||
|
@ -62,6 +86,7 @@ struct liftoff_layer {
|
||||||
struct liftoff_layer_property {
|
struct liftoff_layer_property {
|
||||||
char name[DRM_PROP_NAME_LEN];
|
char name[DRM_PROP_NAME_LEN];
|
||||||
uint64_t value, prev_value;
|
uint64_t value, prev_value;
|
||||||
|
ssize_t core_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct liftoff_plane {
|
struct liftoff_plane {
|
||||||
|
@ -74,6 +99,7 @@ struct liftoff_plane {
|
||||||
drmModePropertyRes **props;
|
drmModePropertyRes **props;
|
||||||
size_t props_len;
|
size_t props_len;
|
||||||
drmModePropertyBlobRes *in_formats_blob;
|
drmModePropertyBlobRes *in_formats_blob;
|
||||||
|
const drmModePropertyRes *core_props[LIFTOFF_PROP_LAST];
|
||||||
|
|
||||||
struct liftoff_layer *layer;
|
struct liftoff_layer *layer;
|
||||||
};
|
};
|
||||||
|
@ -90,6 +116,9 @@ device_test_commit(struct liftoff_device *device, drmModeAtomicReq *req,
|
||||||
struct liftoff_layer_property *
|
struct liftoff_layer_property *
|
||||||
layer_get_property(struct liftoff_layer *layer, const char *name);
|
layer_get_property(struct liftoff_layer *layer, const char *name);
|
||||||
|
|
||||||
|
struct liftoff_layer_property *
|
||||||
|
layer_get_core_property(struct liftoff_layer *layer, enum liftoff_core_property prop);
|
||||||
|
|
||||||
void
|
void
|
||||||
layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect);
|
layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect);
|
||||||
|
|
||||||
|
@ -134,4 +163,7 @@ plane_check_layer_fb(struct liftoff_plane *plane, struct liftoff_layer *layer);
|
||||||
void
|
void
|
||||||
output_log_layers(struct liftoff_output *output);
|
output_log_layers(struct liftoff_output *output);
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
core_property_index(const char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
64
layer.c
64
layer.c
|
@ -10,6 +10,7 @@ struct liftoff_layer *
|
||||||
liftoff_layer_create(struct liftoff_output *output)
|
liftoff_layer_create(struct liftoff_output *output)
|
||||||
{
|
{
|
||||||
struct liftoff_layer *layer;
|
struct liftoff_layer *layer;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
layer = calloc(1, sizeof(*layer));
|
layer = calloc(1, sizeof(*layer));
|
||||||
if (layer == NULL) {
|
if (layer == NULL) {
|
||||||
|
@ -24,6 +25,9 @@ liftoff_layer_create(struct liftoff_output *output)
|
||||||
free(layer);
|
free(layer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < LIFTOFF_PROP_LAST; i++) {
|
||||||
|
layer->core_props[i] = -1;
|
||||||
|
}
|
||||||
liftoff_list_insert(output->layers.prev, &layer->link);
|
liftoff_list_insert(output->layers.prev, &layer->link);
|
||||||
output->layers_changed = true;
|
output->layers_changed = true;
|
||||||
return layer;
|
return layer;
|
||||||
|
@ -49,11 +53,29 @@ liftoff_layer_destroy(struct liftoff_layer *layer)
|
||||||
free(layer);
|
free(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct liftoff_layer_property *
|
||||||
|
layer_get_core_property(struct liftoff_layer *layer, enum liftoff_core_property prop)
|
||||||
|
{
|
||||||
|
ssize_t i;
|
||||||
|
|
||||||
|
i = layer->core_props[prop];
|
||||||
|
if (i < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &layer->props[i];
|
||||||
|
}
|
||||||
|
|
||||||
struct liftoff_layer_property *
|
struct liftoff_layer_property *
|
||||||
layer_get_property(struct liftoff_layer *layer, const char *name)
|
layer_get_property(struct liftoff_layer *layer, const char *name)
|
||||||
{
|
{
|
||||||
|
ssize_t core_prop_idx;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
core_prop_idx = core_property_index(name);
|
||||||
|
if (core_prop_idx >= 0) {
|
||||||
|
return layer_get_core_property(layer, core_prop_idx);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < layer->props_len; i++) {
|
for (i = 0; i < layer->props_len; i++) {
|
||||||
if (strcmp(layer->props[i].name, name) == 0) {
|
if (strcmp(layer->props[i].name, name) == 0) {
|
||||||
return &layer->props[i];
|
return &layer->props[i];
|
||||||
|
@ -68,6 +90,7 @@ liftoff_layer_set_property(struct liftoff_layer *layer, const char *name,
|
||||||
{
|
{
|
||||||
struct liftoff_layer_property *props;
|
struct liftoff_layer_property *props;
|
||||||
struct liftoff_layer_property *prop;
|
struct liftoff_layer_property *prop;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if (strcmp(name, "CRTC_ID") == 0) {
|
if (strcmp(name, "CRTC_ID") == 0) {
|
||||||
liftoff_log(LIFTOFF_ERROR,
|
liftoff_log(LIFTOFF_ERROR,
|
||||||
|
@ -86,16 +109,22 @@ liftoff_layer_set_property(struct liftoff_layer *layer, const char *name,
|
||||||
layer->props = props;
|
layer->props = props;
|
||||||
layer->props_len++;
|
layer->props_len++;
|
||||||
|
|
||||||
prop = &layer->props[layer->props_len - 1];
|
i = layer->props_len - 1;
|
||||||
|
prop = &layer->props[i];
|
||||||
*prop = (struct liftoff_layer_property){0};
|
*prop = (struct liftoff_layer_property){0};
|
||||||
strncpy(prop->name, name, sizeof(prop->name) - 1);
|
strncpy(prop->name, name, sizeof(prop->name) - 1);
|
||||||
|
prop->core_index = core_property_index(name);
|
||||||
|
|
||||||
layer->changed = true;
|
layer->changed = true;
|
||||||
|
|
||||||
|
if (prop->core_index >= 0) {
|
||||||
|
layer->core_props[prop->core_index] = (ssize_t)i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prop->value = value;
|
prop->value = value;
|
||||||
|
|
||||||
if (strcmp(name, "FB_ID") == 0 && layer->force_composition) {
|
if (prop->core_index == LIFTOFF_PROP_FB_ID && layer->force_composition) {
|
||||||
layer->force_composition = false;
|
layer->force_composition = false;
|
||||||
layer->changed = true;
|
layer->changed = true;
|
||||||
}
|
}
|
||||||
|
@ -113,9 +142,16 @@ liftoff_layer_unset_property(struct liftoff_layer *layer, const char *name)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prop->core_index >= 0) {
|
||||||
|
layer->core_props[prop->core_index] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
last = &layer->props[layer->props_len - 1];
|
last = &layer->props[layer->props_len - 1];
|
||||||
if (prop != last) {
|
if (prop != last) {
|
||||||
*prop = *last;
|
*prop = *last;
|
||||||
|
if (last->core_index >= 0) {
|
||||||
|
layer->core_props[last->core_index] = prop - layer->props;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*last = (struct liftoff_layer_property){0};
|
*last = (struct liftoff_layer_property){0};
|
||||||
layer->props_len--;
|
layer->props_len--;
|
||||||
|
@ -156,10 +192,10 @@ layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect)
|
||||||
{
|
{
|
||||||
struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop;
|
struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop;
|
||||||
|
|
||||||
x_prop = layer_get_property(layer, "CRTC_X");
|
x_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_X);
|
||||||
y_prop = layer_get_property(layer, "CRTC_Y");
|
y_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_Y);
|
||||||
w_prop = layer_get_property(layer, "CRTC_W");
|
w_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_W);
|
||||||
h_prop = layer_get_property(layer, "CRTC_H");
|
h_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_H);
|
||||||
|
|
||||||
rect->x = x_prop != NULL ? x_prop->value : 0;
|
rect->x = x_prop != NULL ? x_prop->value : 0;
|
||||||
rect->y = y_prop != NULL ? y_prop->value : 0;
|
rect->y = y_prop != NULL ? y_prop->value : 0;
|
||||||
|
@ -172,10 +208,10 @@ layer_get_prev_rect(struct liftoff_layer *layer, struct liftoff_rect *rect)
|
||||||
{
|
{
|
||||||
struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop;
|
struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop;
|
||||||
|
|
||||||
x_prop = layer_get_property(layer, "CRTC_X");
|
x_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_X);
|
||||||
y_prop = layer_get_property(layer, "CRTC_Y");
|
y_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_Y);
|
||||||
w_prop = layer_get_property(layer, "CRTC_W");
|
w_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_W);
|
||||||
h_prop = layer_get_property(layer, "CRTC_H");
|
h_prop = layer_get_core_property(layer, LIFTOFF_PROP_CRTC_H);
|
||||||
|
|
||||||
rect->x = x_prop != NULL ? x_prop->prev_value : 0;
|
rect->x = x_prop != NULL ? x_prop->prev_value : 0;
|
||||||
rect->y = y_prop != NULL ? y_prop->prev_value : 0;
|
rect->y = y_prop != NULL ? y_prop->prev_value : 0;
|
||||||
|
@ -236,7 +272,7 @@ layer_update_priority(struct liftoff_layer *layer, bool make_current)
|
||||||
struct liftoff_layer_property *prop;
|
struct liftoff_layer_property *prop;
|
||||||
|
|
||||||
/* TODO: also bump priority when updating other properties */
|
/* TODO: also bump priority when updating other properties */
|
||||||
prop = layer_get_property(layer, "FB_ID");
|
prop = layer_get_core_property(layer, LIFTOFF_PROP_FB_ID);
|
||||||
if (prop != NULL && prop->prev_value != prop->value) {
|
if (prop != NULL && prop->prev_value != prop->value) {
|
||||||
layer->pending_priority++;
|
layer->pending_priority++;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +289,7 @@ layer_has_fb(struct liftoff_layer *layer)
|
||||||
{
|
{
|
||||||
struct liftoff_layer_property *fb_id_prop;
|
struct liftoff_layer_property *fb_id_prop;
|
||||||
|
|
||||||
fb_id_prop = layer_get_property(layer, "FB_ID");
|
fb_id_prop = layer_get_core_property(layer, LIFTOFF_PROP_FB_ID);
|
||||||
return fb_id_prop != NULL && fb_id_prop->value != 0;
|
return fb_id_prop != NULL && fb_id_prop->value != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +298,7 @@ layer_is_visible(struct liftoff_layer *layer)
|
||||||
{
|
{
|
||||||
struct liftoff_layer_property *alpha_prop;
|
struct liftoff_layer_property *alpha_prop;
|
||||||
|
|
||||||
alpha_prop = layer_get_property(layer, "alpha");
|
alpha_prop = layer_get_core_property(layer, LIFTOFF_PROP_ALPHA);
|
||||||
if (alpha_prop != NULL && alpha_prop->value == 0) {
|
if (alpha_prop != NULL && alpha_prop->value == 0) {
|
||||||
return false; /* fully transparent */
|
return false; /* fully transparent */
|
||||||
}
|
}
|
||||||
|
@ -282,7 +318,7 @@ layer_cache_fb_info(struct liftoff_layer *layer)
|
||||||
size_t i, j, num_planes;
|
size_t i, j, num_planes;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
fb_id_prop = layer_get_property(layer, "FB_ID");
|
fb_id_prop = layer_get_core_property(layer, LIFTOFF_PROP_FB_ID);
|
||||||
if (fb_id_prop == NULL || fb_id_prop->value == 0) {
|
if (fb_id_prop == NULL || fb_id_prop->value == 0) {
|
||||||
layer->fb_info = (drmModeFB2){0};
|
layer->fb_info = (drmModeFB2){0};
|
||||||
return 0;
|
return 0;
|
||||||
|
|
39
plane.c
39
plane.c
|
@ -43,6 +43,7 @@ liftoff_plane_create(struct liftoff_device *device, uint32_t id)
|
||||||
drmModePropertyRes *prop;
|
drmModePropertyRes *prop;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
bool has_type = false, has_zpos = false;
|
bool has_type = false, has_zpos = false;
|
||||||
|
ssize_t core_prop_idx;
|
||||||
|
|
||||||
liftoff_list_for_each(plane, &device->planes, link) {
|
liftoff_list_for_each(plane, &device->planes, link) {
|
||||||
if (plane->id == id) {
|
if (plane->id == id) {
|
||||||
|
@ -105,6 +106,11 @@ liftoff_plane_create(struct liftoff_device *device, uint32_t id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
core_prop_idx = core_property_index(prop->name);
|
||||||
|
if (core_prop_idx >= 0) {
|
||||||
|
plane->core_props[core_prop_idx] = prop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drmModeFreeObjectProperties(drm_props);
|
drmModeFreeObjectProperties(drm_props);
|
||||||
|
|
||||||
|
@ -173,12 +179,16 @@ liftoff_plane_get_id(struct liftoff_plane *plane)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const drmModePropertyRes *
|
static const drmModePropertyRes *
|
||||||
plane_get_property(struct liftoff_plane *plane, const char *name)
|
plane_get_property(struct liftoff_plane *plane,
|
||||||
|
const struct liftoff_layer_property *layer_prop)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (layer_prop->core_index >= 0)
|
||||||
|
return plane->core_props[layer_prop->core_index];
|
||||||
|
|
||||||
for (i = 0; i < plane->props_len; i++) {
|
for (i = 0; i < plane->props_len; i++) {
|
||||||
if (strcmp(plane->props[i]->name, name) == 0) {
|
if (strcmp(plane->props[i]->name, layer_prop->name) == 0) {
|
||||||
return plane->props[i];
|
return plane->props[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,16 +286,16 @@ plane_set_prop(struct liftoff_plane *plane, drmModeAtomicReq *req,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_plane_prop_str(struct liftoff_plane *plane, drmModeAtomicReq *req,
|
set_plane_core_prop(struct liftoff_plane *plane, drmModeAtomicReq *req,
|
||||||
const char *name, uint64_t value)
|
enum liftoff_core_property core_prop, uint64_t value)
|
||||||
{
|
{
|
||||||
const drmModePropertyRes *prop;
|
const drmModePropertyRes *prop;
|
||||||
|
|
||||||
prop = plane_get_property(plane, name);
|
prop = plane->core_props[core_prop];
|
||||||
if (prop == NULL) {
|
if (prop == NULL) {
|
||||||
liftoff_log(LIFTOFF_DEBUG,
|
liftoff_log(LIFTOFF_DEBUG,
|
||||||
"plane %"PRIu32" is missing the %s property",
|
"plane %"PRIu32" is missing core property %d",
|
||||||
plane->id, name);
|
plane->id, core_prop);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,33 +365,34 @@ plane_apply(struct liftoff_plane *plane, struct liftoff_layer *layer,
|
||||||
cursor = drmModeAtomicGetCursor(req);
|
cursor = drmModeAtomicGetCursor(req);
|
||||||
|
|
||||||
if (layer == NULL) {
|
if (layer == NULL) {
|
||||||
ret = set_plane_prop_str(plane, req, "FB_ID", 0);
|
ret = set_plane_core_prop(plane, req, LIFTOFF_PROP_FB_ID, 0);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return set_plane_prop_str(plane, req, "CRTC_ID", 0);
|
return set_plane_core_prop(plane, req, LIFTOFF_PROP_CRTC_ID, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = set_plane_prop_str(plane, req, "CRTC_ID", layer->output->crtc_id);
|
ret = set_plane_core_prop(plane, req, LIFTOFF_PROP_CRTC_ID,
|
||||||
|
layer->output->crtc_id);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < layer->props_len; i++) {
|
for (i = 0; i < layer->props_len; i++) {
|
||||||
layer_prop = &layer->props[i];
|
layer_prop = &layer->props[i];
|
||||||
if (strcmp(layer_prop->name, "zpos") == 0) {
|
if (layer_prop->core_index == LIFTOFF_PROP_ZPOS) {
|
||||||
/* We don't yet support setting the zpos property. We
|
/* We don't yet support setting the zpos property. We
|
||||||
* only use it (read-only) during plane allocation. */
|
* only use it (read-only) during plane allocation. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
plane_prop = plane_get_property(plane, layer_prop->name);
|
plane_prop = plane_get_property(plane, layer_prop);
|
||||||
if (plane_prop == NULL) {
|
if (plane_prop == NULL) {
|
||||||
if (strcmp(layer_prop->name, "alpha") == 0 &&
|
if (layer_prop->core_index == LIFTOFF_PROP_ALPHA &&
|
||||||
layer_prop->value == 0xFFFF) {
|
layer_prop->value == 0xFFFF) {
|
||||||
continue; /* Layer is completely opaque */
|
continue; /* Layer is completely opaque */
|
||||||
}
|
}
|
||||||
if (strcmp(layer_prop->name, "rotation") == 0 &&
|
if (layer_prop->core_index == LIFTOFF_PROP_ROTATION &&
|
||||||
layer_prop->value == DRM_MODE_ROTATE_0) {
|
layer_prop->value == DRM_MODE_ROTATE_0) {
|
||||||
continue; /* Layer isn't rotated */
|
continue; /* Layer isn't rotated */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue