coregl_tracepath: Refactor function _dump_surface
[platform/core/uifw/coregl.git] / src / modules / tracepath / coregl_tracepath.c
index f4c51a9..4018097 100644 (file)
@@ -62,6 +62,9 @@ struct _Surface_Data {
        GLint                        tex_w;
        GLint                        tex_h;
        GLint                        tex_format;
+       GLint                        width;
+       GLint                        height;
+       GLint                        channel;
 };
 
 typedef struct _GLGlueFakeContext {
@@ -1245,347 +1248,323 @@ finish:
 }
 
 #include <png.h>
+struct png_state {
+       void *png_lib_handle;
+       png_structp (*dl_png_create_write_struct) (png_const_charp user_png_ver,
+                                                                                          png_voidp error_ptr,
+                                                                                          png_error_ptr error_fn,
+                                                                                          png_error_ptr warn_fn);
+       png_infop (*dl_png_create_info_struct) (png_structp png_ptr);
+       void (*dl_png_destroy_write_struct) (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr);
+       void (*dl_png_init_io) (png_structp png_ptr, png_FILE_p fp);
+       void (*dl_png_set_IHDR) (png_structp png_ptr, png_infop info_ptr, png_uint_32 width,
+                                                        png_uint_32 height, int bit_depth, int color_type,
+                                                        int interlace_method, int compression_method, int filter_method);
+       void (*dl_png_set_bKGD) (png_structp png_ptr, png_infop info_ptr, png_color_16p background);
+       void (*dl_png_set_bgr) (png_structp png_ptr);
+       void (*dl_png_write_info) (png_structp png_ptr, png_infop info_ptr);
+       void (*dl_png_write_image) (png_structp png_ptr, png_bytepp image);
+       void (*dl_png_write_end) (png_structp png_ptr, png_infop info_ptr);
+};
 
-void *png_lib_handle = NULL;
+static int
+_dump_surface_egl(Surface_Data *sdata, char name[], unsigned char **data, int *alldumpcount, int force_output)
+{
+       EGLConfig eglconfig;
+       GLenum format;
+       GLint asize, rsize, gsize, bsize;
 
-png_structp (*dl_png_create_write_struct) (png_const_charp user_png_ver,
-               png_voidp error_ptr,
-               png_error_ptr error_fn,
-               png_error_ptr warn_fn);
+       if (trace_surface_filter_type != 0 && trace_surface_filter_type != 1) {
+               return EGL_FALSE;
+       }
 
+       if (trace_surface_filter_handle != 0 &&
+                       trace_surface_filter_handle != (uintptr_t)sdata->surface) {
+               return EGL_FALSE;
+       }
 
-void (*dl_png_destroy_write_struct) (png_structpp png_ptr_ptr,
-                                                                        png_infopp info_ptr_ptr);
+       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_WIDTH, &sdata->width);
+       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_HEIGHT, &sdata->height);
+       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_CONFIG_ID, (GLint *)&eglconfig);
+       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_ALPHA_SIZE, &asize);
+       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_RED_SIZE, &rsize);
+       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_GREEN_SIZE, &gsize);
+       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_BLUE_SIZE, &bsize);
+
+       sdata->channel = 4;
+       if (gsize == 0) {
+               sdata->channel = 1;
+       }
+       if (rsize == 0) {
+               sdata->channel = 0;
+       }
 
+       if (sdata->width <= 0 || sdata->height <= 0 || sdata->channel <= 0) {
+               return EGL_FALSE;
+       }
 
-png_infop (*dl_png_create_info_struct) (png_structp png_ptr);
+       if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
+                       (trace_surface_filter_size_w != sdata->width || trace_surface_filter_size_h != sdata->height)) {
+               return EGL_FALSE;
+       }
 
-void (*dl_png_init_io) (png_structp png_ptr,
-                                               png_FILE_p fp);
+       if ((trace_surface_filter_period_begin > 0 ||
+                       trace_surface_filter_period_end > 0) &&
+                       (trace_surface_filter_period_begin > *alldumpcount ||
+                        trace_surface_filter_period_end < *alldumpcount)) {
+               *alldumpcount = *alldumpcount + 1;
+               sdata->dump_count++;
+               return EGL_FALSE;
+       }
 
+       TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n",
+                 name, sdata->width, sdata->height, sdata->channel);
 
-void (*dl_png_set_IHDR) (png_structp png_ptr,
-                                                png_infop info_ptr,
-                                                png_uint_32 width,
-                                                png_uint_32 height,
-                                                int bit_depth,
-                                                int color_type,
-                                                int interlace_method,
-                                                int compression_method,
-                                                int filter_method);
+       if (trace_surface_print_only_flag == 1 && force_output == 0) {
+               *alldumpcount = *alldumpcount + 1;
+               sdata->dump_count++;
+               return EGL_FALSE;
+       }
 
-void (*dl_png_set_bKGD) (png_structp png_ptr,
-                                                png_infop info_ptr,
-                                                png_color_16p background);
+       *data = (unsigned char *)calloc(1, sdata->width * sdata->height * sdata->channel * sizeof(unsigned char));
+       if (*data == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to allocate memory");
+               return EGL_FALSE;
+       }
 
-void (*dl_png_set_bgr) (png_structp png_ptr);
+       GLint oldfb;
+       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
+       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-void (*dl_png_write_info) (png_structp png_ptr,
-                                                  png_infop info_ptr);
+       format = (sdata->channel == 4) ? GL_RGBA : GL_ALPHA;
+       _orig_tracepath_glReadPixels(0, 0, sdata->width, sdata->height, format, GL_UNSIGNED_BYTE, *data);
 
-void (*dl_png_write_image) (png_structp png_ptr,
-                                                       png_bytepp image);
+       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
 
-void (*dl_png_write_end) (png_structp png_ptr,
-                                                 png_infop info_ptr);
+       return EGL_TRUE;
+}
 
-static void
-_dump_surface(int force_output, int type, const char *position,
-                         Surface_Data *sdata)
+static int
+_dump_surface_fbo(Surface_Data *sdata, char name[], unsigned char **data, int *alldumpcount, int force_output)
 {
-       static int alldumpcount = 0;
-       unsigned char *data = NULL;
-       EGLint width = -1, height = -1, channel = -1;
-       char name[200];
-       FILE *write_fd = NULL;
-       png_struct *png = NULL;
-       png_info *info = NULL;
-       png_byte **rows = NULL;
+       GLint oldfb;
+       GLenum format;
        GLenum ret_value = _COREGL_INT_INIT_VALUE;
 
-       if (!png_lib_handle) {
-               png_lib_handle = dlopen("libpng16.so.16", RTLD_NOW);
-
-               dl_png_create_write_struct = dlsym(png_lib_handle, "png_create_write_struct");
-               dl_png_destroy_write_struct = dlsym(png_lib_handle, "png_destroy_write_struct");
-               dl_png_create_info_struct = dlsym(png_lib_handle, "png_create_info_struct");
-
-               dl_png_init_io = dlsym(png_lib_handle, "png_init_io");
+       if (sdata->fbo == 0) {
+               return EGL_FALSE;
+       }
 
-               dl_png_set_IHDR = dlsym(png_lib_handle, "png_set_IHDR");
-               dl_png_set_bKGD = dlsym(png_lib_handle, "png_set_bKGD");
-               dl_png_set_bgr = dlsym(png_lib_handle, "png_set_bgr");
+       if (trace_surface_filter_type != 0 && trace_surface_filter_type != 2) {
+               return EGL_FALSE;
+       }
 
-               dl_png_write_info = dlsym(png_lib_handle, "png_write_info");
-               dl_png_write_image = dlsym(png_lib_handle, "png_write_image");
-               dl_png_write_end = dlsym(png_lib_handle, "png_write_end");
+       if (trace_surface_filter_handle != 0 &&
+                       trace_surface_filter_handle != (uintptr_t)sdata->tex &&
+                       trace_surface_filter_handle != (uintptr_t)sdata->rb) {
+               return EGL_FALSE;
        }
 
-       {
-               if (!png_lib_handle ||
-                               dl_png_create_write_struct == NULL ||
-                               dl_png_destroy_write_struct == NULL ||
-                               dl_png_create_info_struct == NULL ||
-                               dl_png_init_io == NULL ||
-                               dl_png_set_IHDR == NULL ||
-                               dl_png_set_bKGD == NULL ||
-                               dl_png_set_bgr == NULL ||
-                               dl_png_write_info == NULL ||
-                               dl_png_write_image == NULL ||
-                               dl_png_write_end == NULL) {
-                       COREGL_ERR("Can't trace surface : Failed to use libpng (recommend : 1.2.50-3.4)");
-                       goto finish;
-               }
+       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
+       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
 
-               if (trace_surface_sequence_sort_flag == 1)
-                       snprintf(name, sizeof(name), "[%d (%06d)%p-%p] %s %04d (%s).png", getpid(),
-                                        alldumpcount,
-                                        sdata->display, sdata->context, sdata->trace_data.name, sdata->dump_count,
-                                        position);
-               else
-                       snprintf(name, sizeof(name), "[%d %p-%p] %s %04d (%s).png", getpid(),
-                                        sdata->display,
-                                        sdata->context, sdata->trace_data.name, sdata->dump_count, position);
-
-               if (!strncmp(sdata->trace_data.name, "EGL", 3) && type != 2) {
-                       // EGL
-                       if (trace_surface_filter_type != 0 &&
-                                       trace_surface_filter_type != 1) goto finish;;
-
-                       if (trace_surface_filter_handle != 0 &&
-                                       trace_surface_filter_handle != (uintptr_t)sdata->surface) goto finish;
-
-                       EGLConfig eglconfig;
-                       GLint asize, rsize, gsize, bsize;
-                       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_WIDTH,
-                                                                                       &width);
-                       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_HEIGHT,
-                                                                                       &height);
-                       _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_CONFIG_ID,
-                                                                                       (GLint *)&eglconfig);
-                       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_ALPHA_SIZE,
-                                                                                          &asize);
-                       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_RED_SIZE,
-                                                                                          &rsize);
-                       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_GREEN_SIZE,
-                                                                                          &gsize);
-                       _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_BLUE_SIZE,
-                                                                                          &bsize);
-                       channel = 4;
-                       if (asize == 0) channel = 3;
-                       if (bsize == 0) channel = 2;
-                       if (gsize == 0) channel = 1;
-                       if (rsize == 0) channel = 0;
-
-                       if (channel == 2) channel = 3;
-                       if (width <= 0 || height <= 0 || channel <= 0) goto finish;
-                       if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
-                                       (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
-                               goto finish;
-
-                       if ((trace_surface_filter_period_begin > 0 ||
-                                       trace_surface_filter_period_end > 0) &&
-                                       (trace_surface_filter_period_begin > alldumpcount ||
-                                        trace_surface_filter_period_end < alldumpcount)) {
-                               alldumpcount++;
-                               sdata->dump_count++;
-                               goto finish;
-                       }
+       if (driver_gl_version >= 2) {
+               ret_value = _orig_tracepath_glCheckFramebufferStatus(GL_FRAMEBUFFER);
+       }
+       else {
+               ret_value = _orig_tracepath_glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
+       }
 
-                       if (channel == 3) channel = 4;
+       if (ret_value == GL_FRAMEBUFFER_COMPLETE) {
+               _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
+               sdata->width = sdata->tex_w;
+               sdata->height = sdata->tex_h;
+               sdata->channel = sdata->tex_format;
 
-                       TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
-                                 width, height, channel);
-                       if (trace_surface_print_only_flag == 1 && force_output == 0) {
-                               alldumpcount++;
-                               sdata->dump_count++;
-                               goto finish;
-                       }
+               if (sdata->channel == 2) {
+                       sdata->channel = 3;
+               }
 
-                       data = (unsigned char *)calloc(1,
-                                                                                  width * height * channel * sizeof(unsigned char));
-                       if (data == NULL) {
-                               COREGL_ERR("Can't trace surface : Failed to allocate memory");
-                               goto finish;
-                       }
+               if (sdata->width <= 0 || sdata->height <= 0 || sdata->channel <= 0) {
+                       return EGL_FALSE;
+               }
 
-                       GLint oldfb;
-                       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
-                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, 0);
+               if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
+                               (trace_surface_filter_size_w != sdata->width || trace_surface_filter_size_h != sdata->height)) {
+                       return EGL_FALSE;
+               }
 
-                       switch (channel) {
-                       case 4:
-                               _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
-                                                                                        data);
-                               break;
-                               //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
-                       case 1:
-                               _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
-                                                                                        data);
-                               break;
-                       }
+               if ((trace_surface_filter_period_begin > 0 ||
+                               trace_surface_filter_period_end > 0) &&
+                               (trace_surface_filter_period_begin > *alldumpcount ||
+                                trace_surface_filter_period_end < *alldumpcount)) {
+                       *alldumpcount = *alldumpcount + 1;
+                       sdata->dump_count++;
+                       return EGL_FALSE;
+               }
 
-                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
+               TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
+                         sdata->width, sdata->height, sdata->channel);
+               if (trace_surface_print_only_flag == 1 && force_output == 0) {
+                       *alldumpcount = *alldumpcount + 1;
+                       sdata->dump_count++;
+                       return EGL_FALSE;
                }
-               if (!strncmp(sdata->trace_data.name, "FBO", 3) && type != 1) {
-                       // FBO
-                       if (sdata->fbo == 0) goto finish;
-
-                       if (trace_surface_filter_type != 0 &&
-                                       trace_surface_filter_type != 2) goto finish;
-
-                       if (trace_surface_filter_handle != 0 &&
-                                       trace_surface_filter_handle != (uintptr_t)sdata->tex &&
-                                       trace_surface_filter_handle != (uintptr_t)sdata->rb) goto finish;
-
-                       GLint oldfb;
-                       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
-                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
-
-                       if (driver_gl_version >= 2)
-                               ret_value = _orig_tracepath_glCheckFramebufferStatus(GL_FRAMEBUFFER);
-                       else
-                               ret_value = _orig_tracepath_glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
-                       if (ret_value == GL_FRAMEBUFFER_COMPLETE) {
-                               _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
-                               width = sdata->tex_w;
-                               height = sdata->tex_h;
-                               channel = sdata->tex_format;
-
-                               if (channel == 2) channel = 3;
-                               if (width <= 0 || height <= 0 || channel <= 0) goto finish;
-                               if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
-                                               (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
-                                       goto finish;
-
-                               if ((trace_surface_filter_period_begin > 0 ||
-                                               trace_surface_filter_period_end > 0) &&
-                                               (trace_surface_filter_period_begin > alldumpcount ||
-                                                trace_surface_filter_period_end < alldumpcount)) {
-                                       alldumpcount++;
-                                       sdata->dump_count++;
-                                       goto finish;
-                               }
 
-                               TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
-                                         width, height, channel);
-                               if (trace_surface_print_only_flag == 1 && force_output == 0) {
-                                       alldumpcount++;
-                                       sdata->dump_count++;
-                                       goto finish;
-                               }
+               if (sdata->channel == 3) {
+                       sdata->channel = 4;
+               }
 
-                               if (channel == 3) channel = 4;
+               *data = (unsigned char *)calloc(1, sdata->width * sdata->height * sdata->channel * sizeof(unsigned char));
+               if (*data == NULL) {
+                       COREGL_ERR("Can't trace surface : Failed to allocate memory");
+                       return EGL_FALSE;
+               }
 
-                               data = (unsigned char *)calloc(1,
-                                                                                          width * height * channel * sizeof(unsigned char));
-                               if (data == NULL) {
-                                       COREGL_ERR("Can't trace surface : Failed to allocate memory");
-                                       goto finish;
-                               }
+               _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
+               int atttype = _COREGL_INT_INIT_VALUE;
+               if (driver_gl_version >= 2) {
+                       _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
+               }
+               else {
+                       _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
+                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
+               }
 
-                               _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
-                               int atttype = _COREGL_INT_INIT_VALUE;
-                               if (driver_gl_version >= 2)
-                                       _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
-                                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
-                               else
-                                       _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
-                                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
-                               AST(atttype != sdata->tex);
-                               int attname = _COREGL_INT_INIT_VALUE;
-                               if (driver_gl_version >= 2)
-                                       _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
-                                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
-                               else
-                                       _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
-                                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
-                               switch (atttype) {
-                               case GL_TEXTURE:
-                                       AST(attname == sdata->tex);
-                                       break;
-                               case GL_RENDERBUFFER:
-                                       AST(attname == sdata->rb);
-                                       break;
-                               }
+               AST(atttype != sdata->tex);
+               int attname = _COREGL_INT_INIT_VALUE;
+               if (driver_gl_version >= 2) {
+                       _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
+               }
+               else {
+                       _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
+                                       GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
+               }
 
-                               switch (channel) {
-                               case 4:
-                                       _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
-                                                                                                data);
-                                       break;
-                                       //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
-                               case 1:
-                                       _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
-                                                                                                data);
-                                       break;
-                               }
-                       }
-                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
+               switch (atttype) {
+               case GL_TEXTURE:
+                       AST(attname == sdata->tex);
+                       break;
+               case GL_RENDERBUFFER:
+                       AST(attname == sdata->rb);
+                       break;
                }
 
+               format = (sdata->channel == 4) ? GL_RGBA : GL_ALPHA;
+               _orig_tracepath_glReadPixels(0, 0, sdata->width, sdata->height, format, GL_UNSIGNED_BYTE, *data);
+       }
+       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
 
+       return EGL_TRUE;
+}
 
-               if (data == NULL) goto finish;
+static void
+_dump_surface(int force_output, int type, const char *position, Surface_Data *sdata)
+{
+       static int alldumpcount = 0;
+       unsigned char *data = NULL;
+       char name[200];
+       FILE *write_fd = NULL;
+       png_struct *png = NULL;
+       png_info *info = NULL;
+       png_byte **rows = NULL;
+       struct png_state state = { NULL };
+
+       if (!state.png_lib_handle) {
+               state.png_lib_handle = dlopen("libpng16.so.16", RTLD_NOW);
+               state.dl_png_create_write_struct = dlsym(state.png_lib_handle, "png_create_write_struct");
+               state.dl_png_destroy_write_struct = dlsym(state.png_lib_handle, "png_destroy_write_struct");
+               state.dl_png_create_info_struct = dlsym(state.png_lib_handle, "png_create_info_struct");
+               state.dl_png_init_io = dlsym(state.png_lib_handle, "png_init_io");
+               state.dl_png_set_IHDR = dlsym(state.png_lib_handle, "png_set_IHDR");
+               state.dl_png_set_bKGD = dlsym(state.png_lib_handle, "png_set_bKGD");
+               state.dl_png_set_bgr = dlsym(state.png_lib_handle, "png_set_bgr");
+               state.dl_png_write_info = dlsym(state.png_lib_handle, "png_write_info");
+               state.dl_png_write_image = dlsym(state.png_lib_handle, "png_write_image");
+               state.dl_png_write_end = dlsym(state.png_lib_handle, "png_write_end");
+       }
 
-               unlink(name);
-               write_fd = fopen(name, "wb");
+       if (!state.png_lib_handle ||
+                       state.dl_png_create_write_struct == NULL ||
+                       state.dl_png_destroy_write_struct == NULL ||
+                       state.dl_png_create_info_struct == NULL ||
+                       state.dl_png_init_io == NULL ||
+                       state.dl_png_set_IHDR == NULL ||
+                       state.dl_png_set_bKGD == NULL ||
+                       state.dl_png_set_bgr == NULL ||
+                       state.dl_png_write_info == NULL ||
+                       state.dl_png_write_image == NULL ||
+                       state.dl_png_write_end == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to use libpng (recommend : 1.2.50-3.4)");
+               goto finish;
+       }
 
-               if (write_fd == NULL) {
-                       COREGL_ERR("Can't trace surface : Failed to create png file");
+       if (trace_surface_sequence_sort_flag == 1) {
+               snprintf(name, sizeof(name), "[%d (%06d)%p-%p] %s %04d (%s).png", getpid(),
+                                alldumpcount, sdata->display, sdata->context, sdata->trace_data.name,
+                                sdata->dump_count, position);
+       }
+       else {
+               snprintf(name, sizeof(name), "[%d %p-%p] %s %04d (%s).png", getpid(),
+                                sdata->display, sdata->context, sdata->trace_data.name,
+                                sdata->dump_count, position);
+       }
+
+       if (!strncmp(sdata->trace_data.name, "EGL", 3) && type != 2) {
+               if(_dump_surface_egl(sdata, name, &data, &alldumpcount, force_output) == EGL_FALSE) {
                        goto finish;
                }
-
-               rows = (png_byte **)malloc(height * sizeof(png_byte *));
-               if (rows == NULL) {
-                       COREGL_ERR("Can't trace surface : Failed to allocate memory");
+       } else if (!strncmp(sdata->trace_data.name, "FBO", 3) && type != 1) {
+               if(_dump_surface_fbo(sdata, name, &data, &alldumpcount, force_output) == EGL_FALSE) {
                        goto finish;
                }
+       }
 
-               for (int i = 0; i < height; i++) {
-                       rows[i] = data + (height - i - 1) * (width * channel);
-               }
+       unlink(name);
+       write_fd = fopen(name, "wb");
 
-               png = dl_png_create_write_struct(PNG_LIBPNG_VER_STRING,
-                                                                                NULL,
-                                                                                NULL,
-                                                                                NULL);
-               if (png == NULL) {
-                       COREGL_ERR("Can't trace surface : Failed to create write structure of png file");
-                       goto finish;
-               }
+       if (write_fd == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to create png file");
+               goto finish;
+       }
 
-               info = dl_png_create_info_struct(png);
-               if (info == NULL) {
-                       COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
-                       goto finish;
-               }
+       rows = (png_byte **)malloc(sdata->height * sizeof(png_byte *));
+       if (rows == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to allocate memory");
+               goto finish;
+       }
 
-               dl_png_init_io(png, write_fd);
+       for (int i = 0; i < sdata->height; i++) {
+               rows[i] = data + (sdata->height - i - 1) * (sdata->width * sdata->channel);
+       }
 
-               switch (channel) {
-               case 4:
-                       dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
-                                                       PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-                       break;
-                       //case 3: dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); break;
-               case 1:
-                       dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY,
-                                                       PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-                       break;
-               }
+       png = state.dl_png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (png == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to create write structure of png file");
+               goto finish;
+       }
 
-               dl_png_write_info(png, info);
+       info = state.dl_png_create_info_struct(png);
+       if (info == NULL) {
+               COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
+               goto finish;
+       }
 
-               dl_png_write_image(png, rows);
+       state.dl_png_init_io(png, write_fd);
 
-               dl_png_write_end(png, info);
+       int bit_depth = (sdata->channel == 4) ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_GRAY;
+       state.dl_png_set_IHDR(png, info, sdata->width, sdata->height, 8, bit_depth,
+                                                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
-               dl_png_destroy_write_struct(&png, &info);
+       state.dl_png_write_info(png, info);
+       state.dl_png_write_image(png, rows);
+       state.dl_png_write_end(png, info);
+       state.dl_png_destroy_write_struct(&png, &info);
 
-               alldumpcount++;
-               sdata->dump_count++;
-       }
+       alldumpcount++;
+       sdata->dump_count++;
 
        goto finish;
 
@@ -1594,22 +1573,32 @@ finish:
                free(data);
                data = NULL;
        }
+
+       if(state.png_lib_handle != NULL) {
+               dlclose(state.png_lib_handle);
+               state.png_lib_handle = NULL;
+       }
+
        if (write_fd != NULL) {
                fclose(write_fd);
                write_fd = NULL;
        }
+
        if (rows != NULL) {
                free(rows);
                rows = NULL;
        }
+
        if (png != NULL) {
                if (info != NULL) {
-                       if (dl_png_destroy_write_struct)
-                               dl_png_destroy_write_struct(&png, &info);
+                       if (state.dl_png_destroy_write_struct) {
+                               state.dl_png_destroy_write_struct(&png, &info);
+                       }
                        info = NULL;
                } else {
-                       if (dl_png_destroy_write_struct)
-                               dl_png_destroy_write_struct(&png, NULL);
+                       if (state.dl_png_destroy_write_struct) {
+                               state.dl_png_destroy_write_struct(&png, NULL);
+                       }
                }
                png = NULL;
        }