compositor-drm: Only assign planes with atomic

Without atomic modesetting, we have no way to know whether or not our
desired configuration is usable. It might fail for a number of reasons:
scaling limits, bandwidth limits, global resource (e.g. decompression)
unit contention, or really just anything.

Not only this, but there is no good way to ensure that our configuration
actually lands together in the same refresh cycle - hence the 'atomic'
in atomic modesetting. Some drivers implement a synchronously blocking
drmModeSetPlane, whereas others return immediately. Using overlay planes
can thus decimate your framerate.

The pre-atomic API is not extensible either, so we need numerous out
clauses: fail if we're cropping or scaling (sometimes), or changing
formats, or fencing, or ...

Now we've had atomic support stable for a couple of releases, just
remove support for doing anything more fancy than displaying our
composited output and a cursor with drivers which don't support atomic
modesetting.

Support for using overlay planes was already disabled by default when
using the legacy API, and required a debug key combination to toggle it
on by flipping the sprites_are_broken variable. We can ensure that we
never try to use it on legacy by simply ignoring the hotkey when in
legacy mode.

Signed-off-by: Daniel Stone <daniels@collabora.com>
dev
Daniel Stone 6 years ago
parent b0e16d4c53
commit 87fab1ca4e
  1. 32
      libweston/backend-drm/drm.c

@ -2025,6 +2025,7 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
pixman_box32_t *extents; pixman_box32_t *extents;
assert(!b->sprites_are_broken); assert(!b->sprites_are_broken);
assert(b->atomic_modeset);
assert(mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY); assert(mode == DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY);
/* Check the view spans exactly the output size, calculated in the /* Check the view spans exactly the output size, calculated in the
@ -2039,8 +2040,7 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
/* If the surface buffer has an in-fence fd, but the plane doesn't /* If the surface buffer has an in-fence fd, but the plane doesn't
* support fences, we can't place the buffer on this plane. */ * support fences, we can't place the buffer on this plane. */
if (ev->surface->acquire_fence_fd >= 0 && if (ev->surface->acquire_fence_fd >= 0 &&
(!b->atomic_modeset || scanout_plane->props[WDRM_PLANE_IN_FENCE_FD].prop_id == 0)
scanout_plane->props[WDRM_PLANE_IN_FENCE_FD].prop_id == 0))
return NULL; return NULL;
fb = drm_fb_get_from_view(output_state, ev); fb = drm_fb_get_from_view(output_state, ev);
@ -2050,12 +2050,6 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
return NULL; return NULL;
} }
/* Can't change formats with just a pageflip */
if (!b->atomic_modeset && fb->format->format != output->gbm_format) {
drm_fb_unref(fb);
return NULL;
}
state = drm_output_state_get_plane(output_state, scanout_plane); state = drm_output_state_get_plane(output_state, scanout_plane);
/* The only way we can already have a buffer in the scanout plane is /* The only way we can already have a buffer in the scanout plane is
@ -2075,13 +2069,6 @@ drm_output_prepare_scanout_view(struct drm_output_state *output_state,
state->dest_h != (unsigned) output->base.current_mode->height) state->dest_h != (unsigned) output->base.current_mode->height)
goto err; goto err;
/* The legacy API does not let us perform cropping or scaling. */
if (!b->atomic_modeset &&
(state->src_x != 0 || state->src_y != 0 ||
state->src_w != state->dest_w << 16 ||
state->src_h != state->dest_h << 16))
goto err;
state->in_fence_fd = ev->surface->acquire_fence_fd; state->in_fence_fd = ev->surface->acquire_fence_fd;
/* In plane-only mode, we don't need to test the state now, as we /* In plane-only mode, we don't need to test the state now, as we
@ -3297,6 +3284,7 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
} availability = NO_PLANES; } availability = NO_PLANES;
assert(!b->sprites_are_broken); assert(!b->sprites_are_broken);
assert(b->atomic_modeset);
fb = drm_fb_get_from_view(output_state, ev); fb = drm_fb_get_from_view(output_state, ev);
if (!fb) { if (!fb) {
@ -3356,22 +3344,12 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
state = NULL; state = NULL;
continue; continue;
} }
if (!b->atomic_modeset &&
(state->src_w != state->dest_w << 16 ||
state->src_h != state->dest_h << 16)) {
drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
"no scaling without atomic\n", ev);
drm_plane_state_put_back(state);
state = NULL;
continue;
}
/* If the surface buffer has an in-fence fd, but the plane /* If the surface buffer has an in-fence fd, but the plane
* doesn't support fences, we can't place the buffer on this * doesn't support fences, we can't place the buffer on this
* plane. */ * plane. */
if (ev->surface->acquire_fence_fd >= 0 && if (ev->surface->acquire_fence_fd >= 0 &&
(!b->atomic_modeset || p->props[WDRM_PLANE_IN_FENCE_FD].prop_id == 0) {
p->props[WDRM_PLANE_IN_FENCE_FD].prop_id == 0)) {
drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: " drm_debug(b, "\t\t\t\t[overlay] not placing view %p on overlay: "
"no in-fence support\n", ev); "no in-fence support\n", ev);
drm_plane_state_put_back(state); drm_plane_state_put_back(state);
@ -7044,6 +7022,8 @@ planes_binding(struct weston_keyboard *keyboard, const struct timespec *time,
b->cursors_are_broken ^= 1; b->cursors_are_broken ^= 1;
break; break;
case KEY_V: case KEY_V:
/* We don't support overlay-plane usage with legacy KMS. */
if (b->atomic_modeset)
b->sprites_are_broken ^= 1; b->sprites_are_broken ^= 1;
break; break;
case KEY_O: case KEY_O:

Loading…
Cancel
Save