From 39476e06f2ce99aa0f3ebd0e7a56aa09e78498fd Mon Sep 17 00:00:00 2001 From: Konstantin Drabeniuk Date: Mon, 12 Jun 2017 14:00:41 +0300 Subject: [PATCH] add tbm_surface_internal_dump_with_scale_start() func. Change-Id: Id93ef300366a606c6111d04b9014488c4612a0a9 Signed-off-by: Konstantin Drabeniuk --- configure.ac | 5 +- packaging/libtbm.spec | 1 + src/tbm_surface_internal.c | 181 +++++++++++++++++++++++++++++++++++++++++---- src/tbm_surface_internal.h | 17 +++++ 4 files changed, 188 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index ac0d46f..c1ebbce 100644 --- a/configure.ac +++ b/configure.ac @@ -80,9 +80,10 @@ PKG_CHECK_MODULES(WL_CLIENT, wayland-client) PKG_CHECK_MODULES(WL_SERVER, wayland-server) PKG_CHECK_MODULES(WL_SCANNER, wayland-scanner) PKG_CHECK_MODULES(LIBPNG, libpng) +PKG_CHECK_MODULES(LIBPIXMAN, pixman-1) -LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $CAPI_CFLAGS $WL_CLIENT_CFLAGS $WL_SERVER_CFLAGS $LIBPNG_CFLAGS " -LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $CAPI_LIBS $WL_CLIENT_LIBS $WL_SERVER_LIBS $LIBPNG_LIBS " +LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $CAPI_CFLAGS $WL_CLIENT_CFLAGS $WL_SERVER_CFLAGS $LIBPNG_CFLAGS $LIBPIXMAN_CFLAGS " +LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $CAPI_LIBS $WL_CLIENT_LIBS $WL_SERVER_LIBS $LIBPNG_LIBS $LIBPIXMAN_LIBS " PKG_CHECK_EXISTS([dlog], [have_dlog="yes"], [have_dlog="no"]) AC_MSG_CHECKING([Have dlog logger]) diff --git a/packaging/libtbm.spec b/packaging/libtbm.spec index 2e3c263..069c1aa 100644 --- a/packaging/libtbm.spec +++ b/packaging/libtbm.spec @@ -17,6 +17,7 @@ BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(libpng) BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(pixman-1) %if %{with utest} BuildRequires: gtest-devel diff --git a/src/tbm_surface_internal.c b/src/tbm_surface_internal.c index c456e83..fd375a9 100644 --- a/src/tbm_surface_internal.c +++ b/src/tbm_surface_internal.c @@ -39,6 +39,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tbm_surface_internal.h" #include "list.h" #include +#include static tbm_bufmgr g_surface_bufmgr; static pthread_mutex_t tbm_surface_lock; @@ -1482,6 +1483,7 @@ struct _tbm_surface_dump_info { static tbm_surface_dump_info *g_dump_info = NULL; static const char *dump_postfix[2] = {"png", "yuv"}; +static double scale_factor; static void _tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, @@ -1664,6 +1666,8 @@ tbm_surface_internal_dump_start(char *path, int w, int h, int count) g_dump_info->path = path; g_dump_info->link = &g_dump_info->surface_list; + scale_factor = 0.0; + TBM_LOG_I("Dump Start.. path:%s, count:%d\n", g_dump_info->path, count); return; @@ -1689,6 +1693,16 @@ fail: } void +tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, int count, double scale) +{ + TBM_RETURN_IF_FAIL(scale > 0.0); + + tbm_surface_internal_dump_start(path, (int)(scale * w), (int)(scale * h), count); + + scale_factor = scale; +} + +void tbm_surface_internal_dump_end(void) { tbm_surface_dump_buf_info *buf_info = NULL, *tmp = NULL; @@ -1775,6 +1789,78 @@ tbm_surface_internal_dump_end(void) TBM_LOG_I("Dump End..\n"); } +static pixman_format_code_t +_tbm_surface_internal_pixman_format_get(tbm_format format) +{ + switch (format) { + case TBM_FORMAT_ARGB8888: + return PIXMAN_a8r8g8b8; + case TBM_FORMAT_XRGB8888: + return PIXMAN_x8r8g8b8; + default: + return 0; + } + + return 0; +} + +/** + * This function supports only if a buffer has below formats. + * - TBM_FORMAT_ARGB8888 + * - TBM_FORMAT_XRGB8888 + */ +static tbm_surface_error_e +_tbm_surface_internal_buffer_scale(void *src_ptr, void *dst_ptr, + int format, int src_stride, int src_w, int src_h, + int dst_stride, int dst_w, int dst_h) +{ + pixman_image_t *src_img = NULL, *dst_img = NULL; + pixman_format_code_t pixman_format; + pixman_transform_t t; + struct pixman_f_transform ft; + double scale_x, scale_y; + + TBM_RETURN_VAL_IF_FAIL(src_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION); + TBM_RETURN_VAL_IF_FAIL(dst_ptr != NULL, TBM_SURFACE_ERROR_INVALID_OPERATION); + + pixman_format = _tbm_surface_internal_pixman_format_get(format); + TBM_RETURN_VAL_IF_FAIL(pixman_format > 0, TBM_SURFACE_ERROR_INVALID_OPERATION); + + /* src */ + src_img = pixman_image_create_bits(pixman_format, src_w, src_h, + (uint32_t*)src_ptr, src_stride); + TBM_GOTO_VAL_IF_FAIL(src_img != NULL, cant_convert); + + /* dst */ + dst_img = pixman_image_create_bits(pixman_format, dst_w, dst_h, + (uint32_t*)dst_ptr, dst_stride); + TBM_GOTO_VAL_IF_FAIL(dst_img != NULL, cant_convert); + + pixman_f_transform_init_identity(&ft); + + scale_x = (double)src_w / dst_w; + scale_y = (double)src_h / dst_h; + + pixman_f_transform_scale(&ft, NULL, scale_x, scale_y); + pixman_f_transform_translate(&ft, NULL, 0, 0); + pixman_transform_from_pixman_f_transform(&t, &ft); + pixman_image_set_transform(src_img, &t); + + pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, + 0, 0, 0, 0, 0, 0, dst_w, dst_h); + + pixman_image_unref(src_img); + pixman_image_unref(dst_img); + + return TBM_SURFACE_ERROR_NONE; + +cant_convert: + if (src_img) + pixman_image_unref(src_img); + + return TBM_SURFACE_ERROR_INVALID_OPERATION; +} + void tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type) { @@ -1805,11 +1891,42 @@ tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type) ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info); TBM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE); - if (info.size > buf_info->size) { - TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n", - info.size, buf_info->size); - tbm_surface_unmap(surface); - return; + if (scale_factor > 0.0) { + const int bpp = 4; + + if (info.format != TBM_FORMAT_ARGB8888 && info.format != TBM_FORMAT_XRGB8888) { + TBM_LOG_W("Dump with scale skip. unsupported format(%s)\n", + _tbm_surface_internal_format_to_str(info.format)); + tbm_surface_unmap(surface); + return; + } + + memset(&buf_info->info, 0, sizeof(tbm_surface_info_s)); + + buf_info->info.width = info.width * scale_factor; + buf_info->info.height = info.height * scale_factor; + buf_info->info.format = info.format; + buf_info->info.bpp = tbm_surface_internal_get_bpp(buf_info->info.format); + buf_info->info.num_planes = 1; + buf_info->info.planes[0].stride = buf_info->info.width * bpp; + buf_info->info.size = buf_info->info.width * buf_info->info.height * bpp; + + if (buf_info->info.size > buf_info->size) { + TBM_LOG_W("Dump with scale skip. surface over created buffer size(%u, %d)\n", + buf_info->info.size, buf_info->size); + tbm_surface_unmap(surface); + return; + } + } else { + if (info.size > buf_info->size) { + TBM_LOG_W("Dump skip. surface over created buffer size(%u, %d)\n", + info.size, buf_info->size); + tbm_surface_unmap(surface); + return; + } + + /* make the file information */ + memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s)); } if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) @@ -1817,9 +1934,6 @@ tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type) else postfix = dump_postfix[1]; - /* make the file information */ - memcpy(&buf_info->info, &info, sizeof(tbm_surface_info_s)); - /* dump */ bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE); if (!bo_handle.ptr) { @@ -1836,7 +1950,24 @@ tbm_surface_internal_dump_buffer(tbm_surface_h surface, const char *type) "%10.3f_%03d_%p-%s.%s", _tbm_surface_internal_get_time(), g_dump_info->count++, surface, type, postfix); - memcpy(bo_handle.ptr, info.planes[0].ptr, info.size); + + if (scale_factor > 0.0) { + ret = _tbm_surface_internal_buffer_scale(info.planes[0].ptr, + bo_handle.ptr, + buf_info->info.format, + info.planes[0].stride, + info.width, info.height, + buf_info->info.planes[0].stride, + buf_info->info.width, + buf_info->info.height); + if (ret != TBM_SURFACE_ERROR_NONE) { + TBM_LOG_E("fail to scale buffer"); + tbm_bo_unmap(buf_info->bo); + tbm_surface_unmap(surface); + return; + } + } else + memcpy(bo_handle.ptr, info.planes[0].ptr, info.size); break; case TBM_FORMAT_YVU420: case TBM_FORMAT_YUV420: @@ -1905,7 +2036,7 @@ void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, tbm_surface_dump_buf_info *buf_info; struct list_head *next_link; tbm_bo_handle bo_handle; - int size; + int ret, size, dw = 0, dh = 0, dstride = 0; if (!g_dump_info) return; @@ -1921,7 +2052,16 @@ void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link); TBM_RETURN_IF_FAIL(buf_info != NULL); - size = stride * h; + if (scale_factor > 0.0) { + const int bpp = 4; + + dw = w * scale_factor; + dh = h * scale_factor; + dstride = dw * bpp; + size = dstride * dh; + } else + size = stride * h; + if (size > buf_info->size) { TBM_LOG_W("Dump skip. shm buffer over created buffer size(%d, %d)\n", size, buf_info->size); @@ -1938,14 +2078,27 @@ void tbm_surface_internal_dump_shm_buffer(void *ptr, int w, int h, int stride, snprintf(buf_info->name, sizeof(buf_info->name), "%10.3f_%03d-%s.%s", _tbm_surface_internal_get_time(), g_dump_info->count++, type, dump_postfix[0]); - memcpy(bo_handle.ptr, ptr, size); + if (scale_factor > 0.0) { + ret = _tbm_surface_internal_buffer_scale(ptr, bo_handle.ptr, + TBM_FORMAT_ARGB8888, stride, + w, h, dstride, dw, dh); + if (ret != TBM_SURFACE_ERROR_NONE) { + TBM_LOG_E("fail to scale buffer"); + tbm_bo_unmap(buf_info->bo); + return; + } + buf_info->shm_stride = dstride; + buf_info->shm_h = dh; + } else { + memcpy(bo_handle.ptr, ptr, size); + buf_info->shm_stride = stride; + buf_info->shm_h = h; + } tbm_bo_unmap(buf_info->bo); buf_info->dirty = 0; buf_info->dirty_shm = 1; - buf_info->shm_stride = stride; - buf_info->shm_h = h; if (g_dump_info->count == 1000) g_dump_info->count = 0; diff --git a/src/tbm_surface_internal.h b/src/tbm_surface_internal.h index 10f4daf..12dd3b1 100644 --- a/src/tbm_surface_internal.h +++ b/src/tbm_surface_internal.h @@ -419,6 +419,23 @@ int tbm_surface_internal_delete_user_data(tbm_surface_h surface, void tbm_surface_internal_dump_start(char *path, int w, int h, int count); /** + * @brief Start the dump with scale debugging. + * @details + * Dump with scale supports only if a buffer has below formats. + * - TBM_FORMAT_ARGB8888 + * - TBM_FORMAT_XRGB8888 + * @since_tizen 4.0 + * @param[in] path : the given dump path + * @param[in] w : the width of dump image + * @param[in] h : the height of dump image + * @param[in] count : the dump count number + * @param[in] scale : the scale factor + * @see #tdm_helper_dump_stop() + */ +void tbm_surface_internal_dump_with_scale_start(char *path, int w, int h, + int count, double scale); + +/** * @brief End the dump debugging. * @since_tizen 3.0 * @see #tdm_helper_dump_start() -- 2.7.4