summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c
diff options
context:
space:
mode:
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.c20
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 *