mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-06-21 15:58:23 +02:00
Merge branch 'wip/mvlad/fast-direct-display' into 'main'
backend-drm: Prioritize direct-display paint nodes See merge request wayland/weston!2078
This commit is contained in:
commit
3f719bb601
1 changed files with 401 additions and 154 deletions
|
|
@ -987,10 +987,9 @@ is_paint_node_solid_opaque_untransformed(struct weston_paint_node *pnode)
|
|||
}
|
||||
|
||||
static bool
|
||||
lower_solid_views_to_background_region(struct drm_output *output,
|
||||
struct wl_array *visible_pnodes,
|
||||
struct weston_paint_node **last_visible_pnode,
|
||||
pixman_region32_t *background_region)
|
||||
try_solid_pnodes_to_background(struct drm_output *output, struct wl_array *visible_pnodes,
|
||||
struct weston_paint_node **last_visible_pnode,
|
||||
pixman_region32_t *background_region)
|
||||
{
|
||||
struct drm_device *device = output->device;
|
||||
struct drm_backend *b = device->backend;
|
||||
|
|
@ -1275,6 +1274,291 @@ drm_output_propose_state_try_reuse(struct weston_output *output_base,
|
|||
return state;
|
||||
}
|
||||
|
||||
static bool
|
||||
paint_node_has_direct_display_buffer(struct weston_paint_node *pnode)
|
||||
{
|
||||
struct weston_buffer *buffer = pnode->surface->buffer_ref.buffer;
|
||||
|
||||
if (buffer->type == WESTON_BUFFER_DMABUF) {
|
||||
if (buffer->direct_display)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
filter_pnodes_with_direct_display(struct drm_output *output,
|
||||
struct wl_array *visible_pnodes,
|
||||
struct wl_array *pnodes_with_direct_display,
|
||||
struct wl_array *pnodes_remaining)
|
||||
{
|
||||
struct weston_paint_node **pnode;
|
||||
|
||||
wl_array_for_each(pnode, visible_pnodes) {
|
||||
if (paint_node_has_direct_display_buffer(*pnode)) {
|
||||
struct weston_paint_node **pnode_new =
|
||||
wl_array_add(pnodes_with_direct_display, sizeof(*pnode));
|
||||
*pnode_new = *pnode;
|
||||
} else {
|
||||
struct weston_paint_node **pnode_new =
|
||||
wl_array_add(pnodes_remaining, sizeof(*pnode));
|
||||
*pnode_new = *pnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_pnodes_above_direct_display(struct drm_output *output,
|
||||
struct weston_paint_node *pnode_dd,
|
||||
struct wl_array *result)
|
||||
{
|
||||
struct weston_paint_node *pnode;
|
||||
|
||||
/* all the paint nodes until pnode_dd being stacked on top should be
|
||||
* above pnode_dd; we just need to test for occlusion */
|
||||
wl_list_for_each(pnode, &output->base.paint_node_z_order_list,
|
||||
z_order_link) {
|
||||
bool pnode_above = false;
|
||||
|
||||
if (pnode == pnode_dd)
|
||||
break;
|
||||
|
||||
pixman_region32_t overlap;
|
||||
pixman_region32_init(&overlap);
|
||||
|
||||
if (pnode->is_fully_opaque)
|
||||
pixman_region32_intersect(&overlap,
|
||||
weston_paint_node_get_opaque_region(pnode),
|
||||
weston_paint_node_get_opaque_region(pnode_dd));
|
||||
else
|
||||
pixman_region32_intersect(&overlap, &pnode->visible, &pnode_dd->visible);
|
||||
|
||||
if (pixman_region32_not_empty(&overlap))
|
||||
pnode_above = true;
|
||||
|
||||
if (pnode_above) {
|
||||
struct weston_paint_node **node_above =
|
||||
wl_array_add(result, sizeof(*node_above));
|
||||
*node_above = pnode;
|
||||
}
|
||||
|
||||
pixman_region32_fini(&overlap);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filter_pnodes_above_direct_display(struct drm_output *output, struct wl_array *visible_pnodes,
|
||||
struct wl_array *pnodes_with_direct_display, struct wl_array *result)
|
||||
{
|
||||
struct weston_paint_node **pn;
|
||||
|
||||
wl_array_for_each(pn, pnodes_with_direct_display)
|
||||
find_pnodes_above_direct_display(output, *pn, result);
|
||||
}
|
||||
|
||||
static void
|
||||
filter_pnodes_duplicates(struct drm_output *output, struct wl_array *a, struct wl_array *b)
|
||||
{
|
||||
struct weston_paint_node **pa;
|
||||
struct wl_array tmp_dup;
|
||||
|
||||
wl_array_init(&tmp_dup);
|
||||
|
||||
wl_array_for_each(pa, a) {
|
||||
struct weston_paint_node **pb;
|
||||
bool found_dup = false;
|
||||
|
||||
wl_array_for_each(pb, b) {
|
||||
if (*pa == *pb) {
|
||||
found_dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_dup) {
|
||||
struct weston_paint_node **n =
|
||||
wl_array_add(&tmp_dup, sizeof(*n));
|
||||
*n = *pa;
|
||||
}
|
||||
}
|
||||
|
||||
wl_array_copy(a, &tmp_dup);
|
||||
wl_array_release(&tmp_dup);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_node_print_array(struct drm_backend *b, struct wl_array *array)
|
||||
{
|
||||
struct weston_paint_node **pn;
|
||||
|
||||
wl_array_for_each(pn, array) {
|
||||
struct weston_paint_node *p = *pn;
|
||||
drm_debug(b, "\t\t\t\t[paint node] paint node %s\n", p->internal_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
walk_paint_nodes(pixman_region32_t *renderer_region,
|
||||
pixman_region32_t *obscured_region,
|
||||
pixman_region32_t *background_region,
|
||||
struct drm_plane_state *scanout_state,
|
||||
struct drm_output_state *state,
|
||||
enum drm_output_propose_state_mode mode,
|
||||
uint64_t current_lowest_zpos_underlay,
|
||||
uint64_t current_lowest_zpos_overlay,
|
||||
struct drm_output *output,
|
||||
struct wl_array *pnodes,
|
||||
struct weston_paint_node *last_visible_pnode)
|
||||
{
|
||||
struct drm_device *device = output->device;
|
||||
struct drm_backend *b = device->backend;
|
||||
struct weston_paint_node **visible_pnode;
|
||||
|
||||
/* Assign paint nodes to planes. */
|
||||
wl_array_for_each(visible_pnode, pnodes) {
|
||||
struct weston_paint_node *pnode = *visible_pnode;
|
||||
struct drm_plane_state *ps = NULL;
|
||||
bool need_underlay = false;
|
||||
pixman_region32_t tmp;
|
||||
bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] evaluating paint node %s for plane "
|
||||
"assignment on output %s (%lu)\n",
|
||||
pnode->internal_name, output->base.name,
|
||||
(unsigned long) output->base.id);
|
||||
|
||||
if (!b->gbm)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_GBM;
|
||||
|
||||
if (!weston_paint_node_has_valid_buffer(pnode))
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_BUFFER;
|
||||
|
||||
if (pnode->draw_solid)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_SOLID_SURFACE;
|
||||
|
||||
if (pnode->output->color_effect)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OUTPUT_COLOR_EFFECT;
|
||||
|
||||
if (pnode->surf_xform.transform && (!device->color_pipeline_supported ||
|
||||
!pnode->output->from_blend_to_output_by_backend))
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_COLOR_TRANSFORM;
|
||||
|
||||
/* Since we process views from top to bottom, we know that if
|
||||
* the view intersects the calculated renderer region, it must
|
||||
* be part of, or occluded by, it, and cannot go on an overlay
|
||||
* plane. */
|
||||
pixman_region32_init(&tmp);
|
||||
pixman_region32_intersect(&tmp, renderer_region, &pnode->clipped_view);
|
||||
if (pixman_region32_not_empty(&tmp)) {
|
||||
if (output->has_underlay) {
|
||||
need_underlay = true;
|
||||
} else {
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OCCLUDED_BY_RENDERER;
|
||||
drm_debug(b, "\t\t\t\t[paint node] not assigning paint node %s to a "
|
||||
"plane (occluded by renderer views), current lowest "
|
||||
"zpos change to %"PRIu64"\n", pnode->internal_name,
|
||||
current_lowest_zpos_underlay);
|
||||
}
|
||||
}
|
||||
pixman_region32_fini(&tmp);
|
||||
|
||||
/* If need_underlay, but view contains alpha, then it needs to
|
||||
* be rendered. Only fully-opaque views can go on an underlay.
|
||||
*/
|
||||
if (need_underlay && !pnode->is_fully_opaque)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OCCLUDED_BY_RENDERER;
|
||||
|
||||
/* In case of enforced mode of content-protection do not
|
||||
* assign planes for a protected surface on an unsecured output.
|
||||
*/
|
||||
if (pnode->censored)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_INADEQUATE_CONTENT_PROTECTION;
|
||||
|
||||
if (pnode->surface->tear_control)
|
||||
state->tear &= pnode->surface->tear_control->may_tear;
|
||||
else
|
||||
state->tear = 0;
|
||||
|
||||
/* Now try to place it on a plane if we can. */
|
||||
if (!pnode->try_view_on_plane_failure_reasons) {
|
||||
pixman_region32_t obscured_or_background_region;
|
||||
|
||||
drm_debug(b, "\t\t\t[plane] started with zpos %"PRIu64"\n",
|
||||
need_underlay ? current_lowest_zpos_underlay :
|
||||
current_lowest_zpos_overlay);
|
||||
|
||||
pixman_region32_init(&obscured_or_background_region);
|
||||
if (pnode == last_visible_pnode) {
|
||||
pixman_region32_union(&obscured_or_background_region,
|
||||
background_region,
|
||||
obscured_region);
|
||||
if (pixman_region32_not_empty(&obscured_or_background_region))
|
||||
drm_debug(b, "\t\t\t[plane] adding background region\n");
|
||||
}
|
||||
|
||||
ps = drm_output_find_plane_for_paint_node(state, pnode, mode,
|
||||
scanout_state,
|
||||
&obscured_or_background_region,
|
||||
current_lowest_zpos_overlay,
|
||||
current_lowest_zpos_underlay,
|
||||
need_underlay);
|
||||
|
||||
pixman_region32_fini(&obscured_or_background_region);
|
||||
}
|
||||
|
||||
if (ps) {
|
||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY &&
|
||||
ps->plane->type == WDRM_PLANE_TYPE_OVERLAY) {
|
||||
pixman_region32_union(obscured_region,
|
||||
obscured_region,
|
||||
weston_paint_node_get_opaque_region (pnode));
|
||||
}
|
||||
|
||||
if (drm_mixed_mode_check_underlay(mode, scanout_state, ps->zpos))
|
||||
current_lowest_zpos_underlay = ps->zpos;
|
||||
else
|
||||
current_lowest_zpos_overlay = ps->zpos;
|
||||
drm_debug(b, "\t\t\t[plane] next overlay zpos to use %"PRIu64","
|
||||
" next underlay zpos to use %"PRIu64"\n",
|
||||
current_lowest_zpos_overlay,
|
||||
current_lowest_zpos_underlay);
|
||||
} else if (!ps && !renderer_ok) {
|
||||
drm_debug(b, "\t\t[paint node] failing state generation: "
|
||||
"placing paint node %s to renderer not allowed\n",
|
||||
pnode->internal_name);
|
||||
return -1;
|
||||
} else if (!ps) {
|
||||
FILE *dbg = weston_log_scope_stream(b->debug);
|
||||
|
||||
if (dbg) {
|
||||
fprintf(dbg, "\t\t\t\t[paint node] paint node %s will be placed on the renderer: ",
|
||||
pnode->internal_name);
|
||||
bits_to_str_stream(pnode->try_view_on_plane_failure_reasons,
|
||||
weston_plane_failure_reasons_to_str, dbg);
|
||||
fputs("\n", dbg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ps || drm_mixed_mode_check_underlay(mode, scanout_state, ps->zpos)) {
|
||||
/* visible contains the area that's going to be visible
|
||||
* on screen; add this to the renderer region */
|
||||
pixman_region32_union(renderer_region, renderer_region, &pnode->visible);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_output_state *
|
||||
drm_output_propose_state(struct weston_output *output_base,
|
||||
struct drm_pending_state *pending_state,
|
||||
|
|
@ -1295,7 +1579,7 @@ drm_output_propose_state(struct weston_output *output_base,
|
|||
pixman_region32_t background_region;
|
||||
pixman_region32_t obscured_region;
|
||||
|
||||
int ret;
|
||||
int ret = 0;
|
||||
/* Record the current lowest zpos of the overlay planes */
|
||||
uint64_t current_lowest_zpos_overlay = DRM_PLANE_ZPOS_INVALID_PLANE;
|
||||
/* Record the current lowest zpos of the underlay plane */
|
||||
|
|
@ -1421,7 +1705,7 @@ drm_output_propose_state(struct weston_output *output_base,
|
|||
pixman_region32_init(&obscured_region);
|
||||
|
||||
/* background_region contains the area that is covered by opaque
|
||||
* solid views. If they are black this area can be fully ignored in
|
||||
* solid paint nodes. If they are black this area can be fully ignored in
|
||||
* PLANES_ONLY mode according to the DRM spec:
|
||||
*
|
||||
* "Unless explicitly specified (via CRTC property or otherwise), the
|
||||
|
|
@ -1435,160 +1719,123 @@ drm_output_propose_state(struct weston_output *output_base,
|
|||
* For other colors the same applies if the BACKGROUND_COLOR DRM
|
||||
* property is supported.
|
||||
*
|
||||
* All said views can thus be ignored during plane assignment.
|
||||
* All said paint nodes can thus be ignored during plane assignment.
|
||||
*/
|
||||
pixman_region32_init(&background_region);
|
||||
|
||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY &&
|
||||
!lower_solid_views_to_background_region(output,
|
||||
&visible_pnodes,
|
||||
&last_visible_pnode,
|
||||
&background_region))
|
||||
goto err_region;
|
||||
|
||||
/* Assign paint nodes to planes. */
|
||||
wl_array_for_each(visible_pnode, &visible_pnodes) {
|
||||
struct weston_paint_node *pnode = *visible_pnode;
|
||||
struct drm_plane_state *ps = NULL;
|
||||
bool need_underlay = false;
|
||||
pixman_region32_t tmp;
|
||||
bool renderer_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] evaluating paint node %s for plane "
|
||||
"assignment on output %s (%lu)\n",
|
||||
pnode->internal_name, output->base.name,
|
||||
(unsigned long) output->base.id);
|
||||
|
||||
if (!b->gbm)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_GBM;
|
||||
|
||||
if (!weston_paint_node_has_valid_buffer(pnode))
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_BUFFER;
|
||||
|
||||
if (pnode->draw_solid)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_SOLID_SURFACE;
|
||||
|
||||
if (pnode->output->color_effect)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OUTPUT_COLOR_EFFECT;
|
||||
|
||||
if (pnode->surf_xform.transform && (!device->color_pipeline_supported ||
|
||||
!pnode->output->from_blend_to_output_by_backend))
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_NO_COLOR_TRANSFORM;
|
||||
|
||||
/* Since we process views from top to bottom, we know that if
|
||||
* the view intersects the calculated renderer region, it must
|
||||
* be part of, or occluded by, it, and cannot go on an overlay
|
||||
* plane. */
|
||||
pixman_region32_init(&tmp);
|
||||
pixman_region32_intersect(&tmp, &renderer_region,
|
||||
&pnode->clipped_view);
|
||||
if (pixman_region32_not_empty(&tmp)) {
|
||||
if (output->has_underlay) {
|
||||
need_underlay = true;
|
||||
} else {
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OCCLUDED_BY_RENDERER;
|
||||
drm_debug(b, "\t\t\t\t[paint node] not assigning paint node %s to a "
|
||||
"plane (occluded by renderer views), current lowest "
|
||||
"zpos change to %"PRIu64"\n", pnode->internal_name,
|
||||
current_lowest_zpos_underlay);
|
||||
}
|
||||
}
|
||||
pixman_region32_fini(&tmp);
|
||||
|
||||
/* If need_underlay, but view contains alpha, then it needs to
|
||||
* be rendered. Only fully-opaque views can go on an underlay.
|
||||
*/
|
||||
if (need_underlay && !pnode->is_fully_opaque)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_OCCLUDED_BY_RENDERER;
|
||||
|
||||
/* In case of enforced mode of content-protection do not
|
||||
* assign planes for a protected surface on an unsecured output.
|
||||
*/
|
||||
if (pnode->censored)
|
||||
pnode->try_view_on_plane_failure_reasons |=
|
||||
FAILURE_REASONS_INADEQUATE_CONTENT_PROTECTION;
|
||||
|
||||
if (pnode->surface->tear_control)
|
||||
state->tear &= pnode->surface->tear_control->may_tear;
|
||||
else
|
||||
state->tear = 0;
|
||||
|
||||
/* Now try to place it on a plane if we can. */
|
||||
if (!pnode->try_view_on_plane_failure_reasons) {
|
||||
pixman_region32_t obscured_or_background_region;
|
||||
|
||||
drm_debug(b, "\t\t\t[plane] started with zpos %"PRIu64"\n",
|
||||
need_underlay ? current_lowest_zpos_underlay :
|
||||
current_lowest_zpos_overlay);
|
||||
|
||||
pixman_region32_init(&obscured_or_background_region);
|
||||
if (pnode == last_visible_pnode) {
|
||||
pixman_region32_union(&obscured_or_background_region,
|
||||
&background_region,
|
||||
&obscured_region);
|
||||
if (pixman_region32_not_empty (&obscured_or_background_region))
|
||||
drm_debug(b, "\t\t\t[plane] adding background region\n");
|
||||
}
|
||||
|
||||
ps = drm_output_find_plane_for_paint_node(state, pnode, mode,
|
||||
scanout_state,
|
||||
&obscured_or_background_region,
|
||||
current_lowest_zpos_overlay,
|
||||
current_lowest_zpos_underlay,
|
||||
need_underlay);
|
||||
|
||||
pixman_region32_fini(&obscured_or_background_region);
|
||||
}
|
||||
|
||||
if (ps) {
|
||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY &&
|
||||
ps->plane->type == WDRM_PLANE_TYPE_OVERLAY) {
|
||||
pixman_region32_union(&obscured_region,
|
||||
&obscured_region,
|
||||
weston_paint_node_get_opaque_region (pnode));
|
||||
}
|
||||
|
||||
if (drm_mixed_mode_check_underlay(mode, scanout_state, ps->zpos))
|
||||
current_lowest_zpos_underlay = ps->zpos;
|
||||
else
|
||||
current_lowest_zpos_overlay = ps->zpos;
|
||||
drm_debug(b, "\t\t\t[plane] next overlay zpos to use %"PRIu64","
|
||||
" next underlay zpos to use %"PRIu64"\n",
|
||||
current_lowest_zpos_overlay,
|
||||
current_lowest_zpos_underlay);
|
||||
} else if (!ps && !renderer_ok) {
|
||||
drm_debug(b, "\t\t[paint node] failing state generation: "
|
||||
"placing paint node %s to renderer not allowed\n",
|
||||
pnode->internal_name);
|
||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY) {
|
||||
bool solid_pnodes_to_bg =
|
||||
try_solid_pnodes_to_background(output, &visible_pnodes,
|
||||
&last_visible_pnode, &background_region);
|
||||
if (!solid_pnodes_to_bg)
|
||||
goto err_region;
|
||||
} else if (!ps) {
|
||||
FILE *dbg = weston_log_scope_stream(b->debug);
|
||||
|
||||
if (dbg) {
|
||||
fprintf(dbg, "\t\t\t\t[paint node] paint node %s will be placed on the renderer: ",
|
||||
pnode->internal_name);
|
||||
bits_to_str_stream(pnode->try_view_on_plane_failure_reasons,
|
||||
weston_plane_failure_reasons_to_str, dbg);
|
||||
fputs("\n", dbg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ps || drm_mixed_mode_check_underlay(mode, scanout_state, ps->zpos)) {
|
||||
/* visible contains the area that's going to be visible
|
||||
* on screen; add this to the renderer region */
|
||||
pixman_region32_union(&renderer_region,
|
||||
&renderer_region,
|
||||
&pnode->visible);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_MIXED) {
|
||||
struct wl_array pnodes_with_direct_display;
|
||||
struct wl_array pnodes_remaining;
|
||||
struct wl_array pnodes_above_direct_display;
|
||||
|
||||
unsigned int count_pnodes_dd = 0;
|
||||
unsigned int count_pnodes_above_dd = 0;
|
||||
|
||||
wl_array_init(&pnodes_with_direct_display);
|
||||
wl_array_init(&pnodes_remaining);
|
||||
wl_array_init(&pnodes_above_direct_display);
|
||||
|
||||
filter_pnodes_with_direct_display(output, &visible_pnodes,
|
||||
&pnodes_with_direct_display,
|
||||
&pnodes_remaining);
|
||||
|
||||
filter_pnodes_above_direct_display(output, &visible_pnodes,
|
||||
&pnodes_with_direct_display,
|
||||
&pnodes_above_direct_display);
|
||||
|
||||
/* we might have the same paint nodes in
|
||||
* pnodes_above_direct_display and in pnodes_remaining as we
|
||||
* are searching for paint nodes above the direct display ones
|
||||
* in all visible_pnodes so a paint node above direct-display
|
||||
* would might also be in pnodes_remaining */
|
||||
filter_pnodes_duplicates(output, &pnodes_remaining,
|
||||
&pnodes_above_direct_display);
|
||||
|
||||
count_pnodes_dd = pnodes_with_direct_display.size /
|
||||
sizeof(struct weston_paint_node *);
|
||||
count_pnodes_above_dd = pnodes_above_direct_display.size /
|
||||
sizeof(struct weston_paint_node *);
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] visible paint nodes\n");
|
||||
paint_node_print_array(b, &visible_pnodes);
|
||||
|
||||
if (count_pnodes_dd) {
|
||||
drm_debug(b, "\t\t\t[paint node] pnodes direct display\n");
|
||||
paint_node_print_array(b, &pnodes_with_direct_display);
|
||||
|
||||
if (count_pnodes_above_dd && !output->has_underlay) {
|
||||
drm_debug(b, "\t\t\t[paint node] pnodes above "
|
||||
"direct display\n");
|
||||
paint_node_print_array(b, &pnodes_above_direct_display);
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] walking above "
|
||||
"direct display paint node list\n");
|
||||
ret = walk_paint_nodes(&renderer_region, &obscured_region,
|
||||
&background_region, scanout_state,
|
||||
state, mode,
|
||||
current_lowest_zpos_underlay,
|
||||
current_lowest_zpos_overlay,
|
||||
output,
|
||||
&pnodes_above_direct_display,
|
||||
last_visible_pnode);
|
||||
if (ret) {
|
||||
wl_array_release(&pnodes_with_direct_display);
|
||||
wl_array_release(&pnodes_above_direct_display);
|
||||
wl_array_release(&pnodes_remaining);
|
||||
goto err_region;
|
||||
}
|
||||
}
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] walking direct display "
|
||||
"paint node list\n");
|
||||
|
||||
ret = walk_paint_nodes(&renderer_region, &obscured_region,
|
||||
&background_region, scanout_state,
|
||||
state, mode,
|
||||
current_lowest_zpos_underlay,
|
||||
current_lowest_zpos_overlay,
|
||||
output,
|
||||
&pnodes_with_direct_display,
|
||||
last_visible_pnode);
|
||||
if (ret) {
|
||||
wl_array_release(&pnodes_with_direct_display);
|
||||
wl_array_release(&pnodes_above_direct_display);
|
||||
wl_array_release(&pnodes_remaining);
|
||||
goto err_region;
|
||||
}
|
||||
|
||||
/* replace visible pnodes with remaining pnodes to
|
||||
* avoid going over them again */
|
||||
wl_array_copy(&visible_pnodes, &pnodes_remaining);
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] remaining visible paint nodes\n");
|
||||
paint_node_print_array(b, &visible_pnodes);
|
||||
}
|
||||
|
||||
wl_array_release(&pnodes_with_direct_display);
|
||||
wl_array_release(&pnodes_above_direct_display);
|
||||
wl_array_release(&pnodes_remaining);
|
||||
}
|
||||
|
||||
drm_debug(b, "\t\t\t[paint node] walking visible paint node list\n");
|
||||
ret = walk_paint_nodes(&renderer_region, &obscured_region,
|
||||
&background_region, scanout_state, state,
|
||||
mode,
|
||||
current_lowest_zpos_underlay,
|
||||
current_lowest_zpos_overlay, output,
|
||||
&visible_pnodes,
|
||||
last_visible_pnode);
|
||||
if (ret)
|
||||
goto err_region;
|
||||
|
||||
pixman_region32_fini(&renderer_region);
|
||||
pixman_region32_fini(&obscured_region);
|
||||
pixman_region32_fini(&background_region);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue