From: Sangjin Lee Date: Sat, 21 Nov 2015 12:34:37 +0000 (+0900) Subject: Use tbm surface queue X-Git-Tag: submit/tizen_tv/20151202.065316~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=36dde46fe1c1514334fd1896d4c78873f13fd332;p=platform%2Fcore%2Fuifw%2Flibgbm.git Use tbm surface queue Change-Id: I8023244921a39963c101d2835817ad4a275d3734 --- diff --git a/backends/tbm/gbm_tbm.c b/backends/tbm/gbm_tbm.c index f6560aa..e8adca4 100644 --- a/backends/tbm/gbm_tbm.c +++ b/backends/tbm/gbm_tbm.c @@ -33,10 +33,32 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "config.h" #include "gbm_tbmint.h" #include #include +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; diff --git a/backends/tbm/gbm_tbm.h b/backends/tbm/gbm_tbm.h index 4094375..cb62de4 100644 --- a/backends/tbm/gbm_tbm.h +++ b/backends/tbm/gbm_tbm.h @@ -2,6 +2,18 @@ #define _GBM_TBM_H_ #include + +#ifdef USE_TBM_QUEUE +#include +#include + +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 struct gbm_tbm_device; @@ -43,3 +55,4 @@ uint32_t gbm_tbm_bo_get_stride(struct gbm_tbm_bo *bo); #endif +#endif diff --git a/backends/tbm/gbm_tbmint.h b/backends/tbm/gbm_tbmint.h index 9dd9b71..9804d81 100644 --- a/backends/tbm/gbm_tbmint.h +++ b/backends/tbm/gbm_tbmint.h @@ -31,6 +31,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#ifdef USE_TBM_QUEUE +#include +#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 * diff --git a/configure.ac b/configure.ac index 8042948..7f2eb5b 100644 --- a/configure.ac +++ b/configure.ac @@ -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") diff --git a/packaging/libgbm.spec b/packaging/libgbm.spec index 3a9e05f..adc4da5 100644 --- a/packaging/libgbm.spec +++ b/packaging/libgbm.spec @@ -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 diff --git a/src/gbm.h b/src/gbm.h index 92d472a..8312d3d 100644 --- 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))