backend-drm: Remove separate zpos_plane list
When we introduced support for variable zpos, we did so by filtering the list of acceptable planes and then creating a separate zpos-ordered list. Now that the planes are already zpos-sorted in the backend list, and we have more early filtering, we can replace this with a single plane-list walk. Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
@@ -394,16 +394,6 @@ struct drm_output_state {
|
|||||||
struct wl_list plane_list;
|
struct wl_list plane_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* An instance of this class is created each time we believe we have a plane
|
|
||||||
* suitable to be used by a view as a direct scan-out. The list is initialized
|
|
||||||
* and populated locally.
|
|
||||||
*/
|
|
||||||
struct drm_plane_zpos {
|
|
||||||
struct drm_plane *plane;
|
|
||||||
struct wl_list link; /**< :candidate_plane_zpos_list */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plane state holds the dynamic state for a plane: where it is positioned,
|
* Plane state holds the dynamic state for a plane: where it is positioned,
|
||||||
* and which buffer it is currently displaying.
|
* and which buffer it is currently displaying.
|
||||||
|
|||||||
@@ -63,39 +63,6 @@ drm_propose_state_mode_to_string(enum drm_output_propose_state_mode mode)
|
|||||||
return drm_output_propose_state_mode_as_string[mode];
|
return drm_output_propose_state_mode_as_string[mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
drm_output_add_zpos_plane(struct drm_plane *plane, struct wl_list *planes)
|
|
||||||
{
|
|
||||||
struct drm_backend *b = plane->backend;
|
|
||||||
struct drm_plane_zpos *tmp;
|
|
||||||
struct drm_plane_zpos *plane_zpos;
|
|
||||||
|
|
||||||
plane_zpos = zalloc(sizeof(*plane_zpos));
|
|
||||||
if (!plane_zpos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
plane_zpos->plane = plane;
|
|
||||||
|
|
||||||
drm_debug(b, "\t\t\t\t[plane] plane %d added to candidate list\n",
|
|
||||||
plane->plane_id);
|
|
||||||
|
|
||||||
wl_list_for_each(tmp, planes, link) {
|
|
||||||
if (tmp->plane->zpos_max > plane_zpos->plane->zpos_max) {
|
|
||||||
wl_list_insert(tmp->link.prev, &plane_zpos->link);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (plane_zpos->link.next == NULL)
|
|
||||||
wl_list_insert(planes->prev, &plane_zpos->link);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drm_output_destroy_zpos_plane(struct drm_plane_zpos *plane_zpos)
|
|
||||||
{
|
|
||||||
wl_list_remove(&plane_zpos->link);
|
|
||||||
free(plane_zpos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
drm_output_check_plane_has_view_assigned(struct drm_plane *plane,
|
drm_output_check_plane_has_view_assigned(struct drm_plane *plane,
|
||||||
struct drm_output_state *output_state)
|
struct drm_output_state *output_state)
|
||||||
@@ -665,14 +632,12 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
|
|
||||||
struct drm_plane_state *ps = NULL;
|
struct drm_plane_state *ps = NULL;
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_plane_zpos *p_zpos, *p_zpos_next;
|
|
||||||
struct wl_list zpos_candidate_list;
|
|
||||||
|
|
||||||
struct weston_buffer *buffer;
|
struct weston_buffer *buffer;
|
||||||
struct wl_shm_buffer *shmbuf;
|
struct wl_shm_buffer *shmbuf;
|
||||||
struct drm_fb *fb = NULL;
|
struct drm_fb *fb = NULL;
|
||||||
|
|
||||||
wl_list_init(&zpos_candidate_list);
|
uint32_t possible_plane_mask = 0;
|
||||||
|
|
||||||
/* check view for valid buffer, doesn't make sense to even try */
|
/* check view for valid buffer, doesn't make sense to even try */
|
||||||
if (!weston_view_has_valid_buffer(ev))
|
if (!weston_view_has_valid_buffer(ev))
|
||||||
@@ -698,6 +663,8 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
ev, buffer->width, buffer->height);
|
ev, buffer->width, buffer->height);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possible_plane_mask = (1 << output->cursor_plane->plane_idx);
|
||||||
} else {
|
} else {
|
||||||
if (mode == DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY) {
|
if (mode == DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY) {
|
||||||
drm_debug(b, "\t\t\t\t[view] not assigning view %p "
|
drm_debug(b, "\t\t\t\t[view] not assigning view %p "
|
||||||
@@ -708,10 +675,23 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
fb = drm_fb_get_from_view(state, ev, try_view_on_plane_failure_reasons);
|
fb = drm_fb_get_from_view(state, ev, try_view_on_plane_failure_reasons);
|
||||||
if (!fb)
|
if (!fb)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
possible_plane_mask = fb->plane_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assemble a list with possible candidates */
|
/* assemble a list with possible candidates */
|
||||||
wl_list_for_each(plane, &b->plane_list, link) {
|
wl_list_for_each(plane, &b->plane_list, link) {
|
||||||
|
const char *p_name = drm_output_get_plane_type_name(plane);
|
||||||
|
uint64_t zpos;
|
||||||
|
|
||||||
|
if (possible_plane_mask == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(possible_plane_mask & (1 << plane->plane_idx)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
possible_plane_mask &= ~(1 << plane->plane_idx);
|
||||||
|
|
||||||
if (plane->type == WDRM_PLANE_TYPE_CURSOR &&
|
if (plane->type == WDRM_PLANE_TYPE_CURSOR &&
|
||||||
(plane != output->cursor_plane || !shmbuf)) {
|
(plane != output->cursor_plane || !shmbuf)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -754,30 +734,6 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plane->type != WDRM_PLANE_TYPE_CURSOR &&
|
|
||||||
(!fb || !(fb->plane_mask & (1 << plane->plane_idx)))) {
|
|
||||||
*try_view_on_plane_failure_reasons |=
|
|
||||||
FAILURE_REASONS_FB_FORMAT_INCOMPATIBLE;
|
|
||||||
drm_debug(b, "\t\t\t\t[plane] not trying plane %d: "
|
|
||||||
"invalid pixel format\n", plane->plane_id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
drm_output_add_zpos_plane(plane, &zpos_candidate_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go over the potential candidate list and try to find a possible
|
|
||||||
* plane suitable for \c ev; start with the highest zpos value of a
|
|
||||||
* plane to maximize our chances, but do note we pass the zpos value
|
|
||||||
* based on current tracked value by \c current_lowest_zpos_in_use */
|
|
||||||
while (!wl_list_empty(&zpos_candidate_list)) {
|
|
||||||
struct drm_plane_zpos *head_p_zpos =
|
|
||||||
wl_container_of(zpos_candidate_list.next,
|
|
||||||
head_p_zpos, link);
|
|
||||||
struct drm_plane *plane = head_p_zpos->plane;
|
|
||||||
const char *p_name = drm_output_get_plane_type_name(plane);
|
|
||||||
uint64_t zpos;
|
|
||||||
|
|
||||||
if (current_lowest_zpos == DRM_PLANE_ZPOS_INVALID_PLANE)
|
if (current_lowest_zpos == DRM_PLANE_ZPOS_INVALID_PLANE)
|
||||||
zpos = plane->zpos_max;
|
zpos = plane->zpos_max;
|
||||||
else
|
else
|
||||||
@@ -789,7 +745,6 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
|
|
||||||
ps = drm_output_try_view_on_plane(plane, state, ev,
|
ps = drm_output_try_view_on_plane(plane, state, ev,
|
||||||
mode, fb, zpos);
|
mode, fb, zpos);
|
||||||
drm_output_destroy_zpos_plane(head_p_zpos);
|
|
||||||
if (ps) {
|
if (ps) {
|
||||||
drm_debug(b, "\t\t\t\t[view] view %p has been placed to "
|
drm_debug(b, "\t\t\t\t[view] view %p has been placed to "
|
||||||
"%s plane with computed zpos %"PRIu64"\n",
|
"%s plane with computed zpos %"PRIu64"\n",
|
||||||
@@ -798,9 +753,8 @@ drm_output_prepare_plane_view(struct drm_output_state *state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_for_each_safe(p_zpos, p_zpos_next, &zpos_candidate_list, link)
|
/* if we have a plane state, it has its own ref to the fb; if not then
|
||||||
drm_output_destroy_zpos_plane(p_zpos);
|
* we drop ours here */
|
||||||
|
|
||||||
drm_fb_unref(fb);
|
drm_fb_unref(fb);
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user