diff options
Diffstat (limited to 'src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c')
-rw-r--r-- | src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 20 |
1 files changed, 18 insertions, 2 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 c91f7e2ca9a..3444c96ae49 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 @@ -54,6 +54,8 @@ #include "frontend/drm_driver.h" #include "kms_dri_sw_winsys.h" +#include "util/simple_mtx.h" + #ifdef DEBUG #define DEBUG_PRINT(msg, ...) fprintf(stderr, msg, __VA_ARGS__) #else @@ -85,6 +87,7 @@ struct kms_sw_displaytarget int map_count; struct list_head link; struct list_head planes; + mtx_t map_lock; }; struct kms_sw_winsys @@ -182,6 +185,8 @@ kms_sw_displaytarget_create(struct sw_winsys *ws, kms_sw_dt->format = format; + mtx_init(&kms_sw_dt->map_lock, mtx_plain); + memset(&create_req, 0, sizeof(create_req)); create_req.bpp = util_format_get_blocksizebits(format); create_req.width = width; @@ -236,6 +241,7 @@ kms_sw_displaytarget_destroy(struct sw_winsys *ws, list_del(&kms_sw_dt->link); + mtx_destroy(&kms_sw_dt->map_lock); DEBUG_PRINT("KMS-DEBUG: destroyed buffer %u\n", kms_sw_dt->handle); struct kms_sw_plane *tmp; @@ -257,11 +263,12 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, struct drm_mode_map_dumb map_req; int prot, ret; + mtx_lock(&kms_sw_dt->map_lock); memset(&map_req, 0, sizeof map_req); map_req.handle = kms_sw_dt->handle; ret = drmIoctl(kms_sw->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_req); if (ret) - return NULL; + goto fail_locked; prot = (flags == PIPE_MAP_READ) ? PROT_READ : (PROT_READ | PROT_WRITE); void **ptr = (flags == PIPE_MAP_READ) ? &kms_sw_dt->ro_mapped : &kms_sw_dt->mapped; @@ -269,7 +276,7 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, void *tmp = mmap(NULL, kms_sw_dt->size, prot, MAP_SHARED, kms_sw->fd, map_req.offset); if (tmp == MAP_FAILED) - return NULL; + goto fail_locked; *ptr = tmp; } @@ -278,7 +285,12 @@ kms_sw_displaytarget_map(struct sw_winsys *ws, kms_sw_dt->map_count++; + mtx_unlock(&kms_sw_dt->map_lock); + return *ptr + plane->offset; +fail_locked: + mtx_unlock(&kms_sw_dt->map_lock); + return NULL; } static struct kms_sw_displaytarget * @@ -360,13 +372,16 @@ kms_sw_displaytarget_unmap(struct sw_winsys *ws, struct kms_sw_plane *plane = kms_sw_plane(dt); struct kms_sw_displaytarget *kms_sw_dt = plane->dt; + mtx_lock(&kms_sw_dt->map_lock); if (!kms_sw_dt->map_count) { DEBUG_PRINT("KMS-DEBUG: ignore duplicated unmap %u", kms_sw_dt->handle); + mtx_unlock(&kms_sw_dt->map_lock); return; } kms_sw_dt->map_count--; if (kms_sw_dt->map_count) { DEBUG_PRINT("KMS-DEBUG: ignore unmap for busy buffer %u", kms_sw_dt->handle); + mtx_unlock(&kms_sw_dt->map_lock); return; } @@ -381,6 +396,7 @@ kms_sw_displaytarget_unmap(struct sw_winsys *ws, munmap(kms_sw_dt->ro_mapped, kms_sw_dt->size); kms_sw_dt->ro_mapped = MAP_FAILED; } + mtx_unlock(&kms_sw_dt->map_lock); } static struct sw_displaytarget * |