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>
dev
Marius Vlad 5 years ago committed by Daniel Stone
parent 26dcce06d7
commit 80a62e5873
  1. 55
      libweston/backend-drm/state-propose.c

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

Loading…
Cancel
Save