Discussion:
[PATCH] gallium/winsys/kms: Add support for multi-planes.
Add Reply
Tao Wu
2017-12-24 04:59:27 UTC
Reply
Permalink
Raw Message
From: Lepton Wu <***@chromium.org>

Signed-off-by: Lepton Wu <***@chromium.org>

Change-Id: I0863f522976cc8863d6e95492d9346df35c066ec
---
src/gallium/winsys/sw/kms-dri/kms_dri_sw_winsys.c | 150 +++++++++++++++-------
1 file changed, 106 insertions(+), 44 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..514298aea4e 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,13 +59,20 @@
#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;
@@ -73,6 +80,7 @@ struct kms_sw_displaytarget

int ref_count;
struct list_head link;
+ struct list_head planes;
};

struct kms_sw_winsys
@@ -83,10 +91,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 +113,39 @@ 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,
+ unsigned width, unsigned height,
+ unsigned stride, unsigned offset) {
+ struct kms_sw_plane * tmp, * plane = NULL;
+ if (offset > kms_sw_dt->size) {
+ DEBUG_PRINT("KMS-DEBUG: offset %d bigger then %d\n",
+ 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 +165,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 +178,20 @@ 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;
+ if (get_plane(kms_sw_dt, width, height, create_req.pitch, create_req.size)
+ == 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 *) list_first_entry(&kms_sw_dt->planes,
+ struct kms_sw_plane,
+ link);
free_bo:
memset(&destroy_req, 0, sizeof destroy_req);
destroy_req.handle = create_req.handle;
@@ -163,7 +206,7 @@ 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_displaytarget *kms_sw_dt = kms_sw_plane(dt)->dt;
struct drm_mode_destroy_dumb destroy_req;

kms_sw_dt->ref_count --;
@@ -178,6 +221,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 * plane, * tmp;
+ LIST_FOR_EACH_ENTRY_SAFE(plane, tmp, &kms_sw_dt->planes, link) {
+ FREE(plane);
+ }
FREE(kms_sw_dt);
}

@@ -187,7 +234,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 *kms_sw_pl = kms_sw_plane(dt);
+ struct kms_sw_displaytarget *kms_sw_dt = kms_sw_pl->dt;
struct drm_mode_map_dumb map_req;
int prot, ret;

@@ -204,10 +252,11 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
if (kms_sw_dt->mapped == MAP_FAILED)
return NULL;

- 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, kms_sw_dt->mapped,
+ kms_sw_pl->width, kms_sw_pl->height);

- return kms_sw_dt->mapped;
+ return kms_sw_dt->mapped + kms_sw_pl->offset;
}

static struct kms_sw_displaytarget *
@@ -230,10 +279,10 @@ 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,
unsigned width, unsigned height,
- unsigned stride)
+ unsigned stride, unsigned offset)
{
uint32_t handle = -1;
struct kms_sw_displaytarget * kms_sw_dt;
@@ -245,13 +294,20 @@ 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;
+ if (kms_sw_dt) {
+ struct kms_sw_plane * pl = get_plane(kms_sw_dt, width, height,
+ stride, offset);
+ if (pl == NULL) {
+ kms_sw_dt->ref_count --;
+ }
+ return pl;
+ }

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,22 +316,23 @@ 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);
+ if (get_plane(kms_sw_dt, width, height, stride, offset) == NULL) {
+ FREE(kms_sw_dt);
+ return NULL;
+ }

list_add(&kms_sw_dt->link, &kms_sw->bo_list);

- return kms_sw_dt;
+ return list_first_entry(&kms_sw_dt->planes, struct kms_sw_plane, link);
}

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_displaytarget *kms_sw_dt = kms_sw_plane(dt)->dt;

DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->mapped);

@@ -291,30 +348,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->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 --;
+ return NULL;
}
/* fallthrough */
default:
@@ -331,19 +392,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 *kms_sw_pl = kms_sw_plane(dt);
+ struct kms_sw_displaytarget *kms_sw_dt = kms_sw_pl->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 = kms_sw_pl->stride;
+ whandle->offset = kms_sw_pl->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 = kms_sw_pl->stride;
+ whandle->offset = kms_sw_pl->offset;
return TRUE;
}
/* fallthrough */
--
2.13.5
Lepton Wu
2017-12-28 07:35:05 UTC
Reply
Permalink
Raw Message
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 <***@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
Loading...