Use tbm surface queue 26/52626/2
authorSangjin Lee <lsj119@samsung.com>
Sat, 21 Nov 2015 12:34:37 +0000 (21:34 +0900)
committerSangjin Lee <lsj119@samsung.com>
Wed, 25 Nov 2015 12:43:26 +0000 (21:43 +0900)
Change-Id: I8023244921a39963c101d2835817ad4a275d3734

backends/tbm/gbm_tbm.c
backends/tbm/gbm_tbm.h
backends/tbm/gbm_tbmint.h
configure.ac
packaging/libgbm.spec
src/gbm.h

index f6560aa99f387cd65dbc88b5ab3447ec1841d9b8..e8adca4f8d68d98fb4cc3246a4e3022927c40d68 100644 (file)
@@ -33,10 +33,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <string.h>
 #include <limits.h>
 
+#include "config.h"
 #include "gbm_tbmint.h"
 #include <tbm_surface_internal.h>
 #include <wayland-tbm-server.h>
 
+static int tbm_private_data;
+#define TBM_DATA_KEY ((unsigned long)&tbm_private_data)
+
+#ifdef USE_TBM_QUEUE
+struct gbm_bo* __gbm_tbm_get_gbm_bo(tbm_surface_h surf);
+
+GBM_EXPORT tbm_surface_queue_h
+gbm_tbm_get_surface_queue(struct gbm_surface* surface)
+{
+   struct gbm_tbm_surface *surf = gbm_tbm_surface(surface);
+   return surf->queue;
+}
+
+GBM_EXPORT tbm_surface_h
+gbm_tbm_get_surface(struct gbm_bo* bo)
+{
+   struct gbm_tbm_bo *_bo = gbm_tbm_bo(bo);
+   return _bo->tbm_surf;
+}
+
+#else
 GBM_EXPORT tbm_bo
 gbm_tbm_bo_get_tbm_bo(struct gbm_tbm_bo *bo)
 {
@@ -104,6 +126,7 @@ gbm_tbm_device_set_callback_surface_release_buffer(struct gbm_tbm_device *gbm_tb
 {
    gbm_tbm->base.surface_release_buffer = callback;
 }
+#endif
 
 static int
 __gbm_tbm_is_format_supported(struct gbm_device *gbm,
@@ -112,10 +135,8 @@ __gbm_tbm_is_format_supported(struct gbm_device *gbm,
 {
    switch (format)
    {
-   case GBM_BO_FORMAT_XRGB8888:
    case GBM_FORMAT_XRGB8888:
        break;
-   case GBM_BO_FORMAT_ARGB8888:
    case GBM_FORMAT_ARGB8888:
        if (usage & GBM_BO_USE_SCANOUT)
           return 0;
@@ -157,7 +178,6 @@ __gbm_tbm_bo_get_fd(struct gbm_bo *_bo)
    tbo = tbm_surface_internal_get_bo(bo->tbm_surf, 0);
    if (!tbo)
    {
-      fprintf(stderr, "%s::tbm_surface_internal_get_bo() failed.\n", __FUNCTION__);
          return 0;
    }
    handle = tbm_bo_get_handle(tbo, TBM_DEVICE_MM);
@@ -225,14 +245,13 @@ __gbm_tbm_bo_import(struct gbm_device *gbm, uint32_t type,
 }
 
 static struct gbm_bo *
-__gbm_tbm_bo_create(struct gbm_device *gbm,
+__gbm_tbm_bo_create_by_tbm_surface(struct gbm_device *gbm,
+          tbm_surface_h tbm_surf,
                  uint32_t width, uint32_t height,
                  uint32_t format, uint32_t usage)
 {
    struct gbm_tbm_bo *bo;
    uint32_t size, offset, pitch;
-   int flags = TBM_BO_DEFAULT;
-   int surface_format;
    tbm_bo_handle handle;
    tbm_bo tbo;
 
@@ -245,53 +264,161 @@ __gbm_tbm_bo_create(struct gbm_device *gbm,
    bo->base.height = height;
    bo->base.format = format;
    bo->usage = usage;
+   bo->tbm_surf = tbm_surf;
 
-   switch (format)
+   if (!tbm_surface_internal_get_plane_data(bo->tbm_surf, 0, &size, &offset, &pitch))
    {
-   case GBM_FORMAT_RGB565:
-       surface_format = TBM_FORMAT_BGR565;
-       break;
-   case GBM_FORMAT_XRGB8888:
-   case GBM_BO_FORMAT_XRGB8888:
-       surface_format = TBM_FORMAT_XRGB8888;
-       break;
-   case GBM_FORMAT_ARGB8888:
-   case GBM_BO_FORMAT_ARGB8888:
-   case GBM_FORMAT_ABGR8888:
-       surface_format = TBM_FORMAT_ABGR8888;
-       break;
-   default:
-       free(bo);
-       return NULL;
+      tbm_surface_destroy(bo->tbm_surf);
+      free(bo);
+      return NULL;
    }
 
+   bo->base.stride = pitch;
+   tbo = tbm_surface_internal_get_bo(bo->tbm_surf, 0);
+   handle = tbm_bo_get_handle(tbo, TBM_DEVICE_DEFAULT);
+   bo->base.handle.u64 = handle.u64;
+
+   tbm_bo_add_user_data(tbo, TBM_DATA_KEY, NULL);
+   tbm_bo_set_user_data(tbo, TBM_DATA_KEY, &bo->base);
+
+   return &bo->base;
+}
+
+static struct gbm_bo *
+__gbm_tbm_bo_create(struct gbm_device *gbm,
+                 uint32_t width, uint32_t height,
+                 uint32_t format, uint32_t usage)
+{
+   tbm_surface_h tbm_surf;
+   int flags = TBM_BO_DEFAULT;
+
    if ((usage & GBM_BO_USE_SCANOUT) || (usage & GBM_BO_USE_CURSOR_64X64))
    {
        flags |= TBM_BO_SCANOUT;
    }
 
-   bo->tbm_surf = tbm_surface_internal_create_with_flags(width, height, surface_format, flags);
-   if (!bo->tbm_surf)
+   tbm_surf = tbm_surface_internal_create_with_flags(width, height, format, flags);
+   if (tbm_surf)
    {
-      free(bo);
       return NULL;
    }
 
-   if (!tbm_surface_internal_get_plane_data(bo->tbm_surf, 0, &size, &offset, &pitch))
+   return __gbm_tbm_bo_create_by_tbm_surface(gbm, tbm_surf, width, height, format, flags);
+}
+
+
+#ifdef USE_TBM_QUEUE
+struct gbm_bo*
+__gbm_tbm_get_gbm_bo(tbm_surface_h surf)
+{
+   tbm_bo bo;
+   struct gbm_bo* gbo = NULL;
+
+   bo = tbm_surface_internal_get_bo(surf, 0);
+   if (!bo) return NULL;
+
+   if (tbm_bo_get_user_data(bo, TBM_DATA_KEY, (void**)&gbo))
    {
-      tbm_surface_destroy(bo->tbm_surf);
-      free(bo);
+      return gbo;
+   }
+
+   return NULL;
+}
+
+static struct gbm_surface *
+__gbm_tbm_surface_create(struct gbm_device *gbm,
+                      uint32_t width, uint32_t height,
+                      uint32_t format, uint32_t flags)
+{
+   struct gbm_tbm_surface *surf;
+   int tbm_flags = 0;
+
+   surf = calloc(1, sizeof *surf);
+   if (surf == NULL)
+       return NULL;
+
+   surf->base.gbm = gbm;
+   surf->base.width = width;
+   surf->base.height = height;
+   surf->base.format = format;
+   surf->base.flags = flags;
+
+   if ((flags & GBM_BO_USE_SCANOUT) || (flags & GBM_BO_USE_CURSOR_64X64))
+   {
+       tbm_flags |= TBM_BO_SCANOUT;
+   }
+
+   surf->queue = tbm_surface_queue_create(3, width, height, format, tbm_flags);
+   if (!surf->queue)
+   {
+      free(surf);
       return NULL;
    }
 
-   bo->base.stride = pitch;
-   tbo = tbm_surface_internal_get_bo(bo->tbm_surf, 0);
-   handle = tbm_bo_get_handle(tbo, TBM_DEVICE_DEFAULT);
-   bo->base.handle.u64 = handle.u64;
+   return &surf->base;
+}
 
-   return &bo->base;
+static void
+__gbm_tbm_surface_destroy(struct gbm_surface *surface)
+{
+   struct gbm_tbm_surface *surf = gbm_tbm_surface(surface);
+
+   tbm_surface_queue_destroy(surf->queue);
+   free(surf);
 }
 
+static struct gbm_bo *
+__gbm_tbm_surface_lock_front_buffer(struct gbm_surface *surface)
+{
+   struct gbm_tbm_surface *surf = gbm_tbm_surface(surface);
+   int num_duty;
+   tbm_surface_h tbm_surf;
+   struct gbm_bo *gbo;
+
+   if ((num_duty = tbm_surface_queue_can_acquire(surf->queue, 1)))
+   {
+      if ((TBM_SURFACE_QUEUE_ERROR_NONE == tbm_surface_queue_acquire(surf->queue, &tbm_surf)))
+      {
+         gbo = __gbm_tbm_get_gbm_bo(tbm_surf);
+         if (gbo)
+            return gbo;
+
+         gbo = __gbm_tbm_bo_create_by_tbm_surface(surf->base.gbm,
+                        tbm_surf,
+                        surf->base.width,
+                        surf->base.height,
+                        surf->base.format,
+                        surf->base.flags);
+         if (gbo)
+         {
+            return gbo;
+         }
+      }
+   }
+
+   return NULL;
+}
+
+static void
+__gbm_tbm_surface_release_buffer(struct gbm_surface *surface,
+                                  struct gbm_bo *gbo)
+{
+   struct gbm_tbm_surface *surf = gbm_tbm_surface(surface);
+   struct gbm_tbm_bo *bo = gbm_tbm_bo(gbo);
+   tbm_surface_h tbm_surf;
+
+   tbm_surf = bo->tbm_surf;
+   tbm_surface_queue_release(surf->queue, tbm_surf);
+}
+
+static int
+__gbm_tbm_surface_has_free_buffers(struct gbm_surface *surface)
+{
+   struct gbm_tbm_surface *surf = gbm_tbm_surface(surface);
+
+   return tbm_surface_queue_can_acquire(surf->queue, 0);
+}
+#else
 static struct gbm_surface *
 __gbm_tbm_surface_create(struct gbm_device *gbm,
                       uint32_t width, uint32_t height,
@@ -319,6 +446,7 @@ __gbm_tbm_surface_destroy(struct gbm_surface *_surf)
 
    free(surf);
 }
+#endif
 
 static void
 __tbm_destroy(struct gbm_device *gbm)
@@ -355,6 +483,11 @@ __tbm_device_create(int fd)
    dri->base.destroy = __tbm_destroy;
    dri->base.surface_create = __gbm_tbm_surface_create;
    dri->base.surface_destroy = __gbm_tbm_surface_destroy;
+#ifdef USE_TBM_QUEUE
+   dri->base.surface_lock_front_buffer = __gbm_tbm_surface_lock_front_buffer;
+   dri->base.surface_release_buffer = __gbm_tbm_surface_release_buffer;
+   dri->base.surface_has_free_buffers = __gbm_tbm_surface_has_free_buffers;
+#endif
    dri->base.name = "gbm_tbm";
 
    return &dri->base;
index 40943759f17afb6896cc616a7dbbbe330d5e5e1a..cb62de47650e8eb295a0b06825f39f17e855fbd6 100644 (file)
@@ -2,6 +2,18 @@
 #define _GBM_TBM_H_
 
 #include <gbm.h>
+
+#ifdef USE_TBM_QUEUE
+#include <tbm_surface.h>
+#include <tbm_surface_queue.h>
+
+tbm_surface_queue_h
+gbm_tbm_get_surface_queue(struct gbm_surface* surf);
+
+tbm_surface_h
+gbm_tbm_get_surface(struct gbm_bo* bo);
+
+#else
 #include <tbm_bufmgr.h>
 
 struct gbm_tbm_device;
@@ -43,3 +55,4 @@ uint32_t
 gbm_tbm_bo_get_stride(struct gbm_tbm_bo *bo);
 
 #endif
+#endif
index 9dd9b71d8d28835f7600e1b519351942893699e0..9804d8191ac71d3df76c83f2cfccc43f93f65483 100644 (file)
@@ -31,6 +31,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include <tbm_bufmgr.h>
 #include <tbm_surface.h>
+#ifdef USE_TBM_QUEUE
+#include <tbm_surface_queue.h>
+#endif
+
 #include "gbm_tbm.h"
 #include "gbmint.h"
 
@@ -49,6 +53,10 @@ struct gbm_tbm_bo {
 struct gbm_tbm_surface {
    struct gbm_surface base;
    void *tbm_private;
+
+#ifdef USE_TBM_QUEUE
+   tbm_surface_queue_h queue;
+#endif
 };
 
 static inline struct gbm_tbm_device *
index 8042948ab0425eb0af186eecfd90822edaea40e9..7f2eb5bf62754c5b29f7bcca2b7091d569059a74 100644 (file)
@@ -13,6 +13,13 @@ AC_PROG_LIBTOOL
 PKG_CHECK_MODULES([TBM], [libtbm wayland-tbm-server], [have_tbm=yes], [have_tbm=no])
 if test x$have_tbm = xyes; then
    AC_DEFINE([HAVE_TBM], [1], [Build the tbm backend])
+
+   AC_ARG_ENABLE(tbm-queue, [--enable-tbm-queue],,
+                 enable_tbm_queue=no)
+   AM_CONDITIONAL(USE_TBM_QUEUE, test x$enable_tbm_queue = xyes)
+   if test x$enable_tbm_queue = xyes; then
+      AC_DEFINE([USE_TBM_QUEUE], [1], [Build gbm_tbm with TBM surface queue])
+   fi
 fi
 
 AM_CONDITIONAL(HAVE_TBM, test "x$have_tbm" = "xyes")
index 3a9e05fc5e54b651c0ca929fc777630cb5fe0719..adc4da515bc23be1f9dba4c7c729d13096b7c7b7 100644 (file)
@@ -30,7 +30,7 @@ Development header files for use with Wayland GBM
 %setup -q -n %{name}
 
 %build
-%reconfigure --disable-static
+%reconfigure --disable-static --enable-tbm-queue
 make libdir=%{_libdir} major_ver=%{MAJOR_VER} minor_ver=%{MINOR_VER}
 
 %install
index 92d472a07620a98104de5506b6441fec4527ade3..8312d3d62accc15b9feec9e09673469e31dccfb6 100644 (file)
--- a/src/gbm.h
+++ b/src/gbm.h
@@ -68,14 +68,6 @@ union gbm_bo_handle {
    uint64_t u64;
 };
 
-/** Format of the allocated buffer */
-enum gbm_bo_format {
-   /** RGB with 8 bits per channel in a 32 bit value */
-   GBM_BO_FORMAT_XRGB8888, 
-   /** ARGB with 8 bits per channel in a 32 bit value */
-   GBM_BO_FORMAT_ARGB8888
-};
-
 #define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
                              ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))