1 #include "coregl_tracepath.h"
11 static int api_gl_version;
14 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) RET_TYPE (*_orig_tracepath_##FUNC_NAME) PARAM_LIST = NULL;
15 #include "../../headers/sym.h"
18 #define TIMEVAL_INIT { 0, 0 }
21 char name[MAX_TRACE_NAME_LENGTH];
22 struct _Trace_Data *next;
25 struct _Apicall_Data {
26 struct _Trace_Data trace_data;
30 struct timeval elapsed_time;
31 struct timeval elapsed_time_max;
32 struct timeval last_elapsed_time;
33 struct timeval total_elapsed_time;
34 struct timeval last_total_elapsed_time;
35 struct timeval last_time;
41 struct _Trace_Data trace_data;
48 struct _Surface_Data {
49 struct _Trace_Data trace_data;
63 typedef struct _GLGlueFakeContext {
64 GLuint gl_num_draw_buffers[1];
65 GLuint gl_num_tex_units[1];
66 GLuint gl_num_vertex_attribs[1];
67 GLuint gl_num_transform_feedback_separate_attribs[1];
68 GLuint gl_num_uniform_buffer_bindings[1];
71 GLGlueFakeContext initial_fake_ctx_real;
72 GLGlueFakeContext *initial_fake_ctx = &initial_fake_ctx_real;
74 struct timeval initial_time = TIMEVAL_INIT;
75 struct timeval last_initial_time = TIMEVAL_INIT;
77 struct timeval last_trace_time = TIMEVAL_INIT;
78 struct timeval other_elapsed_time = TIMEVAL_INIT;
79 struct timeval traced_other_elapsed_time = TIMEVAL_INIT;
81 Mutex mtd_access_mutex = MUTEX_INITIALIZER;
82 Memuse_Data **mtd_table;
84 Mutex std_access_mutex = MUTEX_INITIALIZER;
85 Surface_Data **std_table;
88 _state_get_texture_states(GLenum pname, GLint *params)
90 GLuint cur_active_tex = 0;
92 AST(initial_fake_ctx != NULL);
94 _orig_tracepath_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
96 for (i = 0; i < initial_fake_ctx->gl_num_tex_units[0]; i++) {
97 _orig_tracepath_glActiveTexture(GL_TEXTURE0 + i);
98 _orig_tracepath_glGetIntegerv(pname, (GLint *)¶ms[i]);
100 _orig_tracepath_glActiveTexture(cur_active_tex);
104 _state_get_draw_buffers(GLenum *params)
106 AST(initial_fake_ctx != NULL);
109 for (i = 0; i < initial_fake_ctx->gl_num_draw_buffers[0]; i++) {
110 _orig_tracepath_glGetIntegerv(GL_DRAW_BUFFER0 + i, (GLint *)¶ms[i]);
115 _state_get_transform_feedback_buffer_bindings(GLuint *params)
117 AST(initial_fake_ctx != NULL);
120 for (i = 0; i < initial_fake_ctx->gl_num_transform_feedback_separate_attribs[0];
122 _orig_tracepath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i,
123 (GLint *)¶ms[i]);
128 _state_get_transform_feedback_buffer_bindings_offset(GLintptr *params)
130 AST(initial_fake_ctx != NULL);
133 for (i = 0; i < initial_fake_ctx->gl_num_transform_feedback_separate_attribs[0];
135 _orig_tracepath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, i,
136 (GLint *)¶ms[i]);
141 _state_get_transform_feedback_buffer_bindings_size(GLsizeiptr *params)
143 AST(initial_fake_ctx != NULL);
146 for (i = 0; i < initial_fake_ctx->gl_num_transform_feedback_separate_attribs[0];
148 _orig_tracepath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i,
149 (GLint *)¶ms[i]);
154 _state_get_uniform_buffer_bindings(GLuint *params)
156 AST(initial_fake_ctx != NULL);
159 for (i = 0; i < initial_fake_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
160 /////////////////////////////////////////////////////////////////////////////////
161 // XXXX : AVOID SEGFAULT in ADRENO
162 ((GLint *)params)[i] = 0;
163 // _orig_tracepath_glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint *)¶ms[i]);
164 /////////////////////////////////////////////////////////////////////////////////
169 _state_get_uniform_buffer_bindings_offset(GLintptr *params)
171 AST(initial_fake_ctx != NULL);
174 for (i = 0; i < initial_fake_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
175 _orig_tracepath_glGetIntegeri_v(GL_UNIFORM_BUFFER_START, i,
176 (GLint *)¶ms[i]);
181 _state_get_uniform_buffer_bindings_size(GLsizeiptr *params)
183 AST(initial_fake_ctx != NULL);
186 for (i = 0; i < initial_fake_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
187 _orig_tracepath_glGetIntegeri_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint *)¶ms[i]);
192 init_modules_tracepath()
195 const char *output_file = NULL;
196 output_file = get_env_setting("COREGL_LOG_FILE");
197 if (strlen(output_file) > 0) {
198 trace_fp = fopen(output_file, "w");
202 #ifdef COREGL_TRACEPATH_TRACE_APICALL_INFO
203 trace_api_flag = atoi(get_env_setting("COREGL_TRACE_API"));
204 trace_api_all_flag = atoi(get_env_setting("COREGL_TRACE_API_ALL"));
205 trace_api_frame_flag = atoi(get_env_setting("COREGL_TRACE_API_FRAME"));
207 #ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
208 trace_mem_flag = atoi(get_env_setting("COREGL_TRACE_MEM"));
209 trace_mem_all_flag = atoi(get_env_setting("COREGL_TRACE_MEM_ALL"));
211 #ifdef COREGL_TRACEPATH_TRACE_SURFACE_INFO
212 trace_surface_flag = atoi(get_env_setting("COREGL_TRACE_SURFACE"));
213 trace_surface_sequence_sort_flag = atoi(
214 get_env_setting("COREGL_TRACE_SURFACE_SEQUENCE_SORT"));
215 trace_surface_print_only_flag = atoi(
216 get_env_setting("COREGL_TRACE_SURFACE_PRINT_ONLY"));
219 // COREGL_TRACE_SURFACE_FILTER_PERIOD=40~60
220 char tmp[64 + 1] = { 0 }, *tmpp = NULL;
221 strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_PERIOD"), 64);
222 for (tmpp = &tmp[0]; ; tmpp++) {
223 if (*tmpp == 0x00) break;
226 trace_surface_filter_period_begin = atoi(tmp);
227 trace_surface_filter_period_end = atoi(tmpp + 1);
234 // COREGL_TRACE_SURFACE_FILTER_TYPE=EGL|FBO
235 char tmp[64 + 1] = { 0 };
236 strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_TYPE"), 64);
237 if (strcmp(tmp, "EGL") == 0) trace_surface_filter_type = 1;
238 if (strcmp(tmp, "FBO") == 0) trace_surface_filter_type = 2;
242 // COREGL_TRACE_SURFACE_FILTER_HANDLE=0x3234
243 char tmp[64 + 1] = { 0 }, *tmpp = NULL;
244 strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_HANDLE"), 64);
245 if (tmp[0] == '0' && tmp[1] == 'x') {
246 for (tmpp = &tmp[2]; ; tmpp++) {
247 if (*tmpp == 0x00) break;
248 trace_surface_filter_handle *= 16;
251 trace_surface_filter_handle += 1;
254 trace_surface_filter_handle += 2;
257 trace_surface_filter_handle += 3;
260 trace_surface_filter_handle += 4;
263 trace_surface_filter_handle += 5;
266 trace_surface_filter_handle += 6;
269 trace_surface_filter_handle += 7;
272 trace_surface_filter_handle += 8;
275 trace_surface_filter_handle += 9;
279 trace_surface_filter_handle += 10;
283 trace_surface_filter_handle += 11;
287 trace_surface_filter_handle += 12;
291 trace_surface_filter_handle += 13;
295 trace_surface_filter_handle += 14;
299 trace_surface_filter_handle += 15;
304 trace_surface_filter_handle = atoi(tmp);
309 // COREGL_TRACE_SURFACE_FILTER_SIZE=640x480
310 char tmp[64 + 1] = { 0 }, *tmpp = NULL;
311 strncpy(tmp, get_env_setting("COREGL_TRACE_SURFACE_FILTER_SIZE"), 64);
312 for (tmpp = &tmp[0]; ; tmpp++) {
313 if (*tmpp == 0x00) break;
316 trace_surface_filter_size_w = atoi(tmp);
317 trace_surface_filter_size_h = atoi(tmpp + 1);
324 #ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
325 trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
326 trace_ctx_force_flag = atoi(get_env_setting("COREGL_TRACE_CTX_FORCE"));
328 #ifdef COREGL_TRACEPATH_TRACE_STATE_INFO
329 trace_state_flag = atoi(get_env_setting("COREGL_TRACE_STATE"));
333 COREGL_LOG("[CoreGL] \E[40;32;1m<Trace> \E[40;37;1m: ");
335 if (trace_api_flag == 1) {
336 COREGL_LOG("\E[40;31;1m(API)\E[0m ");
337 if (trace_api_all_flag == 1) COREGL_LOG("\E[40;31;1m(API-ALL)\E[0m ");
338 if (trace_api_frame_flag == 1) COREGL_LOG("\E[40;31;1m(API-FRAME)\E[0m ");
340 if (trace_ctx_flag == 1) {
341 COREGL_LOG("\E[40;33;1m(CONTEXT)\E[0m ");
342 if (trace_ctx_force_flag == 1) COREGL_LOG("\E[40;33;1m(CONTEXT-FORCE)\E[0m ");
344 if (trace_state_flag == 1) COREGL_LOG("\E[40;36;1m(STATE)\E[0m ");
345 if (trace_mem_flag == 1) {
346 COREGL_LOG("\E[40;35;1m(MEM)\E[0m ");
347 if (trace_mem_all_flag == 1) COREGL_LOG("\E[40;35;1m(MEM-ALL)\E[0m ");
349 if (trace_surface_flag == 1) {
350 COREGL_LOG("\E[40;36;1m(SURFACE)\E[0m ");
351 if (trace_surface_sequence_sort_flag == 1)
352 COREGL_LOG("\E[40;36;1m(SURFACE-SEQUENCE SORT)\E[0m ");
353 if (trace_surface_print_only_flag == 1)
354 COREGL_LOG("\E[40;36;1m(PRINT ONLY)\E[0m ");
355 if (trace_surface_filter_period_begin != 0 ||
356 trace_surface_filter_period_end != 0)
357 COREGL_LOG("\E[40;36;1m(SURFACE-PERIOD:%d~%d)\E[0m ",
358 trace_surface_filter_period_begin, trace_surface_filter_period_end);
359 if (trace_surface_filter_type == 1)
360 COREGL_LOG("\E[40;36;1m(SURFACE-TYPE:EGL)\E[0m ");
361 if (trace_surface_filter_type == 2)
362 COREGL_LOG("\E[40;36;1m(SURFACE-TYPE:FBO)\E[0m ");
363 if (trace_surface_filter_handle != 0)
364 COREGL_LOG("\E[40;36;1m(SURFACE-HANDLE:0x%x(%d))\E[0m ",
365 trace_surface_filter_handle, trace_surface_filter_handle);
366 if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0)
367 COREGL_LOG("\E[40;36;1m(SURFACE-SIZE:%dx%d)\E[0m ", trace_surface_filter_size_w,
368 trace_surface_filter_size_h);
371 COREGL_LOG("\E[40;37;1menabled\E[0m\n");
376 deinit_modules_tracepath()
381 init_modules_tstate_tracepath(GLThreadState *tstate)
383 MY_MODULE_TSTATE *tstate_mt = NULL;
385 tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
388 tstate->module_data[MY_MODULE_ID] = tstate_mt;
392 deinit_modules_tstate_tracepath(GLThreadState *tstate)
394 if (tstate->module_data[MY_MODULE_ID] != NULL) {
395 free(tstate->module_data[MY_MODULE_ID]);
396 tstate->module_data[MY_MODULE_ID] = NULL;
401 tracepath_apply_overrides()
404 tracepath_apply_overrides_egl(1);
405 tracepath_apply_overrides_gl(1);
410 tracepath_apply_overrides_egl(int enable)
412 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) COREGL_INIT_ORIGINAL(_orig_tracepath_, FUNC_NAME);
413 # include "../../headers/sym_egl.h"
414 #undef _COREGL_SYMBOL
416 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) COREGL_OVERRIDE(tracepath_, FUNC_NAME);
417 # include "../../headers/sym_egl.h"
418 #undef _COREGL_SYMBOL
422 tracepath_apply_overrides_gl(int enable)
424 #define _COREGL_START_API(version) api_gl_version = version;
425 #define _COREGL_END_API(version) api_gl_version = COREGL_GLAPI_2;
426 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
427 if(api_gl_version <= driver_gl_version) COREGL_INIT_ORIGINAL(_orig_tracepath_, FUNC_NAME);
428 # include "../../headers/sym_gl.h"
429 #undef _COREGL_SYMBOL
431 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
432 if(api_gl_version <= driver_gl_version) COREGL_OVERRIDE(tracepath_, FUNC_NAME);
433 # include "../../headers/sym_gl.h"
434 #undef _COREGL_SYMBOL
435 #undef _COREGL_START_API
436 #undef _COREGL_END_API
442 tracepath_dump_context_states(int force_output)
444 static struct timeval tv_last = { 0, 0 };
446 if (unlikely(trace_state_flag != 1)) return;
448 _sym_glGetIntegerv(GL_MAX_DRAW_BUFFERS,
449 (GLint *)initial_fake_ctx->gl_num_draw_buffers);
450 _sym_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
451 (GLint *)initial_fake_ctx->gl_num_tex_units);
452 _sym_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,
453 (GLint *)initial_fake_ctx->gl_num_vertex_attribs);
454 _sym_glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
455 (GLint *)initial_fake_ctx->gl_num_transform_feedback_separate_attribs);
456 _sym_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
457 (GLint *)initial_fake_ctx->gl_num_uniform_buffer_bindings);
460 struct timeval tv_now = { 0, 0 };
461 AST(gettimeofday(&tv_now, NULL) == 0);
462 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
469 TRACE("\E[0;40;34m===================================================================================================================\E[0m\n");
470 TRACE("\E[40;32;1m State info \E[1;37;1m: <PID = %d> (CURRENT BINDED CONTEXT)\E[0m\n",
472 TRACE("\E[0;40;34m===================================================================================================================\E[0m\n");
474 #define PRINTF_CHAR_GLenum "0x%8X"
475 #define PRINTF_CHAR_GLboolean "%10d"
476 #define PRINTF_CHAR_GLint "%10d"
477 #define PRINTF_CHAR_GLsizei "%10u"
478 #define PRINTF_CHAR_GLuint "%10u"
479 #define PRINTF_CHAR_GLuintmask "0x%8X"
480 #define PRINTF_CHAR_GLintptr "%10ld"
481 #define PRINTF_CHAR_GLsizeiptr "%10ld"
483 #define PRINTF_CHAR_GLclampf "%10.6f"
484 #define PRINTF_CHAR_GLfloat "%10.6f"
486 #define PRINTF_CHAR_GLvoidptr "%10p"
488 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
490 #define INITIAL_CTX initial_fake_ctx
492 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
494 TYPE valuedata[SIZE]; \
495 TYPE *value = NULL; \
496 value = valuedata; GET_STMT; value = valuedata; \
497 TRACE("\E[40;37;1m %-30.30s : (\E[0m ", #NAME); \
498 for (int i = 0; i < SIZE; i++) \
502 TRACE("\n %-30.30s ", "");\
506 TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
508 TRACE(" \E[40;37;1m)\E[0m\n"); \
510 # include "../fastpath/coregl_fastpath_state.h"
513 TRACE("\E[0;40;34m===================================================================================================================\E[0m\n");
524 _add_timeval_period(struct timeval *tv_dst, struct timeval tv_now,
525 struct timeval tv_old)
527 tv_dst->tv_sec += tv_now.tv_sec - tv_old.tv_sec;
528 tv_dst->tv_usec += 1000000 + (tv_now.tv_usec - tv_old.tv_usec);
529 tv_dst->tv_sec += (tv_dst->tv_usec / 1000000) - 1;
530 tv_dst->tv_usec = tv_dst->tv_usec % 1000000;
534 _add_timeval(struct timeval *tv_dst, struct timeval tv_src)
536 tv_dst->tv_sec += tv_src.tv_sec;
537 tv_dst->tv_usec += tv_src.tv_usec;
538 if (tv_dst->tv_usec > 1000000) {
539 tv_dst->tv_usec -= 1000000;
541 } else if (tv_dst->tv_usec < 0) {
542 tv_dst->tv_usec += 1000000;
548 _get_timeval_period(struct timeval time_now, struct timeval time_old)
550 return ((time_now.tv_sec - time_old.tv_sec) * 1000) + ((
551 time_now.tv_usec - time_old.tv_usec) / 1000.0);
555 _get_timeval(struct timeval time)
557 return (time.tv_sec * 1000) + (time.tv_usec / 1000.0);
560 static unsigned short
561 _generate_hash_short(const char *string)
563 unsigned short hash = 0;
566 for (i = 0; i < strlen(string); i++) {
567 hash = 253 * hash + string[i];
569 return (hash ^ (hash >> 8)) % MAX_TRACE_TABLE_SIZE;
573 _get_trace_data(Trace_Data **ftd_table, size_t td_size, const char *name)
575 Trace_Data *ret = NULL;
576 Trace_Data *current = NULL;
577 Trace_Data *prev = NULL;
578 unsigned short hash = 0;
580 AST(strlen(name) < MAX_TRACE_NAME_LENGTH);
582 hash = _generate_hash_short(name);
584 current = ftd_table[hash];
586 while (current != NULL && current->next != NULL) {
587 if (strcmp(current->name, name) == 0)
590 current = current->next;
593 if (current != NULL) {
596 Trace_Data *newitm = NULL;
597 newitm = (Trace_Data *)calloc(1, td_size);
598 strcpy(newitm->name, name);
604 ftd_table[hash] = newitm;
616 tracepath_mem_trace_add(const char *desc, int alloc_size)
618 Memuse_Data *mtd = NULL;
620 if (trace_mem_flag == 1) {
621 AST(mutex_lock(&mtd_access_mutex) == 1);
623 if (mtd_table == NULL) {
624 mtd_table = (Memuse_Data **)calloc(1,
625 sizeof(Memuse_Data *) * MAX_TRACE_TABLE_SIZE);
628 mtd = (Memuse_Data *)_get_trace_data((Trace_Data **)mtd_table,
629 sizeof(Memuse_Data), desc);
635 if (mtd->memsize == 0)
636 mtd->memsize = alloc_size;
638 AST(mtd->memsize == alloc_size);
640 AST(mutex_unlock(&mtd_access_mutex) == 1);
642 if (trace_mem_all_flag == 1)
643 _COREGL_TRACE_MEM_OUTPUT(1);
649 tracepath_mem_trace_remove(const char *desc, int alloc_size)
651 Memuse_Data *mtd = NULL;
653 if (trace_mem_flag == 1) {
654 AST(mutex_lock(&mtd_access_mutex) == 1);
656 if (mtd_table == NULL) {
657 mtd_table = (Memuse_Data **)calloc(1,
658 sizeof(Memuse_Data *) * MAX_TRACE_TABLE_SIZE);
661 mtd = (Memuse_Data *)_get_trace_data((Trace_Data **)mtd_table,
662 sizeof(Memuse_Data), desc);
665 AST(mtd->memsize == alloc_size);
667 AST(mtd->alloc_count > mtd->remove_count);
670 AST(mutex_unlock(&mtd_access_mutex) == 1);
672 if (trace_mem_all_flag == 1)
673 _COREGL_TRACE_MEM_OUTPUT(1);
678 tracepath_api_trace_begin(const char *funcname, void *hint,
679 int trace_total_time)
681 Apicall_Data *ftd = NULL;
682 struct timeval t = TIMEVAL_INIT;
684 if (trace_api_flag == 1) {
685 AST(gettimeofday(&t, NULL) == 0);
687 ftd = (Apicall_Data *)hint;
690 MY_MODULE_TSTATE *tstate = NULL;
691 GET_MY_TSTATE(tstate, get_current_thread_state());
693 if (tstate == NULL) {
694 init_new_thread_state();
696 GET_MY_TSTATE(tstate, get_current_thread_state());
700 if (tstate->ftd_table == NULL) {
701 tstate->ftd_table = (Apicall_Data **)calloc(1,
702 sizeof(Apicall_Data *) * MAX_TRACE_TABLE_SIZE);
705 ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table,
706 sizeof(Apicall_Data), funcname);
712 AST(ftd->last_time.tv_sec == 0);
714 AST(gettimeofday(&ftd->last_time, NULL) == 0);
716 if (initial_time.tv_sec == 0) {
717 initial_time = ftd->last_time;
718 last_initial_time = ftd->last_time;
721 if (trace_total_time == 1) {
722 if (last_trace_time.tv_sec != 0) {
723 _add_timeval_period(&other_elapsed_time, t, last_trace_time);
724 last_trace_time.tv_sec = 0;
734 tracepath_api_trace_end(const char *funcname, void *hint, int trace_total_time)
736 Apicall_Data *ftd = NULL;
737 struct timeval t = TIMEVAL_INIT;
739 if (trace_api_flag == 1) {
740 MY_MODULE_TSTATE *tstate = NULL;
741 struct timeval elapsed_time = TIMEVAL_INIT;
743 AST(gettimeofday(&t, NULL) == 0);
745 ftd = (Apicall_Data *)hint;
748 GET_MY_TSTATE(tstate, get_current_thread_state());
750 if (tstate == NULL) {
751 init_new_thread_state();
753 GET_MY_TSTATE(tstate, get_current_thread_state());
758 AST(tstate->ftd_table != NULL);
760 ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table,
761 sizeof(Apicall_Data), funcname);
766 _add_timeval_period(&elapsed_time, t, ftd->last_time);
768 _add_timeval(&ftd->elapsed_time, elapsed_time);
770 if (elapsed_time.tv_sec >= ftd->elapsed_time_max.tv_sec &&
771 elapsed_time.tv_usec > ftd->elapsed_time_max.tv_usec) {
772 ftd->elapsed_time_max.tv_sec = elapsed_time.tv_sec;
773 ftd->elapsed_time_max.tv_usec = elapsed_time.tv_usec;
776 ftd->last_time.tv_sec = 0;
778 if (trace_total_time == 1) {
779 _add_timeval(&ftd->total_elapsed_time, elapsed_time);
781 AST(gettimeofday(&last_trace_time, NULL) == 0);
783 if (initial_time.tv_sec == 0) {
785 last_initial_time = t;
796 tracepath_api_trace_output(int force_output)
798 static struct timeval tv_last = TIMEVAL_INIT;
799 struct timeval total_now = TIMEVAL_INIT;
800 GLThreadState *tstate = NULL;
801 MY_MODULE_TSTATE *tstate_tm = NULL;
802 Apicall_Data **ftd_table = NULL;
804 double total_elapsed_time = 0.0;
805 double total_elapsed_time_period = 0.0;
806 double total_opengl_elapsed_time = 0.0;
807 double total_opengl_elapsed_time_period = 0.0;
808 double total_other_elapsed_time = 0.0;
809 double total_other_elapsed_time_period = 0.0;
811 double swaps_per_sec = 0.0;
815 if (trace_api_flag != 1) {
820 struct timeval tv_now = TIMEVAL_INIT;
821 AST(gettimeofday(&tv_now, NULL) == 0);
822 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
828 AST(gettimeofday(&total_now, NULL) == 0);
830 total_elapsed_time = _get_timeval_period(total_now, initial_time);
831 total_elapsed_time_period = _get_timeval_period(total_now, last_initial_time);
832 last_initial_time = total_now;
834 total_other_elapsed_time = _get_timeval(other_elapsed_time);
835 total_other_elapsed_time_period = _get_timeval_period(other_elapsed_time,
836 traced_other_elapsed_time);
837 traced_other_elapsed_time = other_elapsed_time;
839 tstate = get_current_thread_state();
841 if (tstate == NULL) {
842 init_new_thread_state();
844 tstate = get_current_thread_state();
848 GET_MY_TSTATE(tstate_tm, tstate);
849 if (tstate_tm == NULL) goto finish;
851 ftd_table = tstate_tm->ftd_table;
852 if (ftd_table == NULL) goto finish;
855 static Apicall_Data *trace_hint_swap = NULL;
856 if (trace_hint_swap == NULL)
857 trace_hint_swap = (Apicall_Data *)_get_trace_data((Trace_Data **)ftd_table,
858 sizeof(Apicall_Data), "tracepath_eglSwapBuffers");
860 if (trace_hint_swap != NULL && total_elapsed_time_period > 0) {
861 swaps_per_sec = (trace_hint_swap->call_count -
862 trace_hint_swap->last_call_count) / (total_elapsed_time_period / 1000);
868 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
869 TRACE("\E[40;32;1m API call info \E[1;37;1m: <PID = %d> Thread ID = 0x%x [Swaps per Second(P) = %7.2f]\E[0m\n",
870 getpid(), tstate->thread_id, swaps_per_sec);
871 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
874 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
875 if (ftd_table[i] != NULL) {
876 Apicall_Data *current = ftd_table[i];
878 while (current != NULL) {
879 double elapsed_time = _get_timeval(current->elapsed_time);
880 double elapsed_time_per_call = elapsed_time / current->call_count;
882 total_opengl_elapsed_time += _get_timeval(current->total_elapsed_time);
883 total_opengl_elapsed_time_period += _get_timeval(current->total_elapsed_time) -
884 _get_timeval(current->last_total_elapsed_time);
888 if (current->call_count > current->last_call_count) {
889 double elapsed_time_period = _get_timeval_period(current->elapsed_time,
890 current->last_elapsed_time);
891 double elapsed_time_max = _get_timeval(current->elapsed_time_max);
892 double elapsed_time_per_call_period = elapsed_time_period /
893 (current->call_count - current->last_call_count);
894 char *fname = current->trace_data.name;
896 if (!strncmp(fname, "tracepath_", 10))
897 fname = ¤t->trace_data.name[10];
899 if (elapsed_time_per_call_period >= 0.01 ||
900 current->call_count - current->last_call_count > 1000) {
901 TRACE("\E[40;37;1m %-39.39s : %10d call(s), %9.3f ms/API, %9.2f ms(MAX), %9.3f ms/API(P)\E[0m\n",
902 fname, current->call_count, elapsed_time_per_call, elapsed_time_max,
903 elapsed_time_per_call_period);
907 current = (Apicall_Data *)current->trace_data.next;
914 fp_env = atoi(get_env_setting("COREGL_TRACE_API_ALL"));
917 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
918 if (ftd_table[i] != NULL) {
919 Apicall_Data *current = ftd_table[i];
921 while (current != NULL) {
922 if (current->traced == 0 && current->call_count > 0) {
923 double elapsed_time = _get_timeval(current->elapsed_time);
924 double elapsed_time_per_call = elapsed_time / current->call_count;
925 double elapsed_time_max = _get_timeval(current->elapsed_time_max);
926 char *fname = current->trace_data.name;
928 if (!strncmp(fname, "tracepath_", 10))
929 fname = ¤t->trace_data.name[10];
931 TRACE(" %-39.39s : %10d call(s), %9.3f ms/API, %9.2f ms(MAX)\n",
932 fname, current->call_count, elapsed_time_per_call, elapsed_time_max);
934 current = (Apicall_Data *)current->trace_data.next;
941 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
943 if (trace_api_frame_flag == 0) {
944 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
945 "TOTAL elapsed Time",
948 total_elapsed_time_period,
952 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
953 "OpenGL elapsed Time",
954 total_opengl_elapsed_time,
955 total_opengl_elapsed_time * 100.0 / total_elapsed_time,
956 total_opengl_elapsed_time_period,
957 total_opengl_elapsed_time_period * 100.0 / total_elapsed_time_period);
959 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
960 "Out of OpenGL elapsed time",
961 total_other_elapsed_time,
962 total_other_elapsed_time * 100.0 / total_elapsed_time,
963 total_other_elapsed_time_period,
964 total_other_elapsed_time_period * 100.0 / total_elapsed_time_period);
966 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
967 "CoreGL API tracing overhead",
968 total_elapsed_time - total_opengl_elapsed_time - total_other_elapsed_time,
969 (total_elapsed_time - total_opengl_elapsed_time - total_other_elapsed_time) *
970 100.0 / total_elapsed_time,
971 total_elapsed_time_period - total_opengl_elapsed_time_period -
972 total_other_elapsed_time_period,
973 (total_elapsed_time_period - total_opengl_elapsed_time_period -
974 total_other_elapsed_time_period) * 100.0 / total_elapsed_time_period);
976 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
980 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
981 if (ftd_table[i] != NULL) {
982 Apicall_Data *current = ftd_table[i];
984 while (current != NULL) {
985 current->last_call_count = current->call_count;
986 current->last_elapsed_time = current->elapsed_time;
987 current->last_total_elapsed_time = current->total_elapsed_time;
988 current = (Apicall_Data *)current->trace_data.next;
1002 tracepath_api_trace_reset_frame()
1004 GLThreadState *tstate = NULL;
1005 MY_MODULE_TSTATE *tstate_tm = NULL;
1006 Apicall_Data **ftd_table = NULL;
1010 if (trace_api_flag != 1) {
1014 tstate = get_current_thread_state();
1016 if (tstate == NULL) {
1017 init_new_thread_state();
1019 tstate = get_current_thread_state();
1020 AST(tstate != NULL);
1023 GET_MY_TSTATE(tstate_tm, tstate);
1024 if (tstate_tm == NULL) goto finish;
1026 ftd_table = tstate_tm->ftd_table;
1027 if (ftd_table == NULL) goto finish;
1029 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1030 if (ftd_table[i] != NULL) {
1031 Apicall_Data *current = ftd_table[i];
1033 while (current != NULL) {
1034 current->call_count = 0;
1035 current->last_call_count = 0;
1036 current->elapsed_time.tv_sec = 0;
1037 current->elapsed_time.tv_usec = 0;
1038 current->last_elapsed_time.tv_sec = 0;
1039 current->last_elapsed_time.tv_usec = 0;
1040 current->last_total_elapsed_time.tv_sec = 0;
1041 current->last_total_elapsed_time.tv_usec = 0;
1042 current->total_elapsed_time.tv_sec = 0;
1043 current->total_elapsed_time.tv_usec = 0;
1044 current = (Apicall_Data *)current->trace_data.next;
1048 AST(gettimeofday(&last_initial_time, NULL) == 0);
1056 tracepath_mem_trace_output(int force_output)
1058 static struct timeval tv_last = TIMEVAL_INIT;
1062 if (trace_mem_flag != 1) {
1066 if (!force_output) {
1067 struct timeval tv_now = TIMEVAL_INIT;
1068 AST(gettimeofday(&tv_now, NULL) == 0);
1069 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
1076 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1077 TRACE("\E[40;32;1m Memory usage info \E[1;37;1m: <PID = %d>\E[0m\n", getpid());
1078 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1080 if (mtd_table != NULL) {
1081 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1082 if (mtd_table[i] != NULL) {
1083 Memuse_Data *current = mtd_table[i];
1085 while (current != NULL) {
1086 int obj_count = current->alloc_count - current->remove_count;
1087 if (obj_count > 0) {
1088 TRACE("\E[40;37;1m %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\E[0m\n",
1089 current->trace_data.name, current->memsize, obj_count, current->alloc_count,
1090 current->remove_count);
1092 current = (Memuse_Data *)current->trace_data.next;
1097 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1098 if (mtd_table[i] != NULL) {
1099 Memuse_Data *current = mtd_table[i];
1101 while (current != NULL) {
1102 int obj_count = current->alloc_count - current->remove_count;
1103 if (obj_count == 0) {
1104 TRACE(" %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\n",
1105 current->trace_data.name, current->memsize, obj_count, current->alloc_count,
1106 current->remove_count);
1108 current = (Memuse_Data *)current->trace_data.next;
1114 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1127 void *png_lib_handle = NULL;
1129 png_structp (*dl_png_create_write_struct) (png_const_charp user_png_ver,
1130 png_voidp error_ptr,
1131 png_error_ptr error_fn,
1132 png_error_ptr warn_fn);
1135 void (*dl_png_destroy_write_struct) (png_structpp png_ptr_ptr,
1136 png_infopp info_ptr_ptr);
1139 png_infop (*dl_png_create_info_struct) (png_structp png_ptr);
1141 void (*dl_png_init_io) (png_structp png_ptr,
1145 void (*dl_png_set_IHDR) (png_structp png_ptr,
1151 int interlace_method,
1152 int compression_method,
1155 void (*dl_png_set_bKGD) (png_structp png_ptr,
1157 png_color_16p background);
1159 void (*dl_png_set_bgr) (png_structp png_ptr);
1161 void (*dl_png_write_info) (png_structp png_ptr,
1162 png_infop info_ptr);
1164 void (*dl_png_write_image) (png_structp png_ptr,
1167 void (*dl_png_write_end) (png_structp png_ptr,
1168 png_infop info_ptr);
1171 _dump_surface(int force_output, int type, const char *position,
1172 Surface_Data *sdata)
1174 static int alldumpcount = 0;
1175 unsigned char *data = NULL;
1176 EGLint width = -1, height = -1, channel = -1;
1178 FILE *write_fd = NULL;
1179 png_struct *png = NULL;
1180 png_info *info = NULL;
1181 png_byte **rows = NULL;
1182 GLenum ret_value = _COREGL_INT_INIT_VALUE;
1184 if (!png_lib_handle) {
1185 png_lib_handle = dlopen("libpng16.so.16", RTLD_NOW);
1187 dl_png_create_write_struct = dlsym(png_lib_handle, "png_create_write_struct");
1188 dl_png_destroy_write_struct = dlsym(png_lib_handle, "png_destroy_write_struct");
1189 dl_png_create_info_struct = dlsym(png_lib_handle, "png_create_info_struct");
1191 dl_png_init_io = dlsym(png_lib_handle, "png_init_io");
1193 dl_png_set_IHDR = dlsym(png_lib_handle, "png_set_IHDR");
1194 dl_png_set_bKGD = dlsym(png_lib_handle, "png_set_bKGD");
1195 dl_png_set_bgr = dlsym(png_lib_handle, "png_set_bgr");
1197 dl_png_write_info = dlsym(png_lib_handle, "png_write_info");
1198 dl_png_write_image = dlsym(png_lib_handle, "png_write_image");
1199 dl_png_write_end = dlsym(png_lib_handle, "png_write_end");
1203 if (!png_lib_handle ||
1204 dl_png_create_write_struct == NULL ||
1205 dl_png_destroy_write_struct == NULL ||
1206 dl_png_create_info_struct == NULL ||
1207 dl_png_init_io == NULL ||
1208 dl_png_set_IHDR == NULL ||
1209 dl_png_set_bKGD == NULL ||
1210 dl_png_set_bgr == NULL ||
1211 dl_png_write_info == NULL ||
1212 dl_png_write_image == NULL ||
1213 dl_png_write_end == NULL) {
1214 COREGL_ERR("Can't trace surface : Failed to use libpng (recommend : 1.2.50-3.4)");
1218 if (trace_surface_sequence_sort_flag == 1)
1219 sprintf(name, "[%d (%06d)%p-%p] %s %04d (%s).png", getpid(), alldumpcount,
1220 sdata->display, sdata->context, sdata->trace_data.name, sdata->dump_count,
1223 sprintf(name, "[%d %p-%p] %s %04d (%s).png", getpid(), sdata->display,
1224 sdata->context, sdata->trace_data.name, sdata->dump_count, position);
1226 if (!strncmp(sdata->trace_data.name, "EGL", 3) && type != 2) {
1228 if (trace_surface_filter_type != 0 &&
1229 trace_surface_filter_type != 1) goto finish;;
1231 if (trace_surface_filter_handle != 0 &&
1232 trace_surface_filter_handle != (int)sdata->surface) goto finish;
1234 EGLConfig eglconfig;
1235 GLint asize, rsize, gsize, bsize;
1236 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_WIDTH,
1238 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_HEIGHT,
1240 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_CONFIG_ID,
1241 (GLint *)&eglconfig);
1242 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_ALPHA_SIZE,
1244 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_RED_SIZE,
1246 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_GREEN_SIZE,
1248 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_BLUE_SIZE,
1251 if (asize == 0) channel = 3;
1252 if (bsize == 0) channel = 2;
1253 if (gsize == 0) channel = 1;
1254 if (rsize == 0) channel = 0;
1256 if (channel == 2) channel = 3;
1257 if (width <= 0 || height <= 0 || channel <= 0) goto finish;
1258 if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
1259 (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
1262 if ((trace_surface_filter_period_begin > 0 ||
1263 trace_surface_filter_period_end > 0) &&
1264 (trace_surface_filter_period_begin > alldumpcount ||
1265 trace_surface_filter_period_end < alldumpcount)) {
1267 sdata->dump_count++;
1271 if (channel == 3) channel = 4;
1273 TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
1274 width, height, channel);
1275 if (trace_surface_print_only_flag == 1 && force_output == 0) {
1277 sdata->dump_count++;
1281 data = (unsigned char *)calloc(1,
1282 width * height * channel * sizeof(unsigned char));
1284 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1289 _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
1290 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, 0);
1294 _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1297 //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
1299 _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
1304 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1306 if (!strncmp(sdata->trace_data.name, "FBO", 3) && type != 1) {
1308 if (sdata->fbo == 0) goto finish;
1310 if (trace_surface_filter_type != 0 &&
1311 trace_surface_filter_type != 2) goto finish;
1313 if (trace_surface_filter_handle != 0 &&
1314 trace_surface_filter_handle != sdata->tex &&
1315 trace_surface_filter_handle != sdata->rb) goto finish;
1318 _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
1319 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
1321 if (driver_gl_version >= 2)
1322 ret_value = _orig_tracepath_glCheckFramebufferStatus(GL_FRAMEBUFFER);
1324 ret_value = _orig_tracepath_glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
1325 if (ret_value == GL_FRAMEBUFFER_COMPLETE) {
1326 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1327 width = sdata->tex_w;
1328 height = sdata->tex_h;
1329 channel = sdata->tex_format;
1331 if (channel == 2) channel = 3;
1332 if (width <= 0 || height <= 0 || channel <= 0) goto finish;
1333 if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
1334 (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
1337 if ((trace_surface_filter_period_begin > 0 ||
1338 trace_surface_filter_period_end > 0) &&
1339 (trace_surface_filter_period_begin > alldumpcount ||
1340 trace_surface_filter_period_end < alldumpcount)) {
1342 sdata->dump_count++;
1346 TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
1347 width, height, channel);
1348 if (trace_surface_print_only_flag == 1 && force_output == 0) {
1350 sdata->dump_count++;
1354 if (channel == 3) channel = 4;
1356 data = (unsigned char *)calloc(1,
1357 width * height * channel * sizeof(unsigned char));
1359 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1363 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
1364 int atttype = _COREGL_INT_INIT_VALUE;
1365 if (driver_gl_version >= 2)
1366 _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
1367 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
1369 _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
1370 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
1371 AST(atttype != sdata->tex);
1372 int attname = _COREGL_INT_INIT_VALUE;
1373 if (driver_gl_version >= 2)
1374 _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
1375 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
1377 _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
1378 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
1381 AST(attname == sdata->tex);
1383 case GL_RENDERBUFFER:
1384 AST(attname == sdata->rb);
1390 _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1393 //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
1395 _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
1400 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1405 if (data == NULL) goto finish;
1408 write_fd = fopen(name, "wb");
1410 if (write_fd == NULL) {
1411 COREGL_ERR("Can't trace surface : Failed to create png file");
1415 rows = (png_byte **)malloc(height * sizeof(png_byte *));
1417 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1421 for (int i = 0; i < height; i++) {
1422 rows[i] = data + (height - i - 1) * (width * channel);
1425 png = dl_png_create_write_struct(PNG_LIBPNG_VER_STRING,
1430 COREGL_ERR("Can't trace surface : Failed to create write structure of png file");
1434 info = dl_png_create_info_struct(png);
1436 COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
1440 dl_png_init_io(png, write_fd);
1444 dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
1445 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1447 //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;
1449 dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY,
1450 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1454 dl_png_write_info(png, info);
1456 dl_png_write_image(png, rows);
1458 dl_png_write_end(png, info);
1460 dl_png_destroy_write_struct(&png, &info);
1463 sdata->dump_count++;
1473 if (write_fd != NULL) {
1483 dl_png_destroy_write_struct(&png, &info);
1486 dl_png_destroy_write_struct(&png, NULL);
1492 tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLContext ctx,
1493 GLSurface surf, GLint fbo, GLint tex, GLint rb, GLint tex_w, GLint tex_h,
1494 GLint tex_format, const char *dump)
1496 Surface_Data *std = NULL;
1498 if (trace_surface_flag == 1) {
1499 AST(mutex_lock(&std_access_mutex) == 1);
1501 if (std_table == NULL) {
1502 std_table = (Surface_Data **)calloc(1,
1503 sizeof(Surface_Data *) * MAX_TRACE_TABLE_SIZE);
1506 std = (Surface_Data *)_get_trace_data((Trace_Data **)std_table,
1507 sizeof(Surface_Data), desc);
1512 _dump_surface(0, 0, dump, std);
1516 std->surface = surf;
1518 if (fbo >= 0) std->fbo = fbo;
1521 if (tex_w >= 0) std->tex_w = tex_w;
1522 if (tex_h >= 0) std->tex_h = tex_h;
1523 if (tex_format >= 0) std->tex_format = tex_format;
1525 AST(mutex_unlock(&std_access_mutex) == 1);
1532 tracepath_surface_trace(int force_output, int type, const char *position)
1536 if (trace_surface_flag != 1) {
1540 AST(mutex_lock(&std_access_mutex) == 1);
1542 if (std_table != NULL) {
1543 EGLDisplay olddpy = _orig_tracepath_eglGetCurrentDisplay();
1544 EGLContext oldctx = _orig_tracepath_eglGetCurrentContext();
1545 EGLSurface oldsurf_read = _orig_tracepath_eglGetCurrentSurface(EGL_READ);
1546 EGLSurface oldsurf_draw = _orig_tracepath_eglGetCurrentSurface(EGL_DRAW);
1548 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1549 if (std_table[i] != NULL) {
1550 Surface_Data *current = std_table[i];
1552 while (current != NULL) {
1553 if (current->surface != EGL_NO_SURFACE && current->display != EGL_NO_DISPLAY &&
1554 current->context != EGL_NO_CONTEXT) {
1555 if (_orig_tracepath_eglMakeCurrent(current->display, current->surface,
1556 current->surface, current->context) == EGL_TRUE) {
1557 _dump_surface(force_output, type, position, current);
1561 current = (Surface_Data *)current->trace_data.next;
1565 _orig_tracepath_eglMakeCurrent(olddpy, oldsurf_read, oldsurf_draw, oldctx);
1569 AST(mutex_unlock(&std_access_mutex) == 1);
1579 coregl_dump_surface()
1581 _COREGL_TRACE_SURFACE(1, 0, "USER CALL");