mirror of
https://gitlab.freedesktop.org/emersion/libliftoff.git
synced 2024-11-16 19:47:55 +01:00
Add needs_composition APIs
Right now, compositors are expected to query liftoff_layer_get_plane_id to decide whether a layer needs to be composited. However there are cases where a layer has no plane, but still doesn't need composition (e.g. when FB_ID is zero or when alpha is zero, in the future when the layer is out of CRTC bounds etc). Add a new API to make users' life simpler. Closes: https://github.com/emersion/libliftoff/issues/54
This commit is contained in:
parent
87e5dcfe72
commit
6321e7c5aa
7 changed files with 58 additions and 4 deletions
|
@ -84,7 +84,7 @@ used to tell libliftoff that composition will happen on this special layer.
|
|||
If all regular layers can be put into a plane, the composition layer won't be
|
||||
used. Otherwise, the compositor needs to perform the composition prior to
|
||||
performing a page-flip. Each layer that didn't make it into a hardware plane
|
||||
(ie. `liftoff_layer_get_plane` returns NULL) needs to be composited.
|
||||
(ie. `liftoff_layer_needs_composition` returns true) needs to be composited.
|
||||
|
||||
## Disabling layers
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* Composite layers that didn't make it into a plane */
|
||||
for (i = 1; i < layers_len; i++) {
|
||||
if (liftoff_layer_get_plane(layers[i]) == NULL) {
|
||||
if (liftoff_layer_needs_composition(layers[i])) {
|
||||
composite(drm_fd, &composition_fb, &fbs[i],
|
||||
i * 100, i * 100);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define LIFTOFF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
@ -56,8 +57,8 @@ uint32_t liftoff_plane_get_id(struct liftoff_plane *plane);
|
|||
/**
|
||||
* Build a layer to plane mapping and append the plane configuration to `req`.
|
||||
*
|
||||
* Callers are expected to commit `req` afterwards and can read the layer to
|
||||
* plane mapping with `liftoff_layer_get_plane`.
|
||||
* Callers are expected to commit `req` afterwards and can figure out which
|
||||
* layers need composition via `liftoff_layer_needs_composition`.
|
||||
*
|
||||
* `flags` is the atomic commit flags the caller intends to use.
|
||||
*
|
||||
|
@ -88,6 +89,14 @@ void liftoff_output_destroy(struct liftoff_output *output);
|
|||
*/
|
||||
void liftoff_output_set_composition_layer(struct liftoff_output *output,
|
||||
struct liftoff_layer *layer);
|
||||
/**
|
||||
* Check whether this output needs composition.
|
||||
*
|
||||
* An output doesn't need composition if all visible layers could be mapped to a
|
||||
* plane. In other words, if an output needs composition, at least one layer
|
||||
* will return true when `liftoff_layer_needs_composition` is called.
|
||||
*/
|
||||
bool liftoff_output_needs_composition(struct liftoff_output *output);
|
||||
|
||||
/**
|
||||
* Create a new layer on an output.
|
||||
|
@ -124,6 +133,13 @@ int liftoff_layer_set_property(struct liftoff_layer *layer, const char *name,
|
|||
* needs to be displayed (e.g. the buffer cannot be imported in KMS).
|
||||
*/
|
||||
void liftoff_layer_set_fb_composited(struct liftoff_layer *layer);
|
||||
/**
|
||||
* Check whether this layer needs composition.
|
||||
*
|
||||
* A layer needs composition if it's visible and if it couldn't be mapped to a
|
||||
* plane.
|
||||
*/
|
||||
bool liftoff_layer_needs_composition(struct liftoff_layer *layer);
|
||||
/**
|
||||
* Retrieve the plane mapped to this layer.
|
||||
*
|
||||
|
|
8
layer.c
8
layer.c
|
@ -106,6 +106,14 @@ struct liftoff_plane *liftoff_layer_get_plane(struct liftoff_layer *layer)
|
|||
return layer->plane;
|
||||
}
|
||||
|
||||
bool liftoff_layer_needs_composition(struct liftoff_layer *layer)
|
||||
{
|
||||
if (!layer_is_visible(layer)) {
|
||||
return false;
|
||||
}
|
||||
return layer->plane == NULL;
|
||||
}
|
||||
|
||||
void layer_get_rect(struct liftoff_layer *layer, struct liftoff_rect *rect)
|
||||
{
|
||||
struct liftoff_layer_property *x_prop, *y_prop, *w_prop, *h_prop;
|
||||
|
|
13
output.c
13
output.c
|
@ -55,6 +55,19 @@ void liftoff_output_set_composition_layer(struct liftoff_output *output,
|
|||
output->composition_layer = layer;
|
||||
}
|
||||
|
||||
bool liftoff_output_needs_composition(struct liftoff_output *output)
|
||||
{
|
||||
struct liftoff_layer *layer;
|
||||
|
||||
liftoff_list_for_each(layer, &output->layers, link) {
|
||||
if (liftoff_layer_needs_composition(layer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void output_log_layers(struct liftoff_output *output) {
|
||||
struct liftoff_layer *layer;
|
||||
size_t i;
|
||||
|
|
|
@ -606,6 +606,19 @@ static struct test_case tests[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static bool test_needs_composition(struct test_layer *test_layers)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; test_layers[i].width > 0; i++) {
|
||||
if (test_layers[i].result == NULL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void run_test(struct test_layer *test_layers)
|
||||
{
|
||||
size_t i, j;
|
||||
|
@ -696,6 +709,9 @@ static void run_test(struct test_layer *test_layers)
|
|||
}
|
||||
assert(ok);
|
||||
|
||||
assert(test_needs_composition(test_layers) ==
|
||||
liftoff_output_needs_composition(output));
|
||||
|
||||
liftoff_output_destroy(output);
|
||||
liftoff_device_destroy(device);
|
||||
close(drm_fd);
|
||||
|
|
|
@ -157,6 +157,7 @@ static int test_ignore_alpha(void)
|
|||
ret = drmModeAtomicCommit(drm_fd, req, 0, NULL);
|
||||
assert(ret == 0);
|
||||
assert(liftoff_mock_plane_get_layer(mock_plane) == NULL);
|
||||
assert(!liftoff_layer_needs_composition(layer));
|
||||
drmModeAtomicFree(req);
|
||||
|
||||
liftoff_device_destroy(device);
|
||||
|
|
Loading…
Reference in a new issue