Adding some folks on CC for broader distribution.

On Tue, Jan 9, 2018 at 3:52 PM, Lepton Wu <lep...@chromium.org> wrote:
> 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