On Fri,  9 Dec 2016 19:57:30 +0000
Daniel Stone <dani...@collabora.com> wrote:

> Rather than magically trying to infer what the buffer is and what we
> should do with it when we go to destroy it, add an explicit type
> instead.
> 
> Differential Revision: https://phabricator.freedesktop.org/D1488
> 
> Signed-off-by: Daniel Stone <dani...@collabora.com>
> ---
>  libweston/compositor-drm.c | 50 
> +++++++++++++++++++++++++++++-----------------
>  1 file changed, 32 insertions(+), 18 deletions(-)
> 
> diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
> index 4ef7343..217db32 100644
> --- a/libweston/compositor-drm.c
> +++ b/libweston/compositor-drm.c
> @@ -129,11 +129,19 @@ struct drm_mode {
>       drmModeModeInfo mode_info;
>  };
>  
> +enum drm_fb_type {
> +     BUFFER_INVALID = 0, /**< never used */
> +     BUFFER_CLIENT, /**< directly sourced from client */
> +     BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
> +     BUFFER_GBM_SURFACE, /**< internal EGL rendering */
> +};

Hi,

cool.

> +
>  struct drm_fb {
> +     enum drm_fb_type type;
> +
>       uint32_t fb_id, stride, handle, size;
>       int width, height;
>       int fd;
> -     int is_client_buffer;
>       struct weston_buffer_reference buffer_ref;
>  
>       /* Used by gbm fbs */
> @@ -290,6 +298,7 @@ drm_fb_create_dumb(struct drm_backend *b, int width, int 
> height,
>       if (ret)
>               goto err_fb;
>  
> +     fb->type = BUFFER_PIXMAN_DUMB;
>       fb->handle = create_arg.handle;
>       fb->stride = create_arg.pitch;
>       fb->size = create_arg.size;
> @@ -352,6 +361,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
>  {
>       struct drm_mode_destroy_dumb destroy_arg;
>  
> +     assert(fb->type == BUFFER_PIXMAN_DUMB);
> +
>       if (!fb->map)
>               return;
>  
> @@ -370,8 +381,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
>  }
>  
>  static struct drm_fb *
> -drm_fb_get_from_bo(struct gbm_bo *bo,
> -                struct drm_backend *backend, uint32_t format)
> +drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
> +                uint32_t format, enum drm_fb_type type)
>  {
>       struct drm_fb *fb = gbm_bo_get_user_data(bo);
>       uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };

For the shortcut return:
assert(type == fb->type)?

> @@ -384,6 +395,7 @@ drm_fb_get_from_bo(struct gbm_bo *bo,
>       if (fb == NULL)
>               return NULL;
>  
> +     fb->type = type;
>       fb->bo = bo;
>  
>       fb->width = gbm_bo_get_width(bo);
> @@ -440,9 +452,6 @@ static void
>  drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
>  {
>       assert(fb->buffer_ref.buffer == NULL);
> -
> -     fb->is_client_buffer = 1;
> -

assert(fb->type == BUFFER_CLIENT)?

>       weston_buffer_reference(&fb->buffer_ref, buffer);
>  }
>  
> @@ -452,15 +461,19 @@ drm_output_release_fb(struct drm_output *output, struct 
> drm_fb *fb)
>       if (!fb)
>               return;
>  
> -     if (fb->map &&
> -            (fb != output->dumb[0] && fb != output->dumb[1])) {
> -             drm_fb_destroy_dumb(fb);

This piece sent me into a recursive "well, actually..." loop.

It looked like dead code at first hand, as this gets hit when
output->dumb and fb don't match. When would that be? I would guess when
video mode changed.

I think changing resolutions would hit this path, when flipping to a
new dumb buffer of a different size than one coming out of scanout
which cannot be destroyed until pageflip completed.

Except I am wrong in a couple of ways: destroying the buffer is fine,
the kernel will keep it referenced as long as necessary anyway. And,
drm_output_switch_mode() does destroy everything immediately.

So this bit is ok. Unless there is a third well-actually.

> -     } else if (fb->bo) {
> -             if (fb->is_client_buffer)
> -                     gbm_bo_destroy(fb->bo);
> -             else
> -                     gbm_surface_release_buffer(output->gbm_surface,
> -                                                fb->bo);
> +     switch (fb->type) {
> +     case BUFFER_PIXMAN_DUMB:
> +             /* nothing: pixman buffers are destroyed manually */
> +             break;
> +     case BUFFER_CLIENT:
> +             gbm_bo_destroy(fb->bo);
> +             break;
> +     case BUFFER_GBM_SURFACE:
> +             gbm_surface_release_buffer(output->gbm_surface, fb->bo);
> +             break;
> +     default:
> +             assert(NULL);
> +             break;
>       }
>  }
>  
> @@ -559,7 +572,7 @@ drm_output_prepare_scanout_view(struct drm_output *output,
>               return NULL;
>       }
>  
> -     output->next = drm_fb_get_from_bo(bo, b, format);
> +     output->next = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
>       if (!output->next) {
>               gbm_bo_destroy(bo);
>               return NULL;
> @@ -585,7 +598,8 @@ drm_output_render_gl(struct drm_output *output, 
> pixman_region32_t *damage)
>               return;
>       }
>  
> -     output->next = drm_fb_get_from_bo(bo, b, output->gbm_format);
> +     output->next = drm_fb_get_from_bo(bo, b, output->gbm_format,
> +                                       BUFFER_GBM_SURFACE);
>       if (!output->next) {
>               weston_log("failed to get drm_fb for bo\n");
>               gbm_surface_release_buffer(output->gbm_surface, bo);
> @@ -1054,7 +1068,7 @@ drm_output_prepare_overlay_view(struct drm_output 
> *output,
>               return NULL;
>       }
>  
> -     s->next = drm_fb_get_from_bo(bo, b, format);
> +     s->next = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
>       if (!s->next) {
>               gbm_bo_destroy(bo);
>               return NULL;

Yeah, it looks fine, I only proposed some added asserts which are
non-essential, so:
Reviewed-by: Pekka Paalanen <pekka.paala...@collabora.co.uk>


Thanks,
pq

Attachment: pgpN81j92Azpy.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