Gentle ping. Thanks.

On Wed, Dec 27, 2017 at 11:35 PM, Lepton Wu <lep...@chromium.org> wrote:
> v2: address comments from Tomasz Figa
>    a) Add more check for plane size.
>    b) Avoid duplicated mapping and leaked mapping.
>    c) Other minor changes.
>
> Signed-off-by: Lepton Wu <lep...@chromium.org>
>
> Change-Id: I0863f522976cc8863d6e95492d9346df35c066ec
> ---
>  src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 179 
> +++++++++++++++-------
>  1 file changed, 126 insertions(+), 53 deletions(-)
>
> diff --git a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c 
> b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> index 22e1c936ac5..69c05197081 100644
> --- a/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> +++ b/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
> @@ -59,20 +59,29 @@
>  #define DEBUG_PRINT(msg, ...)
>  #endif
>
> +struct kms_sw_displaytarget;
>
> -struct kms_sw_displaytarget
> -{
> -   enum pipe_format format;
> +struct kms_sw_plane {
>     unsigned width;
>     unsigned height;
>     unsigned stride;
> +   unsigned offset;
> +   struct kms_sw_displaytarget* dt;
> +   struct list_head link;
> +};
> +
> +struct kms_sw_displaytarget
> +{
> +   enum pipe_format format;
>     unsigned size;
>
>     uint32_t handle;
>     void *mapped;
> +   void *ro_mapped;
>
>     int ref_count;
>     struct list_head link;
> +   struct list_head planes;
>  };
>
>  struct kms_sw_winsys
> @@ -83,10 +92,10 @@ struct kms_sw_winsys
>     struct list_head bo_list;
>  };
>
> -static inline struct kms_sw_displaytarget *
> -kms_sw_displaytarget( struct sw_displaytarget *dt )
> +static inline struct kms_sw_plane *
> +kms_sw_plane( struct sw_displaytarget *dt )
>  {
> -   return (struct kms_sw_displaytarget *)dt;
> +   return (struct kms_sw_plane *)dt;
>  }
>
>  static inline struct kms_sw_winsys *
> @@ -105,6 +114,42 @@ kms_sw_is_displaytarget_format_supported( struct 
> sw_winsys *ws,
>     return TRUE;
>  }
>
> +static struct kms_sw_plane *get_plane(struct kms_sw_displaytarget *kms_sw_dt,
> +                                      enum pipe_format format,
> +                                      unsigned width, unsigned height,
> +                                      unsigned stride, unsigned offset) {
> +   struct kms_sw_plane * tmp, * plane = NULL;
> +   if (offset + util_format_get_2d_size(format, stride, height) >
> +       kms_sw_dt->size) {
> +      DEBUG_PRINT("KMS-DEBUG: plane too big. format: %d stride: %d height: 
> %d "
> +                  "offset: %d size:%d\n", format, stride, height, offset,
> +                  kms_sw_dt->size);
> +      return NULL;
> +   }
> +   LIST_FOR_EACH_ENTRY(tmp, &kms_sw_dt->planes, link) {
> +      if (tmp->offset == offset) {
> +         plane = tmp;
> +         break;
> +      }
> +   }
> +   if (plane) {
> +      assert(plane->width == width);
> +      assert(plane->height == height);
> +      assert(plane->stride == stride);
> +      assert(plane->dt == kms_sw_dt);
> +   } else {
> +      plane = CALLOC_STRUCT(kms_sw_plane);
> +      if (plane == NULL) return NULL;
> +      plane->width = width;
> +      plane->height = height;
> +      plane->stride = stride;
> +      plane->offset = offset;
> +      plane->dt = kms_sw_dt;
> +      list_add(&plane->link, &kms_sw_dt->planes);
> +   }
> +   return plane;
> +}
> +
>  static struct sw_displaytarget *
>  kms_sw_displaytarget_create(struct sw_winsys *ws,
>                              unsigned tex_usage,
> @@ -124,11 +169,10 @@ kms_sw_displaytarget_create(struct sw_winsys *ws,
>     if (!kms_sw_dt)
>        goto no_dt;
>
> +   list_inithead(&kms_sw_dt->planes);
>     kms_sw_dt->ref_count = 1;
>
>     kms_sw_dt->format = format;
> -   kms_sw_dt->width = width;
> -   kms_sw_dt->height = height;
>
>     memset(&create_req, 0, sizeof(create_req));
>     create_req.bpp = 32;
> @@ -138,17 +182,19 @@ kms_sw_displaytarget_create(struct sw_winsys *ws,
>     if (ret)
>        goto free_bo;
>
> -   kms_sw_dt->stride = create_req.pitch;
>     kms_sw_dt->size = create_req.size;
>     kms_sw_dt->handle = create_req.handle;
> +   struct kms_sw_plane* plane = get_plane(kms_sw_dt, format, width, height,
> +                                          create_req.pitch, 0);
> +   if (plane == NULL)
> +      goto free_bo;
>
>     list_add(&kms_sw_dt->link, &kms_sw->bo_list);
>
>     DEBUG_PRINT("KMS-DEBUG: created buffer %u (size %u)\n", 
> kms_sw_dt->handle, kms_sw_dt->size);
>
> -   *stride = kms_sw_dt->stride;
> -   return (struct sw_displaytarget *)kms_sw_dt;
> -
> +   *stride = create_req.pitch;
> +   return (struct sw_displaytarget *) plane;
>   free_bo:
>     memset(&destroy_req, 0, sizeof destroy_req);
>     destroy_req.handle = create_req.handle;
> @@ -163,13 +209,19 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws,
>                               struct sw_displaytarget *dt)
>  {
>     struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
> -   struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
> +   struct kms_sw_plane *plane = kms_sw_plane(dt);
> +   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;
>     struct drm_mode_destroy_dumb destroy_req;
>
>     kms_sw_dt->ref_count --;
>     if (kms_sw_dt->ref_count > 0)
>        return;
>
> +   if (kms_sw_dt->ro_mapped)
> +     munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size);
> +   if (kms_sw_dt->mapped)
> +     munmap(kms_sw_dt->mapped, kms_sw_dt->size);
> +
>     memset(&destroy_req, 0, sizeof destroy_req);
>     destroy_req.handle = kms_sw_dt->handle;
>     drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_req);
> @@ -178,6 +230,10 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws,
>
>     DEBUG_PRINT("KMS-DEBUG: destroyed buffer %u\n", kms_sw_dt->handle);
>
> +   struct kms_sw_plane * tmp;
> +   LIST_FOR_EACH_ENTRY_SAFE(plane, tmp, &kms_sw_dt->planes, link) {
> +      FREE(plane);
> +   }
>     FREE(kms_sw_dt);
>  }
>
> @@ -187,7 +243,8 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
>                           unsigned flags)
>  {
>     struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
> -   struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
> +   struct kms_sw_plane *plane = kms_sw_plane(dt);
> +   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;
>     struct drm_mode_map_dumb map_req;
>     int prot, ret;
>
> @@ -198,16 +255,20 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
>        return NULL;
>
>     prot = (flags == PIPE_TRANSFER_READ) ? PROT_READ : (PROT_READ | 
> PROT_WRITE);
> -   kms_sw_dt->mapped = mmap(0, kms_sw_dt->size, prot, MAP_SHARED,
> -                            kms_sw->fd, map_req.offset);
> -
> -   if (kms_sw_dt->mapped == MAP_FAILED)
> -      return NULL;
> +   void **ptr = (flags == PIPE_TRANSFER_READ) ? &kms_sw_dt->ro_mapped : 
> &kms_sw_dt->mapped;
> +   if (*ptr == NULL) {
> +      void * tmp = mmap(0, kms_sw_dt->size, prot, MAP_SHARED,
> +                       kms_sw->fd, map_req.offset);
> +      if (tmp == MAP_FAILED)
> +         return NULL;
> +      *ptr = tmp;
> +   }
>
> -   DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p\n",
> -         kms_sw_dt->handle, kms_sw_dt->size, kms_sw_dt->mapped);
> +   DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p %dx%d \n",
> +         kms_sw_dt->handle, kms_sw_dt->size, *ptr,
> +         plane->width, plane->height);
>
> -   return kms_sw_dt->mapped;
> +   return *ptr + plane->offset;
>  }
>
>  static struct kms_sw_displaytarget *
> @@ -230,10 +291,11 @@ kms_sw_displaytarget_find_and_ref(struct kms_sw_winsys 
> *kms_sw,
>     return NULL;
>  }
>
> -static struct kms_sw_displaytarget *
> +static struct kms_sw_plane *
>  kms_sw_displaytarget_add_from_prime(struct kms_sw_winsys *kms_sw, int fd,
> +                                    enum pipe_format format,
>                                      unsigned width, unsigned height,
> -                                    unsigned stride)
> +                                    unsigned stride, unsigned offset)
>  {
>     uint32_t handle = -1;
>     struct kms_sw_displaytarget * kms_sw_dt;
> @@ -245,13 +307,19 @@ kms_sw_displaytarget_add_from_prime(struct 
> kms_sw_winsys *kms_sw, int fd,
>        return NULL;
>
>     kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, handle);
> -   if (kms_sw_dt)
> -      return kms_sw_dt;
> +   struct kms_sw_plane * plane = NULL;
> +   if (kms_sw_dt) {
> +      plane = get_plane(kms_sw_dt, format, width, height, stride, offset);
> +      if (plane == NULL)
> +         kms_sw_dt->ref_count --;
> +      return plane;
> +   }
>
>     kms_sw_dt = CALLOC_STRUCT(kms_sw_displaytarget);
>     if (!kms_sw_dt)
>        return NULL;
>
> +   list_inithead(&kms_sw_dt->planes);
>     off_t lseek_ret = lseek(fd, 0, SEEK_END);
>     if (lseek_ret == -1) {
>        FREE(kms_sw_dt);
> @@ -260,27 +328,27 @@ kms_sw_displaytarget_add_from_prime(struct 
> kms_sw_winsys *kms_sw, int fd,
>     kms_sw_dt->size = lseek_ret;
>     kms_sw_dt->ref_count = 1;
>     kms_sw_dt->handle = handle;
> -   kms_sw_dt->width = width;
> -   kms_sw_dt->height = height;
> -   kms_sw_dt->stride = stride;
>
>     lseek(fd, 0, SEEK_SET);
> +   plane = get_plane(kms_sw_dt, format, width, height, stride, offset);
> +   if (plane == NULL) {
> +      FREE(kms_sw_dt);
> +      return NULL;
> +   }
>
>     list_add(&kms_sw_dt->link, &kms_sw->bo_list);
>
> -   return kms_sw_dt;
> +   return plane;
>  }
>
>  static void
>  kms_sw_displaytarget_unmap(struct sw_winsys *ws,
>                             struct sw_displaytarget *dt)
>  {
> -   struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
> +   struct kms_sw_plane * plane = kms_sw_plane(dt);
> +   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;
>
> -   DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", 
> kms_sw_dt->handle, kms_sw_dt->mapped);
> -
> -   munmap(kms_sw_dt->mapped, kms_sw_dt->size);
> -   kms_sw_dt->mapped = NULL;
> +   DEBUG_PRINT("KMS-DEBUG: ignore unmap buffer %u \n", kms_sw_dt->handle);
>  }
>
>  static struct sw_displaytarget *
> @@ -291,30 +359,34 @@ kms_sw_displaytarget_from_handle(struct sw_winsys *ws,
>  {
>     struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);
>     struct kms_sw_displaytarget *kms_sw_dt;
> +   struct kms_sw_plane *kms_sw_pl;
>
>     assert(whandle->type == DRM_API_HANDLE_TYPE_KMS ||
>            whandle->type == DRM_API_HANDLE_TYPE_FD);
>
> -   if (whandle->offset != 0) {
> -      DEBUG_PRINT("KMS-DEBUG: attempt to import unsupported winsys offset 
> %d\n",
> -                  whandle->offset);
> -      return NULL;
> -   }
> -
>     switch(whandle->type) {
>     case DRM_API_HANDLE_TYPE_FD:
> -      kms_sw_dt = kms_sw_displaytarget_add_from_prime(kms_sw, 
> whandle->handle,
> +      kms_sw_pl = kms_sw_displaytarget_add_from_prime(kms_sw, 
> whandle->handle,
> +                                                      templ->format,
>                                                        templ->width0,
>                                                        templ->height0,
> -                                                      whandle->stride);
> -      if (kms_sw_dt)
> -         *stride = kms_sw_dt->stride;
> -      return (struct sw_displaytarget *)kms_sw_dt;
> +                                                      whandle->stride,
> +                                                      whandle->offset);
> +      if (kms_sw_pl) {
> +         *stride = kms_sw_pl->stride;
> +      }
> +      return (struct sw_displaytarget *)kms_sw_pl;
>     case DRM_API_HANDLE_TYPE_KMS:
>        kms_sw_dt = kms_sw_displaytarget_find_and_ref(kms_sw, whandle->handle);
>        if (kms_sw_dt) {
> -         *stride = kms_sw_dt->stride;
> -         return (struct sw_displaytarget *)kms_sw_dt;
> +         struct kms_sw_plane * plane;
> +         LIST_FOR_EACH_ENTRY(plane, &kms_sw_dt->planes, link) {
> +            if (whandle->offset == plane->offset) {
> +               *stride = plane->stride;
> +               return  (struct sw_displaytarget *)plane;
> +            }
> +         }
> +         kms_sw_dt->ref_count --;
>        }
>        /* fallthrough */
>     default:
> @@ -331,19 +403,20 @@ kms_sw_displaytarget_get_handle(struct sw_winsys 
> *winsys,
>                                  struct winsys_handle *whandle)
>  {
>     struct kms_sw_winsys *kms_sw = kms_sw_winsys(winsys);
> -   struct kms_sw_displaytarget *kms_sw_dt = kms_sw_displaytarget(dt);
> +   struct kms_sw_plane *plane = kms_sw_plane(dt);
> +   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;
>
>     switch(whandle->type) {
>     case DRM_API_HANDLE_TYPE_KMS:
>        whandle->handle = kms_sw_dt->handle;
> -      whandle->stride = kms_sw_dt->stride;
> -      whandle->offset = 0;
> +      whandle->stride = plane->stride;
> +      whandle->offset = plane->offset;
>        return TRUE;
>     case DRM_API_HANDLE_TYPE_FD:
>        if (!drmPrimeHandleToFD(kms_sw->fd, kms_sw_dt->handle,
>                               DRM_CLOEXEC, (int*)&whandle->handle)) {
> -         whandle->stride = kms_sw_dt->stride;
> -         whandle->offset = 0;
> +         whandle->stride = plane->stride;
> +         whandle->offset = plane->offset;
>           return TRUE;
>        }
>        /* fallthrough */
> --
> 2.15.1.620.gb9897f4670-goog
>
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to