[Mesa-dev] [PATCH v4 2/2] gallium/winsys/kms: Add support for multi-planes

Lepton Wu lepton at chromium.org
Wed Mar 7 22:42:01 UTC 2018


For this patch, actually it's as same as V3. But since it depends on
the 1st patch, I also update the title to V4.

On Wed, Mar 7, 2018 at 2:39 PM, Lepton Wu <lepton at chromium.org> wrote:
> Add a new struct kms_sw_plane which delegate a plane and use it
> in place of sw_displaytarget. Multiple planes share same underlying
> kms_sw_displaytarget.
>
> Change-Id: I0e9ca1d0ba0aa78c27dfdb50c30dc0c424fec172
> Signed-off-by: Lepton Wu <lepton at chromium.org>
> ---
>  .../winsys/sw/kms-dri/kms_dri_sw_winsys.c     | 162 +++++++++++++-----
>  1 file changed, 122 insertions(+), 40 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 7fc40488c2e..ec3c9d9d29e 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,22 @@
>  #define DEBUG_PRINT(msg, ...)
>  #endif
>
> +struct kms_sw_displaytarget;
>
> -struct kms_sw_displaytarget
> +struct kms_sw_plane
>  {
> -   enum pipe_format format;
>     unsigned width;
>     unsigned height;
>     unsigned stride;
> +   unsigned offset;
> +   int mapped;
> +   struct kms_sw_displaytarget *dt;
> +   struct list_head link;
> +};
> +
> +struct kms_sw_displaytarget
> +{
> +   enum pipe_format format;
>     unsigned size;
>
>     uint32_t handle;
> @@ -74,6 +83,7 @@ struct kms_sw_displaytarget
>
>     int ref_count;
>     struct list_head link;
> +   struct list_head planes;
>  };
>
>  struct kms_sw_winsys
> @@ -84,10 +94,16 @@ 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 sw_displaytarget *
> +sw_displaytarget( struct kms_sw_plane *pl)
> +{
> +   return (struct sw_displaytarget *)pl;
>  }
>
>  static inline struct kms_sw_winsys *
> @@ -106,6 +122,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,
> +                                      enum pipe_format format,
> +                                      unsigned width, unsigned height,
> +                                      unsigned stride, unsigned offset)
> +{
> +   struct kms_sw_plane *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(plane, &kms_sw_dt->planes, link) {
> +      if (plane->offset == offset)
> +         return plane;
> +   }
> +
> +   plane = CALLOC_STRUCT(kms_sw_plane);
> +   if (!plane)
> +      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,
> @@ -125,11 +174,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;
> @@ -139,16 +187,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)
> +      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 sw_displaytarget(plane);
>
>   free_bo:
>     memset(&destroy_req, 0, sizeof destroy_req);
> @@ -164,7 +215,8 @@ 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 --;
> @@ -179,6 +231,11 @@ 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);
>  }
>
> @@ -188,7 +245,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;
>
> @@ -211,7 +269,8 @@ kms_sw_displaytarget_map(struct sw_winsys *ws,
>     DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p\n",
>           kms_sw_dt->handle, kms_sw_dt->size, *ptr);
>
> -   return *ptr;
> +   plane->mapped = 1;
> +   return *ptr + plane->offset;
>  }
>
>  static struct kms_sw_displaytarget *
> @@ -234,10 +293,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;
> @@ -249,13 +309,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)
> +        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);
> @@ -264,22 +330,33 @@ 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) {
> +      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;
> +
> +   plane->mapped = 0;
> +   LIST_FOR_EACH_ENTRY(plane, &kms_sw_dt->planes, link) {
> +      if (plane->mapped) {
> +         DEBUG_PRINT("KMS-DEBUG: ignore unmap buffer %u \n", kms_sw_dt->handle);
> +         return;
> +      }
> +   }
>
>     DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->mapped);
>     DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n", kms_sw_dt->handle, kms_sw_dt->ro_mapped);
> @@ -298,30 +375,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 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 sw_displaytarget(plane);
> +            }
> +         }
> +         kms_sw_dt->ref_count --;
>        }
>        /* fallthrough */
>     default:
> @@ -338,19 +419,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.16.2.395.g2e18187dfd-goog
>
<div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 7,
2018 at 2:39 PM, Lepton Wu <span dir="ltr"><<a
href="mailto:lepton at chromium.org"
target="_blank">lepton at chromium.org</a>></span>
wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Add a new struct
kms_sw_plane which delegate a plane and use it<br>
in place of sw_displaytarget. Multiple planes share same underlying<br>
kms_sw_displaytarget.<br>
<br>
Change-Id: I0e9ca1d0ba0aa78c27dfdb50c30dc<wbr>0c424fec172<br>
Signed-off-by: Lepton Wu <<a
href="mailto:lepton at chromium.org">lepton at chromium.org</a>><br>
---<br>
 .../winsys/sw/kms-dri/kms_dri_<wbr>sw_winsys.c   
 | 162 +++++++++++++-----<br>
 1 file changed, 122 insertions(+), 40 deletions(-)<br>
<br>
diff --git a/src/gallium/winsys/sw/kms-<wbr>dri/kms_dri_sw_winsys.c
b/src/gallium/winsys/sw/kms-<wbr>dri/kms_dri_sw_winsys.c<br>
index 7fc40488c2e..ec3c9d9d29e 100644<br>
--- a/src/gallium/winsys/sw/kms-<wbr>dri/kms_dri_sw_winsys.c<br>
+++ b/src/gallium/winsys/sw/kms-<wbr>dri/kms_dri_sw_winsys.c<br>
@@ -59,13 +59,22 @@<br>
 #define DEBUG_PRINT(msg, ...)<br>
 #endif<br>
<br>
+struct kms_sw_displaytarget;<br>
<br>
-struct kms_sw_displaytarget<br>
+struct kms_sw_plane<br>
 {<br>
-   enum pipe_format format;<br>
    unsigned width;<br>
    unsigned height;<br>
    unsigned stride;<br>
+   unsigned offset;<br>
+   int mapped;<br>
+   struct kms_sw_displaytarget *dt;<br>
+   struct list_head link;<br>
+};<br>
+<br>
+struct kms_sw_displaytarget<br>
+{<br>
+   enum pipe_format format;<br>
    unsigned size;<br>
<br>
    uint32_t handle;<br>
@@ -74,6 +83,7 @@ struct kms_sw_displaytarget<br>
<br>
    int ref_count;<br>
    struct list_head link;<br>
+   struct list_head planes;<br>
 };<br>
<br>
 struct kms_sw_winsys<br>
@@ -84,10 +94,16 @@ struct kms_sw_winsys<br>
    struct list_head bo_list;<br>
 };<br>
<br>
-static inline struct kms_sw_displaytarget *<br>
-kms_sw_displaytarget( struct sw_displaytarget *dt )<br>
+static inline struct kms_sw_plane *<br>
+kms_sw_plane( struct sw_displaytarget *dt )<br>
 {<br>
-   return (struct kms_sw_displaytarget *)dt;<br>
+   return (struct kms_sw_plane *)dt;<br>
+}<br>
+<br>
+static inline struct sw_displaytarget *<br>
+sw_displaytarget( struct kms_sw_plane *pl)<br>
+{<br>
+   return (struct sw_displaytarget *)pl;<br>
 }<br>
<br>
 static inline struct kms_sw_winsys *<br>
@@ -106,6 +122,39 @@ kms_sw_is_displaytarget_<wbr>format_supported(
struct sw_winsys *ws,<br>
    return TRUE;<br>
 }<br>
<br>
+static struct kms_sw_plane *get_plane(struct kms_sw_displaytarget
*kms_sw_dt,<br>
+                   
                  enum
pipe_format format,<br>
+                   
                 
unsigned width, unsigned height,<br>
+                   
                 
unsigned stride, unsigned offset)<br>
+{<br>
+   struct kms_sw_plane *plane = NULL;<br>
+<br>
+   if (offset + util_format_get_2d_size(<wbr>format,
stride, height) ><br>
+       kms_sw_dt->size) {<br>
+      DEBUG_PRINT("KMS-DEBUG: plane too big. format:
%d stride: %d height: %d "<br>
+                 
"offset: %d size:%d\n", format, stride, height, offset,<br>
+                 
kms_sw_dt->size);<br>
+      return NULL;<br>
+   }<br>
+<br>
+   LIST_FOR_EACH_ENTRY(plane, &kms_sw_dt->planes, link) {<br>
+      if (plane->offset == offset)<br>
+         return plane;<br>
+   }<br>
+<br>
+   plane = CALLOC_STRUCT(kms_sw_plane);<br>
+   if (!plane)<br>
+      return NULL;<br>
+<br>
+   plane->width = width;<br>
+   plane->height = height;<br>
+   plane->stride = stride;<br>
+   plane->offset = offset;<br>
+   plane->dt = kms_sw_dt;<br>
+   list_add(&plane->link, &kms_sw_dt->planes);<br>
+   return plane;<br>
+}<br>
+<br>
 static struct sw_displaytarget *<br>
 kms_sw_displaytarget_create(<wbr>struct sw_winsys *ws,<br>
                   
         unsigned tex_usage,<br>
@@ -125,11 +174,10 @@ kms_sw_displaytarget_create(<wbr>struct sw_winsys *ws,<br>
    if (!kms_sw_dt)<br>
       goto no_dt;<br>
<br>
+   list_inithead(&kms_sw_dt-><wbr>planes);<br>
    kms_sw_dt->ref_count = 1;<br>
<br>
    kms_sw_dt->format = format;<br>
-   kms_sw_dt->width = width;<br>
-   kms_sw_dt->height = height;<br>
<br>
    memset(&create_req, 0, sizeof(create_req));<br>
    create_req.bpp = 32;<br>
@@ -139,16 +187,19 @@ kms_sw_displaytarget_create(<wbr>struct sw_winsys *ws,<br>
    if (ret)<br>
       goto free_bo;<br>
<br>
-   kms_sw_dt->stride = create_req.pitch;<br>
    kms_sw_dt->size = create_req.size;<br>
    kms_sw_dt->handle = create_req.handle;<br>
+   struct kms_sw_plane *plane = get_plane(kms_sw_dt,
format, width, height,<br>
+                   
                   
  create_req.pitch, 0);<br>
+   if (!plane)<br>
+      goto free_bo;<br>
<br>
    list_add(&kms_sw_dt->link, &kms_sw->bo_list);<br>
<br>
    DEBUG_PRINT("KMS-DEBUG: created buffer %u (size %u)\n",
kms_sw_dt->handle, kms_sw_dt->size);<br>
<br>
-   *stride = kms_sw_dt->stride;<br>
-   return (struct sw_displaytarget *)kms_sw_dt;<br>
+   *stride = create_req.pitch;<br>
+   return sw_displaytarget(plane);<br>
<br>
  free_bo:<br>
    memset(&destroy_req, 0, sizeof destroy_req);<br>
@@ -164,7 +215,8 @@ kms_sw_displaytarget_destroy(<wbr>struct sw_winsys *ws,<br>
                   
          struct sw_displaytarget *dt)<br>
 {<br>
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);<br>
-   struct kms_sw_displaytarget *kms_sw_dt =
kms_sw_displaytarget(dt);<br>
+   struct kms_sw_plane *plane = kms_sw_plane(dt);<br>
+   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;<br>
    struct drm_mode_destroy_dumb destroy_req;<br>
<br>
    kms_sw_dt->ref_count --;<br>
@@ -179,6 +231,11 @@ kms_sw_displaytarget_destroy(<wbr>struct sw_winsys *ws,<br>
<br>
    DEBUG_PRINT("KMS-DEBUG: destroyed buffer %u\n",
kms_sw_dt->handle);<br>
<br>
+   struct kms_sw_plane *tmp;<br>
+   LIST_FOR_EACH_ENTRY_SAFE(<wbr>plane, tmp,
&kms_sw_dt->planes, link) {<br>
+      FREE(plane);<br>
+   }<br>
+<br>
    FREE(kms_sw_dt);<br>
 }<br>
<br>
@@ -188,7 +245,8 @@ kms_sw_displaytarget_map(<wbr>struct sw_winsys *ws,<br>
                   
      unsigned flags)<br>
 {<br>
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);<br>
-   struct kms_sw_displaytarget *kms_sw_dt =
kms_sw_displaytarget(dt);<br>
+   struct kms_sw_plane *plane = kms_sw_plane(dt);<br>
+   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;<br>
    struct drm_mode_map_dumb map_req;<br>
    int prot, ret;<br>
<br>
@@ -211,7 +269,8 @@ kms_sw_displaytarget_map(<wbr>struct sw_winsys *ws,<br>
    DEBUG_PRINT("KMS-DEBUG: mapped buffer %u (size %u) at %p\n",<br>
          kms_sw_dt->handle,
kms_sw_dt->size, *ptr);<br>
<br>
-   return *ptr;<br>
+   plane->mapped = 1;<br>
+   return *ptr + plane->offset;<br>
 }<br>
<br>
 static struct kms_sw_displaytarget *<br>
@@ -234,10 +293,11 @@ kms_sw_displaytarget_find_and_<wbr>ref(struct
kms_sw_winsys *kms_sw,<br>
    return NULL;<br>
 }<br>
<br>
-static struct kms_sw_displaytarget *<br>
+static struct kms_sw_plane *<br>
 kms_sw_displaytarget_add_from_<wbr>prime(struct kms_sw_winsys
*kms_sw, int fd,<br>
+                   
                enum
pipe_format format,<br>
                   
                 unsigned
width, unsigned height,<br>
-                   
                unsigned
stride)<br>
+                   
                unsigned
stride, unsigned offset)<br>
 {<br>
    uint32_t handle = -1;<br>
    struct kms_sw_displaytarget * kms_sw_dt;<br>
@@ -249,13 +309,19 @@ kms_sw_displaytarget_add_from_<wbr>prime(struct
kms_sw_winsys *kms_sw, int fd,<br>
       return NULL;<br>
<br>
    kms_sw_dt =
kms_sw_displaytarget_find_and_<wbr>ref(kms_sw, handle);<br>
-   if (kms_sw_dt)<br>
-      return kms_sw_dt;<br>
+   struct kms_sw_plane *plane = NULL;<br>
+   if (kms_sw_dt) {<br>
+      plane = get_plane(kms_sw_dt, format, width,
height, stride, offset);<br>
+      if (!plane)<br>
+        kms_sw_dt->ref_count --;<br>
+      return plane;<br>
+   }<br>
<br>
    kms_sw_dt = CALLOC_STRUCT(kms_sw_<wbr>displaytarget);<br>
    if (!kms_sw_dt)<br>
       return NULL;<br>
<br>
+   list_inithead(&kms_sw_dt-><wbr>planes);<br>
    off_t lseek_ret = lseek(fd, 0, SEEK_END);<br>
    if (lseek_ret == -1) {<br>
       FREE(kms_sw_dt);<br>
@@ -264,22 +330,33 @@ kms_sw_displaytarget_add_from_<wbr>prime(struct
kms_sw_winsys *kms_sw, int fd,<br>
    kms_sw_dt->size = lseek_ret;<br>
    kms_sw_dt->ref_count = 1;<br>
    kms_sw_dt->handle = handle;<br>
-   kms_sw_dt->width = width;<br>
-   kms_sw_dt->height = height;<br>
-   kms_sw_dt->stride = stride;<br>
<br>
    lseek(fd, 0, SEEK_SET);<br>
+   plane = get_plane(kms_sw_dt, format, width, height,
stride, offset);<br>
+   if (!plane) {<br>
+      FREE(kms_sw_dt);<br>
+      return NULL;<br>
+   }<br>
<br>
    list_add(&kms_sw_dt->link, &kms_sw->bo_list);<br>
<br>
-   return kms_sw_dt;<br>
+   return plane;<br>
 }<br>
<br>
 static void<br>
 kms_sw_displaytarget_unmap(<wbr>struct sw_winsys *ws,<br>
                   
        struct sw_displaytarget *dt)<br>
 {<br>
-   struct kms_sw_displaytarget *kms_sw_dt =
kms_sw_displaytarget(dt);<br>
+   struct kms_sw_plane *plane = kms_sw_plane(dt);<br>
+   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;<br>
+<br>
+   plane->mapped = 0;<br>
+   LIST_FOR_EACH_ENTRY(plane, &kms_sw_dt->planes, link) {<br>
+      if (plane->mapped) {<br>
+         DEBUG_PRINT("KMS-DEBUG: ignore
unmap buffer %u \n", kms_sw_dt->handle);<br>
+         return;<br>
+      }<br>
+   }<br>
<br>
    DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n",
kms_sw_dt->handle, kms_sw_dt->mapped);<br>
    DEBUG_PRINT("KMS-DEBUG: unmapped buffer %u (was %p)\n",
kms_sw_dt->handle, kms_sw_dt->ro_mapped);<br>
@@ -298,30 +375,34 @@ kms_sw_displaytarget_from_<wbr>handle(struct
sw_winsys *ws,<br>
 {<br>
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(ws);<br>
    struct kms_sw_displaytarget *kms_sw_dt;<br>
+   struct kms_sw_plane *kms_sw_pl;<br>
+<br>
<br>
    assert(whandle->type == DRM_API_HANDLE_TYPE_KMS ||<br>
           whandle->type ==
DRM_API_HANDLE_TYPE_FD);<br>
<br>
-   if (whandle->offset != 0) {<br>
-      DEBUG_PRINT("KMS-DEBUG: attempt to import
unsupported winsys offset %d\n",<br>
-                 
whandle->offset);<br>
-      return NULL;<br>
-   }<br>
-<br>
    switch(whandle->type) {<br>
    case DRM_API_HANDLE_TYPE_FD:<br>
-      kms_sw_dt =
kms_sw_displaytarget_add_from_<wbr>prime(kms_sw,
whandle->handle,<br>
+      kms_sw_pl =
kms_sw_displaytarget_add_from_<wbr>prime(kms_sw,
whandle->handle,<br>
+                   
                   
              templ->format,<br>
                   
                   
             
 templ->width0,<br>
                   
                   
             
 templ->height0,<br>
-                   
                   
             
whandle->stride);<br>
-      if (kms_sw_dt)<br>
-         *stride = kms_sw_dt->stride;<br>
-      return (struct sw_displaytarget *)kms_sw_dt;<br>
+                   
                   
             
whandle->stride,<br>
+                   
                   
             
whandle->offset);<br>
+      if (kms_sw_pl)<br>
+         *stride = kms_sw_pl->stride;<br>
+      return sw_displaytarget(kms_sw_pl);<br>
    case DRM_API_HANDLE_TYPE_KMS:<br>
       kms_sw_dt =
kms_sw_displaytarget_find_and_<wbr>ref(kms_sw,
whandle->handle);<br>
       if (kms_sw_dt) {<br>
-         *stride = kms_sw_dt->stride;<br>
-         return (struct sw_displaytarget
*)kms_sw_dt;<br>
+         struct kms_sw_plane *plane;<br>
+         LIST_FOR_EACH_ENTRY(plane,
&kms_sw_dt->planes, link) {<br>
+            if (whandle->offset ==
plane->offset) {<br>
+               *stride =
plane->stride;<br>
+               return
sw_displaytarget(plane);<br>
+            }<br>
+         }<br>
+         kms_sw_dt->ref_count --;<br>
       }<br>
       /* fallthrough */<br>
    default:<br>
@@ -338,19 +419,20 @@ kms_sw_displaytarget_get_<wbr>handle(struct
sw_winsys *winsys,<br>
                   
             struct winsys_handle
*whandle)<br>
 {<br>
    struct kms_sw_winsys *kms_sw = kms_sw_winsys(winsys);<br>
-   struct kms_sw_displaytarget *kms_sw_dt =
kms_sw_displaytarget(dt);<br>
+   struct kms_sw_plane *plane = kms_sw_plane(dt);<br>
+   struct kms_sw_displaytarget *kms_sw_dt = plane->dt;<br>
<br>
    switch(whandle->type) {<br>
    case DRM_API_HANDLE_TYPE_KMS:<br>
       whandle->handle = kms_sw_dt->handle;<br>
-      whandle->stride = kms_sw_dt->stride;<br>
-      whandle->offset = 0;<br>
+      whandle->stride = plane->stride;<br>
+      whandle->offset = plane->offset;<br>
       return TRUE;<br>
    case DRM_API_HANDLE_TYPE_FD:<br>
       if (!drmPrimeHandleToFD(kms_sw-><wbr>fd,
kms_sw_dt->handle,<br>
                   
          DRM_CLOEXEC,
(int*)&whandle->handle)) {<br>
-         whandle->stride =
kms_sw_dt->stride;<br>
-         whandle->offset = 0;<br>
+         whandle->stride = plane->stride;<br>
+         whandle->offset = plane->offset;<br>
          return TRUE;<br>
       }<br>
       /* fallthrough */<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.16.2.395.g2e18187dfd-goog<br>
<br>
</font></span></blockquote></div><br></div>


More information about the mesa-dev mailing list