Bail out based on remaining compatible planes

If we've found a good previous allocation, it's possible that there
is no point trying to continue exploring the graph. In particular,
if we won't get a higher score even if we manage to make use of all
available planes, we can stop right away.

For instance, let's say that we've previously found a way to make use
of 3 out of 5 planes. We're exploring a different path where we've
populated 1 plane, we've skipped 1 plane because we couldn't find a
suitable layer for it, and out of the 3 remaining planes only 2 are
compatible with the CRTC we're interested in. Even if we manage to
make use of these 2 extra planes we would end up with 3 effectively
used planes thus no benefit over the previous solution.
This commit is contained in:
Simon Ser 2024-05-15 13:53:20 +02:00
parent ec86735763
commit 8d45eeae7f

38
alloc.c
View file

@ -415,6 +415,31 @@ check_alloc_valid(struct liftoff_output *output, struct alloc_result *result,
return true;
}
static bool
check_plane_output_compatible(struct liftoff_plane *plane, struct liftoff_output *output)
{
return (plane->possible_crtcs & (1 << output->crtc_index)) != 0;
}
static int
count_remaining_compatible_planes(struct liftoff_output *output,
struct alloc_step *step)
{
struct liftoff_list *link;
struct liftoff_plane *plane;
int remaining = 0;
for (link = step->plane_link; link != &output->device->planes; link = link->next) {
plane = liftoff_container_of(link, plane, link);
if (plane->layer == NULL &&
check_plane_output_compatible(plane, output)) {
remaining++;
}
}
return remaining;
}
static int
output_choose_layers(struct liftoff_output *output, struct alloc_result *result,
struct alloc_step *step)
@ -423,7 +448,7 @@ output_choose_layers(struct liftoff_output *output, struct alloc_result *result,
struct liftoff_plane *plane;
struct liftoff_layer *layer;
int cursor, ret;
size_t remaining_planes;
int remaining_planes;
struct alloc_step next_step = {0};
device = output->device;
@ -444,21 +469,16 @@ output_choose_layers(struct liftoff_output *output, struct alloc_result *result,
plane = liftoff_container_of(step->plane_link, plane, link);
remaining_planes = result->planes_len - step->plane_idx;
if (result->best_score >= step->score + (int)remaining_planes) {
remaining_planes = count_remaining_compatible_planes(output, step);
if (result->best_score >= step->score + remaining_planes) {
/* Even if we find a layer for all remaining planes, we won't
* find a better allocation. Give up. */
/* TODO: change remaining_planes to only count those whose
* possible CRTC match and which aren't allocated */
return 0;
}
cursor = drmModeAtomicGetCursor(result->req);
if (plane->layer != NULL) {
goto skip;
}
if ((plane->possible_crtcs & (1 << output->crtc_index)) == 0) {
if (plane->layer != NULL || !check_plane_output_compatible(plane, output)) {
goto skip;
}