forked from enlightenment/efl
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.
This commit is contained in:
parent
79851b4762
commit
3074280217
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue