On Tue, 10 Jul 2018 18:58:44 +0100
Daniel Stone <dani...@collabora.com> wrote:

> The atomic API can allow us to test state before we apply it, to see if
> it will be valid. Use this when we construct a plane configuration, to
> see if it has a chance of ever working. If not, we can fail
> assign_planes early.
> 
> This will be used in later patches to incrementally build state by
> proposing and testing potential configurations one at a time.
> 
> Signed-off-by: Daniel Stone <dani...@collabora.com>
> Tested-by: Emre Ucan <eu...@de.adit-jv.com>
> ---
>  libweston/compositor-drm.c | 37 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 28a580cd2..f7a364837 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -260,6 +260,7 @@ enum drm_output_state_duplicate_mode {
>  enum drm_state_apply_mode {
>       DRM_STATE_APPLY_SYNC, /**< state fully processed */
>       DRM_STATE_APPLY_ASYNC, /**< state pending event delivery */
> +     DRM_STATE_TEST_ONLY, /**< test if the state can be applied */
>  };
>  
>  struct drm_backend {
> @@ -1822,6 +1823,7 @@ drm_pending_state_get_output(struct drm_pending_state 
> *pending_state,
>  }
>  
>  static int drm_pending_state_apply_sync(struct drm_pending_state *state);
> +static int drm_pending_state_test(struct drm_pending_state *state);
>  
>  /**
>   * Mark a drm_output_state (the output's last state) as complete. This 
> handles
> @@ -2610,9 +2612,16 @@ drm_pending_state_apply_atomic(struct 
> drm_pending_state *pending_state,
>       case DRM_STATE_APPLY_ASYNC:
>               flags |= DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
>               break;
> +     case DRM_STATE_TEST_ONLY:
> +             flags |= DRM_MODE_ATOMIC_TEST_ONLY;
> +             break;
>       }
>  
>       ret = drmModeAtomicCommit(b->drm.fd, req, flags, b);
> +
> +     if (mode == DRM_STATE_TEST_ONLY)
> +             return ret;

This leaks at least 'req'.

> +
>       if (ret != 0) {
>               weston_log("atomic: couldn't commit new state: %m\n");
>               goto out;
> @@ -2640,6 +2649,22 @@ out:
>   *
>   * Unconditionally takes ownership of pending_state, and clears 
> state_invalid.
>   */

The documentation above is misplaced now. drm_pending_state_test()
needs new docs, particularly about what it is supposed to do with
pending_state.

An idea for the future: maybe 'req' could be cached with the
pending_state if it passed the test? To avoid having to build the same
working 'req' twice every frame.


Thanks,
pq

> +static int
> +drm_pending_state_test(struct drm_pending_state *pending_state)
> +{
> +#ifdef HAVE_DRM_ATOMIC
> +     struct drm_backend *b = pending_state->backend;
> +
> +     if (b->atomic_modeset)
> +             return drm_pending_state_apply_atomic(pending_state,
> +                                                   DRM_STATE_TEST_ONLY);
> +#endif
> +
> +     /* We have no way to test state before application on the legacy
> +      * modesetting API, so just claim it succeeded. */
> +     return 0;
> +}
> +
>  static int
>  drm_pending_state_apply(struct drm_pending_state *pending_state)
>  {
> @@ -3271,6 +3296,7 @@ drm_output_propose_state(struct weston_output 
> *output_base,
>       struct weston_view *ev;
>       pixman_region32_t surface_overlap, renderer_region, occluded_region;
>       bool planes_ok = (mode != DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY);
> +     int ret;
>  
>       assert(!output->state_last);
>       state = drm_output_state_duplicate(output->state_cur,
> @@ -3388,7 +3414,18 @@ drm_output_propose_state(struct weston_output 
> *output_base,
>       pixman_region32_fini(&renderer_region);
>       pixman_region32_fini(&occluded_region);
>  
> +     /* Check to see if this state will actually work. */
> +     ret = drm_pending_state_test(state->pending_state);
> +     if (ret != 0)
> +             goto err;
> +
>       return state;
> +
> +err:
> +     pixman_region32_fini(&renderer_region);
> +     pixman_region32_fini(&occluded_region);
> +     drm_output_state_free(state);
> +     return NULL;
>  }
>  
>  static void

Attachment: pgpgIPnHQRlkT.pgp
Description: OpenPGP digital signature

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to