1st implementation of tbm surface dump 32/67532/4 accepted/tizen/common/20160429.170300 accepted/tizen/ivi/20160429.011613 accepted/tizen/mobile/20160429.011551 accepted/tizen/tv/20160429.011559 accepted/tizen/wearable/20160429.011554 submit/tizen/20160428.080908
authorSooChan Lim <sc1.lim@samsung.com>
Wed, 27 Apr 2016 02:50:33 +0000 (11:50 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Wed, 27 Apr 2016 10:11:02 +0000 (19:11 +0900)
Change-Id: I2834e0957e96253f56eee234e8e4b861bcc53665

configure.ac
packaging/libtbm.spec
src/tbm_bufmgr_int.h [changed mode: 0644->0755]
src/tbm_surface_internal.c [changed mode: 0644->0755]
src/tbm_surface_internal.h [changed mode: 0644->0755]

index 2257156..f726daa 100644 (file)
@@ -73,9 +73,10 @@ PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
 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)
 
-LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $PTHREADSTUBS_CFLAGS $CAPI_CFLAGS $WL_CLIENT_CFLAGS $WL_SERVER_CFLAGS"
-LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $PTHREADSTUBS_LIBS $CAPI_LIBS $WL_CLIENT_LIBS $WL_SERVER_LIBS"
+LIBTBM_CFLAGS+="$LIBTBM_CFALGS $LIBDRM_CFLAGS $PTHREADSTUBS_CFLAGS $CAPI_CFLAGS $WL_CLIENT_CFLAGS $WL_SERVER_CFLAGS $LIBPNG_CFLAGS"
+LIBTBM_LIBS+="$LIBTBM_LIBS $LIBDRM_LIBS $PTHREADSTUBS_LIBS $CAPI_LIBS $WL_CLIENT_LIBS $WL_SERVER_LIBS $LIBPNG_LIBS"
 AC_SUBST(LIBTBM_CFLAGS)
 AC_SUBST(LIBTBM_LIBS)
 
index 5217c24..03f0f62 100644 (file)
@@ -15,6 +15,7 @@ BuildRequires:  pkgconfig(wayland-server)
 BuildRequires:  pkgconfig(wayland-client)
 BuildRequires:  pkgconfig(pthread-stubs)
 BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(libpng)
 
 %description
 Description: %{summary}
old mode 100644 (file)
new mode 100755 (executable)
index 36fc796..f0e116a
@@ -64,6 +64,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                return val;\
        } \
 }
+#define TBM_GOTO_VAL_IF_FAIL(cond, val) {\
+       if (!(cond)) {\
+               TBM_LOG("[%s] : '%s' failed.\n", __func__, #cond);\
+               goto val;\
+       } \
+}
 
 /* check flags */
 #define RETURN_CHECK_FLAG(cond) {\
old mode 100644 (file)
new mode 100755 (executable)
index 6aa6c31..de7c2a3
@@ -34,6 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tbm_bufmgr_int.h"
 #include "tbm_surface_internal.h"
 #include "list.h"
+#include <png.h>
 
 static tbm_bufmgr g_surface_bufmgr;
 static pthread_mutex_t tbm_surface_lock;
@@ -1137,3 +1138,316 @@ tbm_surface_internal_delete_user_data(tbm_surface_h surface,
        return 1;
 }
 
+typedef struct _tbm_surface_dump_info tbm_surface_dump_info;
+typedef struct _tbm_surface_dump_buf_info tbm_surface_dump_buf_info;
+
+struct _tbm_surface_dump_buf_info
+{
+       int index;
+       tbm_bo bo;
+       int size;
+       int dirty;
+       char name[1024];
+
+       tbm_surface_info_s info;
+
+       struct list_head link;
+};
+
+struct _tbm_surface_dump_info
+{
+       char *path;  // copy???
+       struct list_head *link;
+       struct list_head surface_list; /* link of surface */
+};
+
+static tbm_surface_dump_info *g_dump_info = NULL;
+static const char *dump_postfix[2] = {"png", "yuv"};
+
+#if 0
+static void
+_tbm_surface_internal_dump_file_raw(const char *file, void *data1, int size1, void *data2,
+                     int size2, void *data3, int size3)
+{
+       unsigned int *blocks;
+       FILE *fp = fopen(file, "w+");
+       TBM_RETURN_IF_FAIL(fp != NULL);
+
+       blocks = (unsigned int *)data1;
+       fwrite(blocks, 1, size1, fp);
+
+       if (size2 > 0) {
+               blocks = (unsigned int *)data2;
+               fwrite(blocks, 1, size2, fp);
+       }
+
+       if (size3 > 0) {
+               blocks = (unsigned int *)data3;
+               fwrite(blocks, 1, size3, fp);
+       }
+
+       fclose(fp);
+}
+#endif
+
+static void
+_tbm_surface_internal_dump_file_png(const char *file, const void *data, int width,
+                     int height)
+{
+       FILE *fp = fopen(file, "wb");
+       TBM_RETURN_IF_FAIL(fp != NULL);
+       int depth = 8;
+
+       png_structp pPngStruct =
+               png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (!pPngStruct) {
+               fclose(fp);
+               return;
+       }
+
+       png_infop pPngInfo = png_create_info_struct(pPngStruct);
+       if (!pPngInfo) {
+               png_destroy_write_struct(&pPngStruct, NULL);
+               fclose(fp);
+               return;
+       }
+
+       png_init_io(pPngStruct, fp);
+       png_set_IHDR(pPngStruct,
+                    pPngInfo,
+                    width,
+                    height,
+                    depth,
+                    PNG_COLOR_TYPE_RGBA,
+                    PNG_INTERLACE_NONE,
+                    PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+       png_set_bgr(pPngStruct);
+       png_write_info(pPngStruct, pPngInfo);
+
+       const int pixel_size = 4;       // RGBA
+       png_bytep *row_pointers =
+               png_malloc(pPngStruct, height * sizeof(png_byte *));
+
+       unsigned int *blocks = (unsigned int *)data;
+       int y = 0;
+       int x = 0;
+
+       for (; y < height; ++y) {
+               png_bytep row =
+                       png_malloc(pPngStruct, sizeof(png_byte) * width * pixel_size);
+               row_pointers[y] = (png_bytep)row;
+               for (x = 0; x < width; ++x) {
+                       unsigned int curBlock = blocks[y * width + x];
+                       row[x * pixel_size] = (curBlock & 0xFF);
+                       row[1 + x * pixel_size] = (curBlock >> 8) & 0xFF;
+                       row[2 + x * pixel_size] = (curBlock >> 16) & 0xFF;
+                       row[3 + x * pixel_size] = (curBlock >> 24) & 0xFF;
+               }
+       }
+
+       png_write_image(pPngStruct, row_pointers);
+       png_write_end(pPngStruct, pPngInfo);
+
+       for (y = 0; y < height; y++)
+               png_free(pPngStruct, row_pointers[y]);
+       png_free(pPngStruct, row_pointers);
+
+       png_destroy_write_struct(&pPngStruct, &pPngInfo);
+
+       fclose(fp);
+}
+
+void
+tbm_surface_internal_dump_start(char *path, int buffer_size, int count)
+{
+       TBM_RETURN_IF_FAIL(path != NULL);
+       TBM_RETURN_IF_FAIL(buffer_size > 0);
+       TBM_RETURN_IF_FAIL(count > 0);
+
+       tbm_surface_dump_buf_info *buf_info = NULL;
+       tbm_bo bo = NULL;
+       tbm_bo_handle bo_handle;
+       int i;
+
+       /* check running */
+       if (g_dump_info) {
+               TBM_LOG("[libtbm:%d] "
+                       "waring: %s:%d already running the tbm_surface_internal_dump.\n",
+                       getpid(), __func__, __LINE__);
+               return;
+       }
+
+       g_dump_info = calloc(1, sizeof (buffer_size *count));
+       TBM_RETURN_IF_FAIL(g_dump_info);
+
+       LIST_INITHEAD(&g_dump_info->surface_list);
+
+       for (i = 0; i < count; i++)     {
+               buf_info = calloc(1, sizeof (tbm_surface_dump_buf_info));
+               TBM_GOTO_VAL_IF_FAIL(buf_info, fail);
+               bo = tbm_bo_alloc(g_surface_bufmgr, buffer_size, TBM_BO_DEFAULT);
+               TBM_GOTO_VAL_IF_FAIL(bo, fail);
+
+               bo_handle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+               memset(bo_handle.ptr, 0x00, buffer_size);
+               tbm_bo_unmap(bo);
+
+               buf_info->index = i;
+               buf_info->bo = bo;
+               buf_info->size = buffer_size;
+
+               LIST_ADDTAIL(&buf_info->link, &g_dump_info->surface_list);
+       }
+
+       g_dump_info->path = path;
+       g_dump_info->link = &g_dump_info->surface_list;
+
+       TBM_LOG("Dump Start.. path:%s\n", g_dump_info->path);
+
+       return;
+fail:
+// TODO:
+       return;
+}
+
+void
+tbm_surface_internal_dump_end(void)
+{
+       tbm_surface_dump_buf_info *buf_info, *tmp;
+       char file[2048] = {0, };
+       tbm_bo_handle bo_handle;
+
+    if (!g_dump_info)
+               return;
+
+       /* make files */
+       if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
+               LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
+                       if (buf_info->dirty) {
+                               switch (buf_info->info.format) {
+                               case TBM_FORMAT_ARGB8888:
+                               case TBM_FORMAT_XRGB8888:
+                                       bo_handle = tbm_bo_map(buf_info->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
+                                       if (bo_handle.ptr == NULL)
+                                               continue;
+                                       snprintf(file, sizeof(file), "%s/%s", g_dump_info->path, buf_info->name);
+                                       TBM_LOG("Dump File.. %s generated.\n", file);
+                                       _tbm_surface_internal_dump_file_png(file, bo_handle.ptr,
+                                                                                       buf_info->info.planes[0].stride >> 2, buf_info->info.height);
+                                       break;
+                               case TBM_FORMAT_YVU420:
+                               case TBM_FORMAT_YUV420:
+                                       // TODO:
+                                       break;
+                               case TBM_FORMAT_NV12:
+                               case TBM_FORMAT_NV21:
+                                       // TODO:
+                                       break;
+                               case TBM_FORMAT_YUYV:
+                               case TBM_FORMAT_UYVY:
+                                       // TODO:
+                                       break;
+                               default:
+                                       //TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format));
+                                       TBM_LOG("can't dump\n");
+                                       tbm_bo_unmap(buf_info->bo);
+                                       return;
+                               }
+                       }
+               }
+       }
+
+
+       /* free resources */
+       if (!LIST_IS_EMPTY(&g_dump_info->surface_list)) {
+               LIST_FOR_EACH_ENTRY_SAFE(buf_info, tmp, &g_dump_info->surface_list, link) {
+               tbm_bo_unref(buf_info->bo);
+                       free(buf_info);
+               }
+       }
+
+       free(g_dump_info);
+       g_dump_info = NULL;
+
+       TBM_LOG("Dump End..\n");
+}
+
+void
+tbm_internal_surface_dump_buffer(tbm_surface_h surface, const char *type)
+{
+       TBM_RETURN_IF_FAIL(surface != NULL);
+       TBM_RETURN_IF_FAIL(type != NULL);
+
+       tbm_surface_dump_buf_info *buf_info;
+       tbm_surface_info_s info;
+       struct list_head *next_link;
+       tbm_bo_handle bo_handle;
+       int ret;
+       const char *postfix;
+
+    if (!g_dump_info)
+               return;
+
+       next_link = g_dump_info->link->next;
+       TBM_RETURN_IF_FAIL(next_link != NULL);
+
+       if (next_link == &g_dump_info->surface_list)
+       {
+               next_link = next_link->next;
+               TBM_RETURN_IF_FAIL(next_link != NULL);
+       }
+
+       buf_info = LIST_ENTRY(tbm_surface_dump_buf_info, next_link, link);
+       TBM_RETURN_IF_FAIL(buf_info != NULL);
+
+       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.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888)
+               postfix = dump_postfix[0];
+       else
+               postfix = dump_postfix[1];
+
+       /* make the file information */
+    snprintf(buf_info->name, sizeof(buf_info->name), "%d-%s.%s", buf_info->index, type, postfix);
+       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);
+       TBM_RETURN_IF_FAIL(bo_handle.ptr != NULL);
+
+       switch (info.format) {
+       case TBM_FORMAT_ARGB8888:
+       case TBM_FORMAT_XRGB8888:
+               memcpy(bo_handle.ptr, info.planes[0].ptr, info.size);
+               break;
+       case TBM_FORMAT_YVU420:
+       case TBM_FORMAT_YUV420:
+               // TODO:
+               break;
+       case TBM_FORMAT_NV12:
+       case TBM_FORMAT_NV21:
+               // TODO:
+               break;
+       case TBM_FORMAT_YUYV:
+       case TBM_FORMAT_UYVY:
+               // TODO:
+               break;
+       default:
+               //TDM_ERR("can't dump %c%c%c%c buffer", FOURCC_STR (info.format));
+               TBM_LOG("can't dump\n");
+               tbm_bo_unmap(buf_info->bo);
+               return;
+       }
+
+       tbm_bo_unmap(buf_info->bo);
+
+       tbm_surface_unmap(surface);
+
+       buf_info->dirty = 1;
+       g_dump_info->link = next_link;
+
+       TBM_LOG("Dump %s \n", buf_info->name);
+}
+
old mode 100644 (file)
new mode 100755 (executable)
index dc08067..083ef36
@@ -397,6 +397,42 @@ int tbm_surface_internal_get_user_data(tbm_surface_h surface, unsigned long key,
 int tbm_surface_internal_delete_user_data(tbm_surface_h surface,
                                          unsigned long key);
 
+/**
+ * @brief Start the dump debugging.
+ * @since_tizen 3.0
+ * @param[in] path The given dump path
+ * @param[in] buffer_size the buffer size of a dump image
+ * @param[in] count The dump count number
+ * @see #tdm_helper_dump_stop()
+ */
+void tbm_surface_internal_dump_start(char *path, int buffer_size, int count);
+
+/**
+ * @brief End the dump debugging.
+ * @since_tizen 3.0
+ * @see #tdm_helper_dump_start()
+ */
+void tbm_surface_internal_dump_end(void);
+
+/**
+ * @brief Dump a buffer
+ * @details
+ * This function supports only if a buffer has below formats.
+ * - TBM_FORMAT_ARGB8888
+ * - TBM_FORMAT_XRGB8888
+ * - TBM_FORMAT_YVU420
+ * - TBM_FORMAT_YUV420
+ * - TBM_FORMAT_NV12
+ * - TBM_FORMAT_NV21
+ * - TBM_FORMAT_YUYV
+ * - TBM_FORMAT_UYVY
+ * The filename extension should be "png" for TBM_FORMAT_ARGB8888 and TBM_FORMAT_XRGB8888
+ * or "yuv" for YUV formats.
+ * @param[in] surface a tbm surface
+ * @param[in] type   a string used by a file name.
+ */
+void tbm_internal_surface_dump_buffer(tbm_surface_h surface, const char *type);
+
 #ifdef __cplusplus
 }
 #endif