From b1a3a1e75e66d10e8e1d599288738173f16e2383 Mon Sep 17 00:00:00 2001 From: Haegeun Park Date: Wed, 21 Aug 2013 06:29:06 -0700 Subject: [PATCH] [Title] Released a new feature 'COREGL_TRACE_SURFACE' [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 | 1 + src/coregl_internal.h | 11 +- src/coregl_trace.c | 10 +- src/headers/sym_egl.h | 1 + src/modules/fastpath/coregl_fastpath.c | 1 + src/modules/tracepath/coregl_tracepath.c | 506 +++++++++++++++++++-------- src/modules/tracepath/coregl_tracepath.h | 3 +- src/modules/tracepath/coregl_tracepath_egl.c | 12 +- src/modules/tracepath/coregl_tracepath_gl.c | 294 ++++++++++++++++ 9 files changed, 676 insertions(+), 163 deletions(-) diff --git a/include/EGL/sym_egl.h b/include/EGL/sym_egl.h index 4e1c6ca..38f512d 100644 --- a/include/EGL/sym_egl.h +++ b/include/EGL/sym_egl.h @@ -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() diff --git a/src/coregl_internal.h b/src/coregl_internal.h index 1942c57..fb05065 100644 --- a/src/coregl_internal.h +++ b/src/coregl_internal.h @@ -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) diff --git a/src/coregl_trace.c b/src/coregl_trace.c index c72f398..d86f33d 100644 --- a/src/coregl_trace.c +++ b/src/coregl_trace.c @@ -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; diff --git a/src/headers/sym_egl.h b/src/headers/sym_egl.h index 4e1c6ca..38f512d 100644 --- a/src/headers/sym_egl.h +++ b/src/headers/sym_egl.h @@ -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() diff --git a/src/modules/fastpath/coregl_fastpath.c b/src/modules/fastpath/coregl_fastpath.c index 963a3a3..99a472e 100644 --- a/src/modules/fastpath/coregl_fastpath.c +++ b/src/modules/fastpath/coregl_fastpath.c @@ -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; diff --git a/src/modules/tracepath/coregl_tracepath.c b/src/modules/tracepath/coregl_tracepath.c index f9efa31..8eea9f9 100644 --- a/src/modules/tracepath/coregl_tracepath.c +++ b/src/modules/tracepath/coregl_tracepath.c @@ -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"); } diff --git a/src/modules/tracepath/coregl_tracepath.h b/src/modules/tracepath/coregl_tracepath.h index 4003d96..a2be915 100644 --- a/src/modules/tracepath/coregl_tracepath.h +++ b/src/modules/tracepath/coregl_tracepath.h @@ -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); extern void tracepath_mem_trace_output(int force_output); -extern void tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLSurface surf, GLContext ctx); -extern void tracepath_surface_trace_remove(const char *desc); +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); extern void tracepath_surface_trace(int force_output, const char *position); extern void tracepath_glbuf_clear(Glbuf_Data **glbuf); diff --git a/src/modules/tracepath/coregl_tracepath_egl.c b/src/modules/tracepath/coregl_tracepath_egl.c index 3478220..9d09df5 100644 --- a/src/modules/tracepath/coregl_tracepath_egl.c +++ b/src/modules/tracepath/coregl_tracepath_egl.c @@ -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; } diff --git a/src/modules/tracepath/coregl_tracepath_gl.c b/src/modules/tracepath/coregl_tracepath_gl.c index 2ccba30..e030ba1 100644 --- a/src/modules/tracepath/coregl_tracepath_gl.c +++ b/src/modules/tracepath/coregl_tracepath_gl.c @@ -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: -- 2.7.4