sung pushed a commit to branch master.

commit 3074280217f47b2cfd01708160aa2d83ddcb4de6
Author: Sung W. Park <[email protected]>
Date:   Mon Jul 22 18:52:32 2013 +0900

    Evas: adding image dump debug feature for gl_x11 backend
    
    Added a feature to dump out a png image before calling SwapBuffers.
    To turn on the feature, use the following env vars.
    
    EVAS_GL_SWAP_BUFFER_DEBUG_DIR="dir_name" sets the name of the directory
    that the files will be output to and enables the debug mode.
    
    EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS=1 will enable the writing of the
    files every frame.  This in effect turns on the swap_buffer_debug
    variable, which can be set on or off in gdb for debugging.  This will
    allow dumping of certain frames without having to dump out a ton of
    files to track down one frame.
---
 .../evas/engines/gl_common/evas_gl_common.h        |  2 +
 .../evas/engines/gl_common/evas_gl_context.c       | 64 ++++++++++++++++++++++
 src/modules/evas/engines/gl_x11/evas_engine.c      | 45 ++++++++++++++-
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h 
b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 1f4f1fa..def6425 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -747,6 +747,8 @@ void              
evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_P
 
 void              evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, 
int y1, int x2, int y2);
 
+int               evas_gl_common_buffer_dump(Evas_Engine_GL_Context *gc, const 
char* dname, const char* fname, int frame);
+
 extern void       (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b);
 extern void       (*glsym_glBindFramebuffer)      (GLenum a, GLuint b);
 extern void       (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum 
c, GLuint d, GLint e);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c 
b/src/modules/evas/engines/gl_common/evas_gl_context.c
index 777397a..d1b2c7e 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -3185,6 +3185,70 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
    gc->havestuff = EINA_FALSE;
 }
 
+int
+evas_gl_common_buffer_dump(Evas_Engine_GL_Context *gc, const char* dname, 
const char* buf_name, int frame)
+{
+   RGBA_Image *im = NULL;
+   DATA32 *data1, *data2;
+   char fname[100];
+   int ok = 0;
+
+   sprintf(fname, "./%s/evas_win_%s-fc_%03d.png", dname, buf_name, frame);
+
+   data1 = (DATA32 *)malloc(gc->w * gc->h * sizeof(DATA32));
+   data2 = (DATA32 *)malloc(gc->w * gc->h * sizeof(DATA32));
+
+   if ((!data1) || (!data2)) goto finish;
+
+   glReadPixels(0, 0, gc->w, gc->h, GL_RGBA,
+                GL_UNSIGNED_BYTE, (unsigned char*)data1);
+
+   // Flip the Y and change from RGBA TO BGRA
+   int i, j;
+   for (j = 0; j < gc->h; j++)
+      for (i = 0; i < gc->w; i++)
+        {
+           DATA32 d;
+           int idx1 = (j * gc->w) + i;
+           int idx2 = ((gc->h - 1) - j) * gc->w + i;
+
+           d = data1[idx1];
+           data2[idx2] = ((d & 0x000000ff) << 16) +
+              ((d & 0x00ff0000) >> 16)  +
+              ((d & 0xff00ff00));
+        }
+
+   evas_common_convert_argb_premul(data2, gc->w * gc->h);
+
+   im = (RGBA_Image*) evas_cache_image_data(evas_common_image_cache_get(),
+                                            gc->w,
+                                            gc->h,
+                                            (DATA32 *)data2,
+                                            1,
+                                            EVAS_COLORSPACE_ARGB8888);
+   if (im)
+     {
+        im->image.data = data2;
+        if (im->image.data)
+          {
+             ok = evas_common_save_image_to_file(im, fname, NULL, 0, 0);
+
+             if (!ok) ERR("Error Saving file.");
+          }
+
+        evas_cache_image_drop(&im->cache_entry);
+     }
+
+finish:
+   if (data1) free(data1);
+   if (data2) free(data2);
+   if (im)  evas_cache_image_drop(&im->cache_entry);
+
+   if (ok) return 1;
+   else return 0;
+}
+
+
 Eina_Bool
 evas_gl_common_module_open(void)
 {
diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c 
b/src/modules/evas/engines/gl_x11/evas_engine.c
index 0f48b78..2bf934c 100644
--- a/src/modules/evas/engines/gl_x11/evas_engine.c
+++ b/src/modules/evas/engines/gl_x11/evas_engine.c
@@ -26,6 +26,8 @@ enum {
 
 static int partial_render_debug = -1;
 static int partial_rect_union_mode = -1;
+static int swap_buffer_debug_mode = -1;
+static int swap_buffer_debug = 0;
 
 enum {
    MODE_FULL,
@@ -52,6 +54,7 @@ struct _Render_Engine
    int                      vsync;
    int                      lost_back;
    int                      prev_age;
+   int                      frame_cnt;
    Eina_Bool                evgl_initted : 1;
 
    struct {
@@ -1472,6 +1475,8 @@ static void
 eng_output_flush(void *data, Evas_Render_Mode render_mode)
 {
    Render_Engine *re;
+   static char *dname = NULL;
+
    re = (Render_Engine *)data;
 
    if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
@@ -1482,7 +1487,42 @@ eng_output_flush(void *data, Evas_Render_Mode 
render_mode)
    re->win->draw.drew = 0;
    eng_window_use(re->win);
    evas_gl_common_context_done(re->win->gl_context);
-   
+
+   // Save contents of the framebuffer to a file
+   if (swap_buffer_debug_mode == -1)
+     {
+        if ((dname = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))
+          {
+             int stat;
+             // Create a directory with 0775 permission
+             stat = mkdir(dname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+             if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1;
+          }
+        else
+           swap_buffer_debug_mode = 0;
+     }
+
+   if (swap_buffer_debug_mode == 1)
+     {
+        // Set this env var to dump files every frame
+        // Or set the global var in gdb to 1|0 to turn it on and off
+        if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS"))
+           swap_buffer_debug = 1;
+
+        if (swap_buffer_debug)
+          {
+             char fname[100];
+             int ret = 0;
+             sprintf(fname, "%p", (void*)re->win);
+
+             ret = evas_gl_common_buffer_dump(re->win->gl_context,
+                                              (const char*)dname,
+                                              (const char*)fname,
+                                              re->frame_cnt);
+             if (!ret) swap_buffer_debug_mode = 0;
+          }
+     }
+
 #ifdef GL_GLES
    if (!re->vsync)
      {
@@ -1552,6 +1592,7 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
      }
    else
       eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]);
+
 //xx   if (!safe_native) eglWaitGL();
    if (re->info->callback.post_swap)
      {
@@ -1615,6 +1656,8 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode)
         re->rects = NULL;
      }
 
+   re->frame_cnt++;
+
  end:
    evas_gl_preload_render_unlock(eng_preload_make_current, re);
 }

-- 

------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk

Reply via email to