Keep track of the update frequency of each layer

Keep track of the number of layer updates per 60 page-flips.

We could implement a more fine-grained tracking, for instance with a sliding
window. However it's a lot more complex than the current solution and the gains
are not clear. I'd prefer to keep the current solution and experiment with other
solutions once we have a good test-bed.

References: https://github.com/emersion/libliftoff/issues/22
This commit is contained in:
Simon Ser 2019-11-15 21:43:44 +01:00
parent 78cc612f10
commit 5f39331f78
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
3 changed files with 48 additions and 0 deletions

21
alloc.c
View file

@ -550,6 +550,25 @@ static void mark_layers_clean(struct liftoff_display *display)
}
}
static void update_layers_priority(struct liftoff_display *display)
{
struct liftoff_output *output;
struct liftoff_layer *layer;
display->page_flip_counter++;
bool period_elapsed =
display->page_flip_counter >= LIFTOFF_PRIORITY_PERIOD;
if (period_elapsed) {
display->page_flip_counter = 0;
}
liftoff_list_for_each(output, &display->outputs, link) {
liftoff_list_for_each(layer, &output->layers, link) {
layer_update_priority(layer, period_elapsed);
}
}
}
bool liftoff_display_apply(struct liftoff_display *display, drmModeAtomicReq *req)
{
struct liftoff_output *output;
@ -560,6 +579,8 @@ bool liftoff_display_apply(struct liftoff_display *display, drmModeAtomicReq *re
size_t i;
bool compatible;
update_layers_priority(display);
if (reuse_previous_alloc(display, req)) {
liftoff_log(LIFTOFF_DEBUG, "Re-using previous plane allocation");
return true;

View file

@ -5,6 +5,10 @@
#include "list.h"
#include "log.h"
/* Layer priority is assigned depending on the number of updates during a
* given number of page-flips */
#define LIFTOFF_PRIORITY_PERIOD 60
struct liftoff_display {
int drm_fd;
@ -13,6 +17,8 @@ struct liftoff_display {
uint32_t *crtcs;
size_t crtcs_len;
int page_flip_counter;
};
struct liftoff_output {
@ -34,6 +40,8 @@ struct liftoff_layer {
size_t props_len;
struct liftoff_plane *plane;
int current_priority, pending_priority;
};
struct liftoff_layer_property {
@ -71,6 +79,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);
void layer_mark_clean(struct liftoff_layer *layer);
void layer_update_priority(struct liftoff_layer *layer, bool make_current);
struct liftoff_plane *plane_create(struct liftoff_display *display, uint32_t id);
void plane_destroy(struct liftoff_plane *plane);

18
layer.c
View file

@ -117,3 +117,21 @@ void layer_mark_clean(struct liftoff_layer *layer)
layer->props[i].changed = false;
}
}
void layer_update_priority(struct liftoff_layer *layer, bool make_current) {
struct liftoff_layer_property *prop;
/* TODO: also bump priority when updating other
* properties */
prop = layer_get_property(layer, "FB_ID");
if (prop->changed) {
layer->pending_priority++;
}
if (make_current) {
layer->current_priority = layer->pending_priority;
layer->pending_priority = 0;
liftoff_log(LIFTOFF_DEBUG, "Layer %p has priority %d",
(void *)layer, layer->current_priority);
}
}