2019-09-30 20:22:01 +02:00
|
|
|
#include <assert.h>
|
2019-12-12 23:40:01 +01:00
|
|
|
#include <inttypes.h>
|
2019-08-21 22:07:37 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2019-09-08 16:41:25 +02:00
|
|
|
#include <sys/types.h>
|
2019-08-21 22:07:37 +02:00
|
|
|
#include "private.h"
|
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
struct liftoff_output *
|
|
|
|
liftoff_output_create(struct liftoff_device *device, uint32_t crtc_id)
|
2019-08-21 22:07:37 +02:00
|
|
|
{
|
2019-09-12 10:39:06 +02:00
|
|
|
struct liftoff_output *output;
|
2019-09-08 16:41:25 +02:00
|
|
|
ssize_t crtc_index;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
crtc_index = -1;
|
2019-11-24 12:59:10 +01:00
|
|
|
for (i = 0; i < device->crtcs_len; i++) {
|
|
|
|
if (device->crtcs[i] == crtc_id) {
|
2023-02-16 21:33:36 +01:00
|
|
|
crtc_index = (ssize_t)i;
|
2019-09-08 16:41:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (crtc_index < 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-08-21 22:07:37 +02:00
|
|
|
|
|
|
|
output = calloc(1, sizeof(*output));
|
|
|
|
if (output == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-11-24 12:59:10 +01:00
|
|
|
output->device = device;
|
2019-08-21 22:07:37 +02:00
|
|
|
output->crtc_id = crtc_id;
|
2023-02-16 21:33:36 +01:00
|
|
|
output->crtc_index = (size_t)crtc_index;
|
2019-09-12 10:39:06 +02:00
|
|
|
liftoff_list_init(&output->layers);
|
2019-11-24 12:59:10 +01:00
|
|
|
liftoff_list_insert(&device->outputs, &output->link);
|
2019-08-21 22:07:37 +02:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
void
|
|
|
|
liftoff_output_destroy(struct liftoff_output *output)
|
2019-08-21 22:07:37 +02:00
|
|
|
{
|
2019-12-31 20:46:08 +01:00
|
|
|
if (output == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-12 10:39:06 +02:00
|
|
|
liftoff_list_remove(&output->link);
|
2019-08-21 22:07:37 +02:00
|
|
|
free(output);
|
|
|
|
}
|
2019-09-30 20:22:01 +02:00
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
void
|
|
|
|
liftoff_output_set_composition_layer(struct liftoff_output *output,
|
|
|
|
struct liftoff_layer *layer)
|
2019-09-30 20:22:01 +02:00
|
|
|
{
|
|
|
|
assert(layer->output == output);
|
2019-12-12 23:22:18 +01:00
|
|
|
if (layer != output->composition_layer) {
|
|
|
|
output->layers_changed = true;
|
|
|
|
}
|
2019-09-30 20:22:01 +02:00
|
|
|
output->composition_layer = layer;
|
|
|
|
}
|
2019-12-12 23:40:01 +01:00
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
bool
|
|
|
|
liftoff_output_needs_composition(struct liftoff_output *output)
|
2020-12-06 15:07:03 +01:00
|
|
|
{
|
|
|
|
struct liftoff_layer *layer;
|
|
|
|
|
|
|
|
liftoff_list_for_each(layer, &output->layers, link) {
|
|
|
|
if (liftoff_layer_needs_composition(layer)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
static double
|
|
|
|
fp16_to_double(uint64_t val)
|
|
|
|
{
|
2021-08-09 12:48:30 +02:00
|
|
|
return (double)(val >> 16) + (double)(val & 0xFFFF) / 0xFFFF;
|
|
|
|
}
|
|
|
|
|
2021-08-13 22:02:33 +02:00
|
|
|
void
|
|
|
|
output_log_layers(struct liftoff_output *output)
|
|
|
|
{
|
2019-12-12 23:40:01 +01:00
|
|
|
struct liftoff_layer *layer;
|
|
|
|
size_t i;
|
2020-04-09 18:25:37 +02:00
|
|
|
bool is_composition_layer;
|
2019-12-12 23:40:01 +01:00
|
|
|
|
2020-02-26 12:24:12 +01:00
|
|
|
if (!log_has(LIFTOFF_DEBUG)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-08-12 18:36:52 +02:00
|
|
|
liftoff_log(LIFTOFF_DEBUG, "Layers on CRTC %"PRIu32" (%zu total):",
|
|
|
|
output->crtc_id, liftoff_list_length(&output->layers));
|
2019-12-12 23:40:01 +01:00
|
|
|
liftoff_list_for_each(layer, &output->layers, link) {
|
2020-02-26 13:26:29 +01:00
|
|
|
if (layer->force_composition) {
|
|
|
|
liftoff_log(LIFTOFF_DEBUG, " Layer %p "
|
|
|
|
"(forced composition):", (void *)layer);
|
|
|
|
} else {
|
|
|
|
if (!layer_has_fb(layer)) {
|
|
|
|
continue;
|
|
|
|
}
|
2020-04-09 18:25:37 +02:00
|
|
|
is_composition_layer = output->composition_layer == layer;
|
|
|
|
liftoff_log(LIFTOFF_DEBUG, " Layer %p%s:",
|
|
|
|
(void *)layer, is_composition_layer ?
|
|
|
|
" (composition layer)" : "");
|
2020-02-26 13:26:29 +01:00
|
|
|
}
|
|
|
|
|
Keep output layers ordered by allocation priority
To optimize for offloading success, the list of output layers can be
ordered by allocation priority, improving the chances of a higher
allocation score before the deadline.
The allocation algorithm picks DRM planes first, then tests output
layers against them. To reduce the number of tests, the layers can be
ordered such that it matches the DRM plane order. DRM planes in
libliftoff are ordered by primary, followed by all other planes in
descending z-order. We order the layers similarly, with the composition
layer first, followed by layers of descending priority.
In addition to layer priority, it's z-pos and intersection with other
layers are considered. Since to offload a high priority layer, all
intersection layers with higher z-pos will also need to be offloaded.
This also changes when reallocation is necessary. On top of the existing
criteria, reallocation is done when a layer's ordering changes.
With layer priority now considered, the priority test now passes --
enable it.
2023-10-02 23:55:55 +02:00
|
|
|
liftoff_log(LIFTOFF_DEBUG, " Priority = %"PRIi32,
|
|
|
|
layer->current_priority);
|
|
|
|
|
2019-12-12 23:40:01 +01:00
|
|
|
for (i = 0; i < layer->props_len; i++) {
|
2020-02-26 12:45:33 +01:00
|
|
|
char *name = layer->props[i].name;
|
|
|
|
uint64_t value = layer->props[i].value;
|
|
|
|
|
|
|
|
if (strcmp(name, "CRTC_X") == 0 ||
|
|
|
|
strcmp(name, "CRTC_Y") == 0) {
|
2021-08-09 12:48:30 +02:00
|
|
|
liftoff_log(LIFTOFF_DEBUG, " %s = %+"PRIi32,
|
2020-02-26 12:45:33 +01:00
|
|
|
name, (int32_t)value);
|
2021-08-09 12:48:30 +02:00
|
|
|
} else if (strcmp(name, "SRC_X") == 0 ||
|
|
|
|
strcmp(name, "SRC_Y") == 0 ||
|
|
|
|
strcmp(name, "SRC_W") == 0 ||
|
2020-02-26 12:45:33 +01:00
|
|
|
strcmp(name, "SRC_H") == 0) {
|
2021-08-09 12:48:30 +02:00
|
|
|
liftoff_log(LIFTOFF_DEBUG, " %s = %f",
|
|
|
|
name, fp16_to_double(value));
|
2020-02-26 12:45:33 +01:00
|
|
|
} else {
|
|
|
|
liftoff_log(LIFTOFF_DEBUG, " %s = %"PRIu64,
|
|
|
|
name, value);
|
|
|
|
}
|
2019-12-12 23:40:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|