backend-drm: Allow for views to reach overlays/underlays planes

In this manner we will allow views to reach the overlay (or underlays)
even if the damage tracking will detect that the new view will
occlude the view underneath it.

Renames occluded_region to planes_region, and uses occluded_region
to represent the region where we add each view's visible-and-opaque region.
Sprinkle some comments about each region.

Re-uses the view's clipped region to determine visible-and-opaque region
which is accumulated (for both renderer and HW planes cases) into
occluded_region. The current view's clipped_region is then checked against
occluded_region.

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Suggested-by: Daniel Stone <daniel.stone@collabora.com>
This commit is contained in:
Marius Vlad 2019-09-11 18:21:59 +03:00 committed by Daniel Stone
parent 26dcce06d7
commit 80a62e5873
1 changed files with 42 additions and 13 deletions

View File

@ -713,7 +713,10 @@ drm_output_propose_state(struct weston_output *output_base,
struct drm_output_state *state;
struct drm_plane_state *scanout_state = NULL;
struct weston_view *ev;
pixman_region32_t surface_overlap, renderer_region, occluded_region;
pixman_region32_t surface_overlap, renderer_region, planes_region;
pixman_region32_t occluded_region;
bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
int ret;
uint64_t current_lowest_zpos = DRM_PLANE_ZPOS_INVALID_PLANE;
@ -766,20 +769,19 @@ drm_output_propose_state(struct weston_output *output_base,
(unsigned long) output->base.id);
}
/*
* Find a surface for each sprite in the output using some heuristics:
* 1) size
* 2) frequency of update
* 3) opacity (though some hw might support alpha blending)
* 4) clipping (this can be fixed with color keys)
*
* The idea is to save on blitting since this should save power.
* If we can get a large video surface on the sprite for example,
* the main display surface may not need to update at all, and
* the client buffer can be used directly for the sprite surface
* as we do for flipping full screen surfaces.
/* - renderer_region contains the total region which which will be
* covered by the renderer
* - planes_region contains the total region which has been covered by
* hardware planes
* - occluded_region contains the total region which which will be
* covered by the renderer and hardware planes, where the view's
* visible-and-opaque region is added in both cases (the view's
* opaque region accumulates there for each view); it is being used
* to skip the view, if it is completely occluded; includes the
* situation where occluded_region covers entire output's region.
*/
pixman_region32_init(&renderer_region);
pixman_region32_init(&planes_region);
pixman_region32_init(&occluded_region);
wl_list_for_each(ev, &output_base->compositor->view_list, link) {
@ -824,6 +826,9 @@ drm_output_propose_state(struct weston_output *output_base,
pixman_region32_init(&surface_overlap);
pixman_region32_subtract(&surface_overlap, &clipped_view,
&occluded_region);
/* if the view is completely occluded then ignore that
* view; includes the case where occluded_region covers
* the entire output */
totally_occluded = !pixman_region32_not_empty(&surface_overlap);
if (totally_occluded) {
drm_debug(b, "\t\t\t\t[view] ignoring view %p "
@ -875,10 +880,22 @@ drm_output_propose_state(struct weston_output *output_base,
* be added to the renderer region nor the occluded
* region. */
if (ps->plane->type != WDRM_PLANE_TYPE_CURSOR) {
pixman_region32_union(&planes_region,
&planes_region,
&clipped_view);
if (!weston_view_is_opaque(ev, &clipped_view))
pixman_region32_intersect(&clipped_view,
&clipped_view,
&ev->transform.opaque);
/* the visible-and-opaque region of this view
* will occlude views underneath it */
pixman_region32_union(&occluded_region,
&occluded_region,
&clipped_view);
pixman_region32_fini(&clipped_view);
}
continue;
}
@ -897,9 +914,21 @@ drm_output_propose_state(struct weston_output *output_base,
pixman_region32_union(&renderer_region,
&renderer_region,
&clipped_view);
if (!weston_view_is_opaque(ev, &clipped_view))
pixman_region32_intersect(&clipped_view,
&clipped_view,
&ev->transform.opaque);
pixman_region32_union(&occluded_region,
&occluded_region,
&clipped_view);
pixman_region32_fini(&clipped_view);
}
pixman_region32_fini(&renderer_region);
pixman_region32_fini(&planes_region);
pixman_region32_fini(&occluded_region);
/* In renderer-only mode, we can't test the state as we don't have a