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