[Title] Released a new feature 'COREGL_TRACE_SURFACE'
authorHaegeun Park <haegeun.park@samsung.com>
Wed, 21 Aug 2013 13:29:06 +0000 (06:29 -0700)
committerHaegeun Park <haegeun.park@samsung.com>
Mon, 26 Aug 2013 04:59:11 +0000 (21:59 -0700)
[Issue#]
[Problem]
[Cause]
[Solution]
- COREGL_TRACE_SURFACE=1 : enable surface trace.
                           png files will be dumped from EGLsurface & FBO
* Options
  - COREGL_TRACE_SURFACE_SEQUENCE_SORT=1 : dumps png file with sequence order (sort by time).
                                         default : sort by type
  - COREGL_TRACE_SURFACE_PRINT_ONLY=1 : print only. png file will not be generated
* Filters
  - COREGL_TRACE_SURFACE_FILTER_PERIOD=30~40 : dumps only frame30 to frame40
  - COREGL_TRACE_SURFACE_FILTER_TYPE=EGL|FBO : dumps only EGLsurfaces or FBOs
  - COREGL_TRACE_SURFACE_FILTER_HANDLE=0x2342122 : dumps only 0x2342122 surface
  - COREGL_TRACE_SURFACE_FILTER_FILTER_SIZE=320x200 : dumps only 320x200 surfaces
  - Supports combinations with others
* GDB support
  - (in gdb) p coregl_dump_surface() : dumps all surfaces at that time
  - Supports combinatons with filters
  - With print only option, only coregl_dump_surface() will generate png file.

include/EGL/sym_egl.h
src/coregl_internal.h
src/coregl_trace.c
src/headers/sym_egl.h
src/modules/fastpath/coregl_fastpath.c
src/modules/tracepath/coregl_tracepath.c
src/modules/tracepath/coregl_tracepath.h
src/modules/tracepath/coregl_tracepath_egl.c
src/modules/tracepath/coregl_tracepath_gl.c

index 4e1c6ca..38f512d 100644 (file)
@@ -84,6 +84,7 @@ _COREGL_EXT_SYMBOL_ALIAS(eglUnlockSurfaceKHR, eglUnlockSurface)
 
 // Verified extensions
 _COREGL_EXT_SYMBOL_FASTPATH_PASS(eglSwapBuffersRegionEXT)
+_COREGL_EXT_SYMBOL_FASTPATH_PASS(eglSwapBuffersRegionSEC)
 
 // Blocked extensions
 //_COREGL_EXT_SYMBOL_FASTPATH_BLOCK()
index 1942c57..fb05065 100644 (file)
@@ -94,11 +94,18 @@ extern int                 trace_api_flag;
 extern int                 trace_api_all_flag;
 extern int                 trace_mem_flag;
 extern int                 trace_mem_all_flag;
-extern int                 trace_surface_flag;
-extern int                 trace_surface_all_flag;
 extern int                 trace_ctx_flag;
 extern int                 trace_ctx_force_flag;
 extern int                 trace_state_flag;
+extern int                 trace_surface_flag;
+extern int                 trace_surface_sequence_sort_flag;
+extern int                 trace_surface_filter_period_begin;
+extern int                 trace_surface_filter_period_end;
+extern int                 trace_surface_filter_type;
+extern int                 trace_surface_filter_handle;
+extern int                 trace_surface_filter_size_w;
+extern int                 trace_surface_filter_size_h;
+extern int                 trace_surface_print_only_flag;
 
 #define USE_TRACEPATH          (trace_api_flag == 1 || trace_ctx_flag == 1 || trace_state_flag == 1 || trace_mem_flag == 1 || trace_surface_flag == 1)
 
index c72f398..d86f33d 100644 (file)
@@ -10,9 +10,17 @@ int                 trace_ctx_flag = 0;
 int                 trace_ctx_force_flag = 0;
 int                 trace_mem_flag = 0;
 int                 trace_mem_all_flag = 0;
+int                 trace_state_flag = 0;
 int                 trace_surface_flag = 0;
 int                 trace_surface_all_flag = 0;
-int                 trace_state_flag = 0;
+int                 trace_surface_sequence_sort_flag = 0;
+int                 trace_surface_filter_period_begin = 0;
+int                 trace_surface_filter_period_end = 0;
+int                 trace_surface_filter_type = 0;
+int                 trace_surface_filter_handle = 0;
+int                 trace_surface_filter_size_w = 0;
+int                 trace_surface_filter_size_h = 0;
+int                 trace_surface_print_only_flag = 0;
 
 General_Trace_List *thread_trace_list = NULL;
 Mutex               general_trace_lists_access_mutex = MUTEX_INITIALIZER;
index 4e1c6ca..38f512d 100644 (file)
@@ -84,6 +84,7 @@ _COREGL_EXT_SYMBOL_ALIAS(eglUnlockSurfaceKHR, eglUnlockSurface)
 
 // Verified extensions
 _COREGL_EXT_SYMBOL_FASTPATH_PASS(eglSwapBuffersRegionEXT)
+_COREGL_EXT_SYMBOL_FASTPATH_PASS(eglSwapBuffersRegionSEC)
 
 // Blocked extensions
 //_COREGL_EXT_SYMBOL_FASTPATH_BLOCK()
index 963a3a3..99a472e 100644 (file)
@@ -813,6 +813,7 @@ fastpath_sostate_set_object_tag(GL_Shared_Object_State *sostate, GL_Object_Type
 
        FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object);
 
+       AST(object->tag == NULL);
        object->tag = tag;
        ret = 1;
        goto finish;
index f9efa31..8eea9f9 100644 (file)
@@ -53,7 +53,13 @@ struct _Surface_Data
        GLDisplay                    display;
        GLSurface                    surface;
        GLContext                    context;
+       GLint                        fbo;
+       GLint                        tex;
+       GLint                        rb;
        int                          dump_count;
+       GLint                        tex_w;
+       GLint                        tex_h;
+       GLint                        tex_format;
 };
 
 typedef struct _GLGlueFakeContext
@@ -117,7 +123,83 @@ init_modules_tracepath()
 #endif
 #ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
        trace_surface_flag = atoi(get_env_setting("COREGL_TRACE_SURFACE"));
-       trace_surface_all_flag = atoi(get_env_setting("COREGL_TRACE_SURFACE_ALL"));
+       trace_surface_sequence_sort_flag = atoi(get_env_setting("COREGL_TRACE_SURFACE_SEQUENCE_SORT"));
+       trace_surface_print_only_flag = atoi(get_env_setting("COREGL_TRACE_SURFACE_PRINT_ONLY"));
+
+       { // COREGL_TRACE_SURFACE_FILTER_PERIOD=40~60
+               char tmp[64] = { 0 }, *tmpp = NULL;
+               strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_PERIOD"), 64);
+               for (tmpp = &tmp[0]; ; tmpp++)
+               {
+                       if (*tmpp == 0x00) break;
+                       if (*tmpp == '~')
+                       {
+                               *tmpp = 0x00;
+                               trace_surface_filter_period_begin = atoi(tmp);
+                               trace_surface_filter_period_end = atoi(tmpp + 1);
+                               break;
+                       }
+               }
+       }
+
+       { // COREGL_TRACE_SURFACE_FILTER_TYPE=EGL|FBO
+               char tmp[64] = { 0 };
+               strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_TYPE"), 64);
+               if (strcmp(tmp, "EGL") == 0) trace_surface_filter_type = 1;
+               if (strcmp(tmp, "FBO") == 0) trace_surface_filter_type = 2;
+       }
+
+       { // COREGL_TRACE_SURFACE_FILTER_HANDLE=0x3234
+               char tmp[64] = { 0 }, *tmpp = NULL;
+               strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_HANDLE"), 64);
+               if (tmp[0] == '0' && tmp[1] == 'x')
+               {
+                       for (tmpp = &tmp[2]; ; tmpp++)
+                       {
+                               if (*tmpp == 0x00) break;
+                               trace_surface_filter_handle *= 16;
+                               switch (*tmpp)
+                               {
+                                       case '1' : trace_surface_filter_handle += 1; break;
+                                       case '2' : trace_surface_filter_handle += 2; break;
+                                       case '3' : trace_surface_filter_handle += 3; break;
+                                       case '4' : trace_surface_filter_handle += 4; break;
+                                       case '5' : trace_surface_filter_handle += 5; break;
+                                       case '6' : trace_surface_filter_handle += 6; break;
+                                       case '7' : trace_surface_filter_handle += 7; break;
+                                       case '8' : trace_surface_filter_handle += 8; break;
+                                       case '9' : trace_surface_filter_handle += 9; break;
+                                       case 'A' : case 'a' : trace_surface_filter_handle += 10; break;
+                                       case 'B' : case 'b' : trace_surface_filter_handle += 11; break;
+                                       case 'C' : case 'c' : trace_surface_filter_handle += 12; break;
+                                       case 'D' : case 'd' : trace_surface_filter_handle += 13; break;
+                                       case 'E' : case 'e' : trace_surface_filter_handle += 14; break;
+                                       case 'F' : case 'f' : trace_surface_filter_handle += 15; break;
+                               }
+                       }
+               }
+               else
+               {
+                       trace_surface_filter_handle = atoi(tmp);
+               }
+       }
+
+       { // COREGL_TRACE_SURFACE_FILTER_SIZE=640x480
+               char tmp[64] = { 0 }, *tmpp = NULL;
+               strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_SIZE"), 64);
+               for (tmpp = &tmp[0]; ; tmpp++)
+               {
+                       if (*tmpp == 0x00) break;
+                       if (*tmpp == 'x')
+                       {
+                               *tmpp = 0x00;
+                               trace_surface_filter_size_w = atoi(tmp);
+                               trace_surface_filter_size_h = atoi(tmpp + 1);
+                               break;
+                       }
+               }
+       }
+
 #endif
 #ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
        trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
@@ -148,7 +230,15 @@ init_modules_tracepath()
                }
                if (trace_surface_flag == 1) {
                        COREGL_LOG("\E[40;36;1m(SURFACE)\E[0m ");
-                       if (trace_surface_all_flag == 1) COREGL_LOG("\E[40;36;1m(SURFACE-ALL)\E[0m ");
+                       if (trace_surface_sequence_sort_flag == 1) COREGL_LOG("\E[40;36;1m(SURFACE-SEQUENCE SORT)\E[0m ");
+                       if (trace_surface_print_only_flag == 1) COREGL_LOG("\E[40;36;1m(PRINT ONLY)\E[0m ");
+                       if (trace_surface_filter_period_begin != 0 || trace_surface_filter_period_end != 0)
+                               COREGL_LOG("\E[40;36;1m(SURFACE-PERIOD:%d~%d)\E[0m ", trace_surface_filter_period_begin, trace_surface_filter_period_end);
+                       if (trace_surface_filter_type == 1) COREGL_LOG("\E[40;36;1m(SURFACE-TYPE:EGL)\E[0m ");
+                       if (trace_surface_filter_type == 2) COREGL_LOG("\E[40;36;1m(SURFACE-TYPE:FBO)\E[0m ");
+                       if (trace_surface_filter_handle != 0) COREGL_LOG("\E[40;36;1m(SURFACE-HANDLE:%p(%d))\E[0m ", trace_surface_filter_handle, trace_surface_filter_handle);
+                       if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0)
+                               COREGL_LOG("\E[40;36;1m(SURFACE-SIZE:%dx%d)\E[0m ", trace_surface_filter_size_w, trace_surface_filter_size_h);
                }
 
                COREGL_LOG("\E[40;37;1menabled\E[0m\n");
@@ -917,7 +1007,7 @@ void (*dl_png_write_end) (png_structp png_ptr,
                             png_infop info_ptr);
 
 void
-tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLSurface surf, GLContext ctx)
+tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLContext ctx, GLSurface surf, GLint fbo, GLint tex, GLint rb, GLint tex_w, GLint tex_h, GLint tex_format)
 {
        Surface_Data *std = NULL;
 
@@ -934,9 +1024,15 @@ tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLSurface surf, GLC
 
                AST(std != NULL);
 
-      std->display = dpy;
-      std->surface = surf;
-      std->context = ctx;
+               std->display = dpy;
+               std->surface = surf;
+               std->context = ctx;
+               if (fbo >= 0) std->fbo = fbo;
+               std->tex = tex;
+               std->rb = rb;
+               if (tex_w >= 0) std->tex_w = tex_w;
+               if (tex_h >= 0) std->tex_h = tex_h;
+               if (tex_format >= 0) std->tex_format = tex_format;
 
                AST(mutex_unlock(&std_access_mutex) == 1);
 
@@ -944,152 +1040,259 @@ tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLSurface surf, GLC
 
 }
 
-void
-tracepath_surface_trace_remove(const char *desc)
+static void
+_dump_surface(int force_output, const char *position, Surface_Data *sdata)
 {
-       Surface_Data *std = NULL;
+       static int alldumpcount = 0;
 
-       if (trace_surface_flag == 1)
+       if (!png_lib_handle)
        {
-               AST(mutex_lock(&std_access_mutex) == 1);
+               png_lib_handle = dlopen("libpng.so.3", RTLD_NOW);
 
-               if (std_table == NULL)
+               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");
+
+               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");
+
+               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");
+       }
+
+       {
+               png_struct *png;
+               png_info *info;
+               png_byte **rows;
+               png_color_16 black;
+
+               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)
                {
-                       std_table = (Surface_Data **)calloc(1, sizeof(Surface_Data *) * MAX_TRACE_TABLE_SIZE);
+                       COREGL_ERR("Can't trace surface : Failed to use libpng (recommend : 1.2.50-3.4)");
+                       return;
                }
 
-               std = (Surface_Data *)_get_trace_data((Trace_Data **)std_table, sizeof(Surface_Data), desc);
+               EGLint width = -1, height = -1, channel = -1;
+               unsigned char *data = NULL;
+               char name[200];
 
-               AST(std != NULL);
+               if (trace_surface_sequence_sort_flag == 1)
+                       sprintf(name, "[%d (%06d)%p-%p] %s %04d (%s).png", getpid(), alldumpcount, sdata->display, sdata->context, sdata->trace_data.name, sdata->dump_count, position);
+               else
+                       sprintf(name, "[%d %p-%p] %s %04d (%s).png", getpid(), sdata->display, sdata->context, sdata->trace_data.name, sdata->dump_count, position);
+
+               if (sdata->fbo == 0 && sdata->tex == 0 && sdata->rb == 0)
+               { // EGL
+                       if (trace_surface_filter_type != 0 &&
+                           trace_surface_filter_type != 1) return;
+
+                       if (trace_surface_filter_handle != 0 &&
+                           trace_surface_filter_handle != (int)sdata->surface) return;
+
+                       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) return;
+                       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))
+                               return;
+
+                       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++;
+                               return;
+                       }
 
-               AST(mutex_unlock(&std_access_mutex) == 1);
+                       TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%d).\E[0m\n", name, width, height);
+                       if (trace_surface_print_only_flag == 1 && force_output == 0)
+                       {
+                               alldumpcount++;
+                               sdata->dump_count++;
+                               return;
+                       }
 
-       }
-}
+                       data = (unsigned char *)malloc(width * height * channel * sizeof(unsigned char));
+                       if (data == NULL)
+                       {
+                               COREGL_ERR("Can't trace surface : Failed to allocate memory");
+                               return;
+                       }
 
-static void
-_dump_surface(Surface_Data *sdata)
-{
-   if (!png_lib_handle)
-       {
-      png_lib_handle = dlopen("libpng.so.3", RTLD_NOW);
+                       GLint oldfb;
+                       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
+                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
+                       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;
+                       }
 
-      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");
+                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
+               }
+               if (sdata->fbo != 0)
+               { // FBO
+                       if (trace_surface_filter_type != 0 &&
+                           trace_surface_filter_type != 2) return;
 
-      dl_png_init_io = dlsym(png_lib_handle, "png_init_io");
+                       if (trace_surface_filter_handle != 0 &&
+                           trace_surface_filter_handle != sdata->tex &&
+                           trace_surface_filter_handle != sdata->rb) return;
 
-      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");
+                       GLint oldfb;
+                       _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
+                       _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
 
-      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 (_orig_tracepath_glCheckFramebufferStatus(GL_FRAMEBUFFER) == 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) return;
+                               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))
+                                       return;
+
+                               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++;
+                                       return;
+                               }
 
-   {
-      png_struct *png;
-      png_info *info;
-      png_byte **rows;
-      png_color_16 black;
-      char name[200];
-
-      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)");
-         return;
-      }
-
-      EGLint width, height;
-      _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_WIDTH, &width);
-      _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_HEIGHT, &height);
-
-      unsigned char *data;
-      data = (unsigned char *)malloc(width * height * 4 * sizeof(unsigned char));
-      _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
-
-      sprintf(name, "%s_%d.png", sdata->trace_data.name, sdata->dump_count);
-      sdata->dump_count++;
-
-      FILE *file = fopen (name, "wb");
-
-      if (file == NULL)
-      {
-         COREGL_ERR("Can't trace surface : Failed to create png file");
-         return;
-      }
-
-      rows = malloc(height * sizeof(png_byte *));
-      if (rows == NULL)
-      {
-         COREGL_ERR("Can't trace surface : Failed to allocate memory");
-         return;
-      }
-
-      for (int i = 0; i < height; i++)
-      {
-          rows[i] = data + (height - i - 1) * (width * 4);
-      }
-
-      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");
-         return;
-      }
-
-      info = dl_png_create_info_struct(png);
-      if (info == NULL)
-      {
-         fclose (file);
-         dl_png_destroy_write_struct (&png, NULL);
-         COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
-         return;
-      }
-
-      dl_png_init_io(png, file);
-
-      dl_png_set_IHDR(png, info,
-          width, height, 8,
-          PNG_COLOR_TYPE_RGBA,
-          PNG_INTERLACE_NONE,
-          PNG_COMPRESSION_TYPE_DEFAULT,
-          PNG_FILTER_TYPE_DEFAULT);
-
-      black.red = 0x00;
-      black.green = 0x00;
-      black.blue = 0x00;
-      dl_png_set_bKGD(png, info, &black);
-
-      //dl_png_set_bgr(png);
-
-      dl_png_write_info(png, info);
-
-      dl_png_write_image(png, rows);
-
-      dl_png_write_end(png, info);
-
-      dl_png_destroy_write_struct(&png, &info);
-
-      free(rows);
-      fclose(file);
-   }
+                               TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%d).\E[0m\n", name, width, height);
+                               if (trace_surface_print_only_flag == 1 && force_output == 0)
+                               {
+                                       alldumpcount++;
+                                       sdata->dump_count++;
+                                       return;
+                               }
+
+                               data = (unsigned char *)malloc(width * height * channel * sizeof(unsigned char));
+                               if (data == NULL)
+                               {
+                                       COREGL_ERR("Can't trace surface : Failed to allocate memory");
+                                       return;
+                               }
+
+                               _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
+                               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);
+               }
+
+               if (data == NULL) return;
+
+               unlink(name);
+               FILE *file = fopen (name, "wb");
+
+               if (file == NULL)
+               {
+                       COREGL_ERR("Can't trace surface : Failed to create png file");
+                       return;
+               }
+
+               rows = malloc(height * sizeof(png_byte *));
+               if (rows == NULL)
+               {
+                       COREGL_ERR("Can't trace surface : Failed to allocate memory");
+                       return;
+               }
+
+               for (int i = 0; i < height; i++)
+               {
+                       rows[i] = data + (height - i - 1) * (width * channel);
+               }
+
+               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");
+                       return;
+               }
+
+               info = dl_png_create_info_struct(png);
+               if (info == NULL)
+               {
+                       fclose (file);
+                       dl_png_destroy_write_struct (&png, NULL);
+                       COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
+                       return;
+               }
+
+               dl_png_init_io(png, file);
+
+               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;
+               }
+
+               black.red = 0x00;
+               black.green = 0x00;
+               black.blue = 0x00;
+               dl_png_set_bKGD(png, info, &black);
+
+               //dl_png_set_bgr(png);
+
+               dl_png_write_info(png, info);
+
+               dl_png_write_image(png, rows);
+
+               dl_png_write_end(png, info);
+
+               dl_png_destroy_write_struct(&png, &info);
+
+               free(rows);
+               free(data);
+               fclose(file);
+
+               alldumpcount++;
+               sdata->dump_count++;
+       }
 
 }
 
@@ -1099,7 +1302,7 @@ tracepath_surface_trace(int force_output, const char *position)
 {
        GLThreadState *tstate = NULL;
        MY_MODULE_TSTATE *tstate_tm = NULL;
-   int i;
+       int i;
 
        if (trace_surface_flag != 1)
        {
@@ -1129,28 +1332,33 @@ tracepath_surface_trace(int force_output, const char *position)
 
                                while (current != NULL)
                                {
-               {
-                  if (current->surface != EGL_NO_SURFACE && current->display != EGL_NO_DISPLAY && current->context != EGL_NO_CONTEXT)
-                  {
-                     _orig_tracepath_eglMakeCurrent(current->display, current->surface, current->surface, current->context);
-
-                     _dump_surface(current);
-//                     printf("THE PNG dumped SURF=%p (dpy=%p, surf=%p)\n", current->surface, current->display, current->context);
-                  }
-               }
+                                       if (current->surface != EGL_NO_SURFACE && current->display != EGL_NO_DISPLAY && current->context != EGL_NO_CONTEXT)
+                                       {
+                                               if (_orig_tracepath_eglMakeCurrent(current->display, current->surface, current->surface, current->context) == EGL_TRUE)
+                                               {
+                                                       _dump_surface(force_output, position, current);
+                                               }
+                                       }
 
                                        current = (Surface_Data *)current->trace_data.next;
                                }
                        }
                }
 
-      _orig_tracepath_eglMakeCurrent(tstate_tm->ctx->dpy, tstate_tm->surf_draw, tstate_tm->surf_read, tstate_tm->ctx->handle);
+               _orig_tracepath_eglMakeCurrent(tstate_tm->ctx->dpy, tstate_tm->surf_draw, tstate_tm->surf_read, tstate_tm->ctx->handle);
 
        }
 
-   goto finish;
+       goto finish;
 
-   finish:
-      return;
+       finish:
+               return;
+}
+
+
+COREGL_API void
+coregl_dump_surface()
+{
+       _COREGL_TRACE_SURFACE(1, "USER CALL");
 }
 
index 4003d96..a2be915 100644 (file)
@@ -137,8 +137,7 @@ extern void                tracepath_mem_trace_add(const char *desc, int alloc_s
 extern void                tracepath_mem_trace_remove(const char *desc, int alloc_size);\r
 extern void                tracepath_mem_trace_output(int force_output);\r
 \r
-extern void                tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLSurface surf, GLContext ctx);\r
-extern void                tracepath_surface_trace_remove(const char *desc);\r
+extern void                tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLContext ctx, GLSurface surf, GLint fbo, GLint tex, GLint rb, GLint tex_w, GLint tex_h, GLint tex_format);\r
 extern void                tracepath_surface_trace(int force_output, const char *position);\r
 \r
 extern void                tracepath_glbuf_clear(Glbuf_Data **glbuf);\r
index 3478220..9d09df5 100644 (file)
@@ -455,7 +455,7 @@ finish:
    {
       char name[256];
       sprintf(name, "EGLSURFACE_%p", surface);
-      tracepath_surface_trace_remove(name);
+      tracepath_surface_trace_add(name, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    }
 #endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
        return ret;
@@ -722,13 +722,6 @@ finish:
                }
        }
 #endif // COREGL_TRACEPATH_TRACE_CONTEXT_INFO
-#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
-   {
-      char name[256];
-      sprintf(name, "EGLSURFACE_%p", draw);
-      tracepath_surface_trace_add(name, dpy, draw, ctx);
-   }
-#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
        return ret;
 }
 
@@ -821,6 +814,8 @@ tracepath_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 {
        EGLBoolean ret = EGL_FALSE;
 
+       _COREGL_TRACE_SURFACE(0, "SWAPBUFFERS");
+
        _COREGL_TRACEPATH_FUNC_BEGIN();
        ret = _orig_tracepath_eglSwapBuffers(dpy, surface);
 
@@ -830,7 +825,6 @@ finish:
        _COREGL_TRACEPATH_FUNC_END();
        _COREGL_TRACE_API_OUTPUT(0);
        _COREGL_TRACE_MEM_OUTPUT(0);
-       _COREGL_TRACE_SURFACE(0, "SWAPBUFFERS");
        return ret;
 }
 
index 2ccba30..e030ba1 100644 (file)
@@ -158,6 +158,89 @@ finish:
        return;
 }
 
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+void
+_surface_trace_set(int set, GLint fbname, GLenum attachment, MY_MODULE_TSTATE *tstate)
+{
+       int atttype = _COREGL_INT_INIT_VALUE;
+   _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
+       AST(atttype != _COREGL_INT_INIT_VALUE);
+       int attname = _COREGL_INT_INIT_VALUE;
+   _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
+       AST(attname != _COREGL_INT_INIT_VALUE);
+       if (set == 1)
+       {
+               switch (atttype)
+               {
+                       case GL_TEXTURE:
+                               //COREGL_LOG("FBO DUMPING BEGIN = (TEX)%d\n", attname);
+                               {
+                                       char name[256];
+                                       sprintf(name, "FBOTEX_%d", attname);
+                                       tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, fbname, attname, 0, -1, -1, -1);
+                               }
+                               break;
+                       case GL_RENDERBUFFER:
+                               //COREGL_LOG("FBO DUMPING BEGIN = (RB)%d\n", attname);
+                               {
+                                       char name[256];
+                                       sprintf(name, "FBORB_%d", attname);
+                                       tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, fbname, 0, attname, -1, -1, -1);
+                               }
+                               break;
+               }
+       }
+       else
+       {
+               switch (atttype)
+               {
+                       case GL_TEXTURE:
+                               //COREGL_LOG("FBO DUMPING END = (TEX)%d\n", attname);
+                               {
+                                       char name[256];
+                                       sprintf(name, "FBOTEX_%d", attname);
+                                       tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, 0, attname, 0, -1, -1, -1);
+                               }
+                               break;
+                       case GL_RENDERBUFFER:
+                               //COREGL_LOG("FBO DUMPING END = (RB)%d\n", attname);
+                               {
+                                       char name[256];
+                                       sprintf(name, "FBORB_%d", attname);
+                                       tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, 0, 0, attname, -1, -1, -1);
+                               }
+                               break;
+               }
+       }
+}
+
+void
+tracepath_fbdump_update(GLint set)
+{
+       if (trace_surface_flag == 1)
+       {
+               GLint fbname = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbname);
+               AST(fbname != _COREGL_INT_INIT_VALUE);
+               if (fbname != 0)
+               {
+                       MY_MODULE_TSTATE *tstate = NULL;
+
+                       GET_MY_TSTATE(tstate, get_current_thread_state());
+                       AST(tstate != NULL);
+                       if (tstate->ctx != NULL)
+                       {
+                               _surface_trace_set(set, fbname, GL_COLOR_ATTACHMENT0, tstate);
+                               _surface_trace_set(set, fbname, GL_DEPTH_ATTACHMENT, tstate);
+                               _surface_trace_set(set, fbname, GL_STENCIL_ATTACHMENT, tstate);
+                       }
+               }
+       }
+}
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
+
 void
 tracepath_glActiveTexture(GLenum texture)
 {
@@ -210,8 +293,16 @@ void
 tracepath_glBindFramebuffer(GLenum target, GLuint framebuffer)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glBindFramebuffer(target, framebuffer);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 
        goto finish;
 
@@ -519,8 +610,17 @@ void
 tracepath_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glDeleteFramebuffers(n, framebuffers);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish:
@@ -543,8 +643,17 @@ void
 tracepath_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glDeleteRenderbuffers(n, renderbuffers);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish:
@@ -584,8 +693,17 @@ void
 tracepath_glDeleteTextures(GLsizei n, const GLuint* textures)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glDeleteTextures(n, textures);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish:
@@ -691,6 +809,20 @@ tracepath_glDrawArrays(GLenum mode, GLint first, GLsizei count)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       if (trace_surface_flag == 1)
+       {
+               GLint fbname = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbname);
+               AST(fbname != _COREGL_INT_INIT_VALUE);
+               if (fbname == 0)
+               {
+                       char name[256];
+                       sprintf(name, "EGLSURFACE_%p", _orig_tracepath_eglGetCurrentSurface(EGL_DRAW));
+                       tracepath_surface_trace_add(name, _orig_tracepath_eglGetCurrentDisplay(), _orig_tracepath_eglGetCurrentContext(), _orig_tracepath_eglGetCurrentSurface(EGL_DRAW), 0, 0, 0, 0, 0, 0);
+               }
+   }
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 }
 
 void
@@ -703,6 +835,20 @@ tracepath_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* in
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       if (trace_surface_flag == 1)
+       {
+               GLint fbname = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbname);
+               AST(fbname != _COREGL_INT_INIT_VALUE);
+               if (fbname == 0)
+               {
+                       char name[256];
+                       sprintf(name, "EGLSURFACE_%p", _orig_tracepath_eglGetCurrentSurface(EGL_DRAW));
+                       tracepath_surface_trace_add(name, _orig_tracepath_eglGetCurrentDisplay(), _orig_tracepath_eglGetCurrentContext(), _orig_tracepath_eglGetCurrentSurface(EGL_DRAW), 0, 0, 0, 0, 0, 0);
+               }
+   }
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 }
 
 void
@@ -761,8 +907,17 @@ void
 tracepath_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish:
@@ -773,8 +928,17 @@ void
 tracepath_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glFramebufferTexture2D(target, attachment, textarget, texture, level);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish:
@@ -1401,6 +1565,7 @@ void
 tracepath_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
        _orig_tracepath_glRenderbufferStorage(target, internalformat, width, height);
 
        goto finish;
@@ -1446,6 +1611,46 @@ finish:
                }
        }
 #endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       if (trace_surface_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               if (tstate->ctx != NULL)
+               {
+                       int objidx = _COREGL_INT_INIT_VALUE;
+                       _orig_tracepath_glGetIntegerv(GL_RENDERBUFFER_BINDING, &objidx);
+                       AST(objidx != _COREGL_INT_INIT_VALUE);
+
+                       {
+                               int channel = 0;
+                               switch (internalformat)
+                               {
+                                       case GL_ALPHA:
+                                       case GL_LUMINANCE:
+                                       case GL_DEPTH_COMPONENT :
+                                       case 0x81A5:
+                                       case 0x81A6:
+                                       case 0x81A7:
+                                       case 0x8D46 :
+                                       case 0x8D47 :
+                                       case 0x8D48 : channel = 1; break;
+                                       case GL_LUMINANCE_ALPHA:
+                                       case 0x84F9: channel = 2; break;
+                                       case GL_RGB: channel = 3; break;
+                                       case GL_RGBA:
+                                       case 0x80E1: channel = 4; break;
+                               }
+
+                               char name[256];
+                               sprintf(name, "FBORB_%d", objidx);
+                               tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, -1, 0, objidx, width, height, channel);
+                       }
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 }
 
 void
@@ -1617,6 +1822,46 @@ finish:
                }
        }
 #endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       if (trace_surface_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               if (tstate->ctx != NULL)
+               {
+                       int objidx = _COREGL_INT_INIT_VALUE;
+                       _orig_tracepath_glGetIntegerv(GL_TEXTURE_BINDING_2D, &objidx);
+                       AST(objidx != _COREGL_INT_INIT_VALUE);
+
+                       {
+                               int channel = 0;
+                               switch (internalformat)
+                               {
+                                       case GL_ALPHA:
+                                       case GL_LUMINANCE:
+                                       case GL_DEPTH_COMPONENT :
+                                       case 0x81A5:
+                                       case 0x81A6:
+                                       case 0x81A7:
+                                       case 0x8D46 :
+                                       case 0x8D47 :
+                                       case 0x8D48 : channel = 1; break;
+                                       case GL_LUMINANCE_ALPHA:
+                                       case 0x84F9: channel = 2; break;
+                                       case GL_RGB: channel = 3; break;
+                                       case GL_RGBA:
+                                       case 0x80E1: channel = 4; break;
+                               }
+
+                               char name[256];
+                               sprintf(name, "FBOTEX_%d", objidx);
+                               tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, -1, objidx, 0, width, height, channel);
+                       }
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 }
 
 void
@@ -2549,14 +2794,63 @@ finish:
                }
        }
 #endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       if (trace_surface_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               if (tstate->ctx != NULL)
+               {
+                       int objidx = _COREGL_INT_INIT_VALUE;
+                       _orig_tracepath_glGetIntegerv(GL_RENDERBUFFER_BINDING, &objidx);
+                       AST(objidx != _COREGL_INT_INIT_VALUE);
+
+                       {
+                               int channel = 0;
+                               switch (internalformat)
+                               {
+                                       case GL_ALPHA:
+                                       case GL_LUMINANCE:
+                                       case GL_DEPTH_COMPONENT :
+                                       case 0x81A5:
+                                       case 0x81A6:
+                                       case 0x81A7:
+                                       case 0x8D46 :
+                                       case 0x8D47 :
+                                       case 0x8D48 : channel = 1; break;
+                                       case GL_LUMINANCE_ALPHA:
+                                       case 0x84F9: channel = 2; break;
+                                       case GL_RGB: channel = 3; break;
+                                       case GL_RGBA:
+                                       case 0x80E1: channel = 4; break;
+                               }
+
+                               char name[256];
+                               sprintf(name, "FBORB_%d", objidx);
+                               tracepath_surface_trace_add(name, tstate->ctx->dpy, tstate->ctx->handle, tstate->surf_draw, -1, 0, objidx, width, height, channel);
+                       }
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
 }
 
 void
 tracepath_glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
 {
        _COREGL_TRACEPATH_FUNC_BEGIN();
+
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(0);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        _orig_tracepath_glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
 
+#ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
+       tracepath_fbdump_update(1);
+#endif // COREGL_TRACEPATH_TRACE_SURFACE_INFO
+
        goto finish;
 
 finish: