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 strncpy(newitm->name, name, strlen(newitm->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());
702 if (tstate->ftd_table == NULL) {
703 tstate->ftd_table = (Apicall_Data **)calloc(1,
704 sizeof(Apicall_Data *) * MAX_TRACE_TABLE_SIZE);
707 ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table,
708 sizeof(Apicall_Data), funcname);
715 AST(ftd->last_time.tv_sec == 0);
717 AST(gettimeofday(&ftd->last_time, NULL) == 0);
719 if (initial_time.tv_sec == 0) {
720 initial_time = ftd->last_time;
721 last_initial_time = ftd->last_time;
724 if (trace_total_time == 1) {
725 if (last_trace_time.tv_sec != 0) {
726 _add_timeval_period(&other_elapsed_time, t, last_trace_time);
727 last_trace_time.tv_sec = 0;
737 tracepath_api_trace_end(const char *funcname, void *hint, int trace_total_time)
739 Apicall_Data *ftd = NULL;
740 struct timeval t = TIMEVAL_INIT;
742 if (trace_api_flag == 1) {
743 MY_MODULE_TSTATE *tstate = NULL;
744 struct timeval elapsed_time = TIMEVAL_INIT;
746 AST(gettimeofday(&t, NULL) == 0);
748 ftd = (Apicall_Data *)hint;
751 GET_MY_TSTATE(tstate, get_current_thread_state());
753 if (tstate == NULL) {
754 init_new_thread_state();
756 GET_MY_TSTATE(tstate, get_current_thread_state());
761 AST(tstate && (tstate->ftd_table != NULL));
763 if (tstate && (tstate->ftd_table)) {
764 ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table,
765 sizeof(Apicall_Data), funcname);
771 _add_timeval_period(&elapsed_time, t, ftd->last_time);
773 _add_timeval(&ftd->elapsed_time, elapsed_time);
775 if (elapsed_time.tv_sec >= ftd->elapsed_time_max.tv_sec &&
776 elapsed_time.tv_usec > ftd->elapsed_time_max.tv_usec) {
777 ftd->elapsed_time_max.tv_sec = elapsed_time.tv_sec;
778 ftd->elapsed_time_max.tv_usec = elapsed_time.tv_usec;
781 ftd->last_time.tv_sec = 0;
783 if (trace_total_time == 1) {
784 _add_timeval(&ftd->total_elapsed_time, elapsed_time);
786 AST(gettimeofday(&last_trace_time, NULL) == 0);
788 if (initial_time.tv_sec == 0) {
790 last_initial_time = t;
801 tracepath_api_trace_output(int force_output)
803 static struct timeval tv_last = TIMEVAL_INIT;
804 struct timeval total_now = TIMEVAL_INIT;
805 GLThreadState *tstate = NULL;
806 MY_MODULE_TSTATE *tstate_tm = NULL;
807 Apicall_Data **ftd_table = NULL;
809 double total_elapsed_time = 0.0;
810 double total_elapsed_time_period = 0.0;
811 double total_opengl_elapsed_time = 0.0;
812 double total_opengl_elapsed_time_period = 0.0;
813 double total_other_elapsed_time = 0.0;
814 double total_other_elapsed_time_period = 0.0;
816 double swaps_per_sec = 0.0;
820 if (trace_api_flag != 1) {
825 struct timeval tv_now = TIMEVAL_INIT;
826 AST(gettimeofday(&tv_now, NULL) == 0);
827 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
833 AST(gettimeofday(&total_now, NULL) == 0);
835 total_elapsed_time = _get_timeval_period(total_now, initial_time);
836 total_elapsed_time_period = _get_timeval_period(total_now, last_initial_time);
837 last_initial_time = total_now;
839 total_other_elapsed_time = _get_timeval(other_elapsed_time);
840 total_other_elapsed_time_period = _get_timeval_period(other_elapsed_time,
841 traced_other_elapsed_time);
842 traced_other_elapsed_time = other_elapsed_time;
844 tstate = get_current_thread_state();
846 if (tstate == NULL) {
847 init_new_thread_state();
849 tstate = get_current_thread_state();
853 GET_MY_TSTATE(tstate_tm, tstate);
854 if (tstate_tm == NULL) goto finish;
856 ftd_table = tstate_tm->ftd_table;
857 if (ftd_table == NULL) goto finish;
860 static Apicall_Data *trace_hint_swap = NULL;
861 if (trace_hint_swap == NULL)
862 trace_hint_swap = (Apicall_Data *)_get_trace_data((Trace_Data **)ftd_table,
863 sizeof(Apicall_Data), "tracepath_eglSwapBuffers");
865 if (trace_hint_swap != NULL && total_elapsed_time_period > 0) {
866 swaps_per_sec = (trace_hint_swap->call_count -
867 trace_hint_swap->last_call_count) / (total_elapsed_time_period / 1000);
873 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
874 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",
875 getpid(), tstate->thread_id, swaps_per_sec);
876 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
879 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
880 if (ftd_table[i] != NULL) {
881 Apicall_Data *current = ftd_table[i];
883 while (current != NULL) {
884 double elapsed_time = _get_timeval(current->elapsed_time);
885 double elapsed_time_per_call = elapsed_time / current->call_count;
887 total_opengl_elapsed_time += _get_timeval(current->total_elapsed_time);
888 total_opengl_elapsed_time_period += _get_timeval(current->total_elapsed_time) -
889 _get_timeval(current->last_total_elapsed_time);
893 if (current->call_count > current->last_call_count) {
894 double elapsed_time_period = _get_timeval_period(current->elapsed_time,
895 current->last_elapsed_time);
896 double elapsed_time_max = _get_timeval(current->elapsed_time_max);
897 double elapsed_time_per_call_period = elapsed_time_period /
898 (current->call_count - current->last_call_count);
899 char *fname = current->trace_data.name;
901 if (!strncmp(fname, "tracepath_", 10))
902 fname = ¤t->trace_data.name[10];
904 if (elapsed_time_per_call_period >= 0.01 ||
905 current->call_count - current->last_call_count > 1000) {
906 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",
907 fname, current->call_count, elapsed_time_per_call, elapsed_time_max,
908 elapsed_time_per_call_period);
912 current = (Apicall_Data *)current->trace_data.next;
919 fp_env = atoi(get_env_setting("COREGL_TRACE_API_ALL"));
922 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
923 if (ftd_table[i] != NULL) {
924 Apicall_Data *current = ftd_table[i];
926 while (current != NULL) {
927 if (current->traced == 0 && current->call_count > 0) {
928 double elapsed_time = _get_timeval(current->elapsed_time);
929 double elapsed_time_per_call = elapsed_time / current->call_count;
930 double elapsed_time_max = _get_timeval(current->elapsed_time_max);
931 char *fname = current->trace_data.name;
933 if (!strncmp(fname, "tracepath_", 10))
934 fname = ¤t->trace_data.name[10];
936 TRACE(" %-39.39s : %10d call(s), %9.3f ms/API, %9.2f ms(MAX)\n",
937 fname, current->call_count, elapsed_time_per_call, elapsed_time_max);
939 current = (Apicall_Data *)current->trace_data.next;
946 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
948 if (trace_api_frame_flag == 0) {
949 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
950 "TOTAL elapsed Time",
953 total_elapsed_time_period,
957 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
958 "OpenGL elapsed Time",
959 total_opengl_elapsed_time,
960 total_opengl_elapsed_time * 100.0 / total_elapsed_time,
961 total_opengl_elapsed_time_period,
962 total_opengl_elapsed_time_period * 100.0 / total_elapsed_time_period);
964 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
965 "Out of OpenGL elapsed time",
966 total_other_elapsed_time,
967 total_other_elapsed_time * 100.0 / total_elapsed_time,
968 total_other_elapsed_time_period,
969 total_other_elapsed_time_period * 100.0 / total_elapsed_time_period);
971 TRACE("\E[40;36;1m %-39.39s : %13.2f ms[%6.2f%%], %13.2f ms(P)[%6.2f%%]\E[0m\n",
972 "CoreGL API tracing overhead",
973 total_elapsed_time - total_opengl_elapsed_time - total_other_elapsed_time,
974 (total_elapsed_time - total_opengl_elapsed_time - total_other_elapsed_time) *
975 100.0 / total_elapsed_time,
976 total_elapsed_time_period - total_opengl_elapsed_time_period -
977 total_other_elapsed_time_period,
978 (total_elapsed_time_period - total_opengl_elapsed_time_period -
979 total_other_elapsed_time_period) * 100.0 / total_elapsed_time_period);
981 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
985 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
986 if (ftd_table[i] != NULL) {
987 Apicall_Data *current = ftd_table[i];
989 while (current != NULL) {
990 current->last_call_count = current->call_count;
991 current->last_elapsed_time = current->elapsed_time;
992 current->last_total_elapsed_time = current->total_elapsed_time;
993 current = (Apicall_Data *)current->trace_data.next;
1007 tracepath_api_trace_reset_frame()
1009 GLThreadState *tstate = NULL;
1010 MY_MODULE_TSTATE *tstate_tm = NULL;
1011 Apicall_Data **ftd_table = NULL;
1015 if (trace_api_flag != 1) {
1019 tstate = get_current_thread_state();
1021 if (tstate == NULL) {
1022 init_new_thread_state();
1024 tstate = get_current_thread_state();
1025 AST(tstate != NULL);
1028 GET_MY_TSTATE(tstate_tm, tstate);
1029 if (tstate_tm == NULL) goto finish;
1031 ftd_table = tstate_tm->ftd_table;
1032 if (ftd_table == NULL) goto finish;
1034 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1035 if (ftd_table[i] != NULL) {
1036 Apicall_Data *current = ftd_table[i];
1038 while (current != NULL) {
1039 current->call_count = 0;
1040 current->last_call_count = 0;
1041 current->elapsed_time.tv_sec = 0;
1042 current->elapsed_time.tv_usec = 0;
1043 current->last_elapsed_time.tv_sec = 0;
1044 current->last_elapsed_time.tv_usec = 0;
1045 current->last_total_elapsed_time.tv_sec = 0;
1046 current->last_total_elapsed_time.tv_usec = 0;
1047 current->total_elapsed_time.tv_sec = 0;
1048 current->total_elapsed_time.tv_usec = 0;
1049 current = (Apicall_Data *)current->trace_data.next;
1053 AST(gettimeofday(&last_initial_time, NULL) == 0);
1061 tracepath_mem_trace_output(int force_output)
1063 static struct timeval tv_last = TIMEVAL_INIT;
1067 if (trace_mem_flag != 1) {
1071 if (!force_output) {
1072 struct timeval tv_now = TIMEVAL_INIT;
1073 AST(gettimeofday(&tv_now, NULL) == 0);
1074 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
1081 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1082 TRACE("\E[40;32;1m Memory usage info \E[1;37;1m: <PID = %d>\E[0m\n", getpid());
1083 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1085 if (mtd_table != NULL) {
1086 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1087 if (mtd_table[i] != NULL) {
1088 Memuse_Data *current = mtd_table[i];
1090 while (current != NULL) {
1091 int obj_count = current->alloc_count - current->remove_count;
1092 if (obj_count > 0) {
1093 TRACE("\E[40;37;1m %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\E[0m\n",
1094 current->trace_data.name, current->memsize, obj_count, current->alloc_count,
1095 current->remove_count);
1097 current = (Memuse_Data *)current->trace_data.next;
1102 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1103 if (mtd_table[i] != NULL) {
1104 Memuse_Data *current = mtd_table[i];
1106 while (current != NULL) {
1107 int obj_count = current->alloc_count - current->remove_count;
1108 if (obj_count == 0) {
1109 TRACE(" %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\n",
1110 current->trace_data.name, current->memsize, obj_count, current->alloc_count,
1111 current->remove_count);
1113 current = (Memuse_Data *)current->trace_data.next;
1119 TRACE("\E[40;34m========================================================================================================================\E[0m\n");
1132 void *png_lib_handle = NULL;
1134 png_structp (*dl_png_create_write_struct) (png_const_charp user_png_ver,
1135 png_voidp error_ptr,
1136 png_error_ptr error_fn,
1137 png_error_ptr warn_fn);
1140 void (*dl_png_destroy_write_struct) (png_structpp png_ptr_ptr,
1141 png_infopp info_ptr_ptr);
1144 png_infop (*dl_png_create_info_struct) (png_structp png_ptr);
1146 void (*dl_png_init_io) (png_structp png_ptr,
1150 void (*dl_png_set_IHDR) (png_structp png_ptr,
1156 int interlace_method,
1157 int compression_method,
1160 void (*dl_png_set_bKGD) (png_structp png_ptr,
1162 png_color_16p background);
1164 void (*dl_png_set_bgr) (png_structp png_ptr);
1166 void (*dl_png_write_info) (png_structp png_ptr,
1167 png_infop info_ptr);
1169 void (*dl_png_write_image) (png_structp png_ptr,
1172 void (*dl_png_write_end) (png_structp png_ptr,
1173 png_infop info_ptr);
1176 _dump_surface(int force_output, int type, const char *position,
1177 Surface_Data *sdata)
1179 static int alldumpcount = 0;
1180 unsigned char *data = NULL;
1181 EGLint width = -1, height = -1, channel = -1;
1183 FILE *write_fd = NULL;
1184 png_struct *png = NULL;
1185 png_info *info = NULL;
1186 png_byte **rows = NULL;
1187 GLenum ret_value = _COREGL_INT_INIT_VALUE;
1189 if (!png_lib_handle) {
1190 png_lib_handle = dlopen("libpng16.so.16", RTLD_NOW);
1192 dl_png_create_write_struct = dlsym(png_lib_handle, "png_create_write_struct");
1193 dl_png_destroy_write_struct = dlsym(png_lib_handle, "png_destroy_write_struct");
1194 dl_png_create_info_struct = dlsym(png_lib_handle, "png_create_info_struct");
1196 dl_png_init_io = dlsym(png_lib_handle, "png_init_io");
1198 dl_png_set_IHDR = dlsym(png_lib_handle, "png_set_IHDR");
1199 dl_png_set_bKGD = dlsym(png_lib_handle, "png_set_bKGD");
1200 dl_png_set_bgr = dlsym(png_lib_handle, "png_set_bgr");
1202 dl_png_write_info = dlsym(png_lib_handle, "png_write_info");
1203 dl_png_write_image = dlsym(png_lib_handle, "png_write_image");
1204 dl_png_write_end = dlsym(png_lib_handle, "png_write_end");
1208 if (!png_lib_handle ||
1209 dl_png_create_write_struct == NULL ||
1210 dl_png_destroy_write_struct == NULL ||
1211 dl_png_create_info_struct == NULL ||
1212 dl_png_init_io == NULL ||
1213 dl_png_set_IHDR == NULL ||
1214 dl_png_set_bKGD == NULL ||
1215 dl_png_set_bgr == NULL ||
1216 dl_png_write_info == NULL ||
1217 dl_png_write_image == NULL ||
1218 dl_png_write_end == NULL) {
1219 COREGL_ERR("Can't trace surface : Failed to use libpng (recommend : 1.2.50-3.4)");
1223 if (trace_surface_sequence_sort_flag == 1)
1224 snprintf(name, sizeof(name), "[%d (%06d)%p-%p] %s %04d (%s).png", getpid(),
1226 sdata->display, sdata->context, sdata->trace_data.name, sdata->dump_count,
1229 snprintf(name, sizeof(name), "[%d %p-%p] %s %04d (%s).png", getpid(),
1231 sdata->context, sdata->trace_data.name, sdata->dump_count, position);
1233 if (!strncmp(sdata->trace_data.name, "EGL", 3) && type != 2) {
1235 if (trace_surface_filter_type != 0 &&
1236 trace_surface_filter_type != 1) goto finish;;
1238 if (trace_surface_filter_handle != 0 &&
1239 trace_surface_filter_handle != (int)sdata->surface) goto finish;
1241 EGLConfig eglconfig;
1242 GLint asize, rsize, gsize, bsize;
1243 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_WIDTH,
1245 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_HEIGHT,
1247 _orig_tracepath_eglQuerySurface(sdata->display, sdata->surface, EGL_CONFIG_ID,
1248 (GLint *)&eglconfig);
1249 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_ALPHA_SIZE,
1251 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_RED_SIZE,
1253 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_GREEN_SIZE,
1255 _orig_tracepath_eglGetConfigAttrib(sdata->display, eglconfig, EGL_BLUE_SIZE,
1258 if (asize == 0) channel = 3;
1259 if (bsize == 0) channel = 2;
1260 if (gsize == 0) channel = 1;
1261 if (rsize == 0) channel = 0;
1263 if (channel == 2) channel = 3;
1264 if (width <= 0 || height <= 0 || channel <= 0) goto finish;
1265 if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
1266 (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
1269 if ((trace_surface_filter_period_begin > 0 ||
1270 trace_surface_filter_period_end > 0) &&
1271 (trace_surface_filter_period_begin > alldumpcount ||
1272 trace_surface_filter_period_end < alldumpcount)) {
1274 sdata->dump_count++;
1278 if (channel == 3) channel = 4;
1280 TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
1281 width, height, channel);
1282 if (trace_surface_print_only_flag == 1 && force_output == 0) {
1284 sdata->dump_count++;
1288 data = (unsigned char *)calloc(1,
1289 width * height * channel * sizeof(unsigned char));
1291 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1296 _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
1297 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, 0);
1301 _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1304 //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
1306 _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
1311 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1313 if (!strncmp(sdata->trace_data.name, "FBO", 3) && type != 1) {
1315 if (sdata->fbo == 0) goto finish;
1317 if (trace_surface_filter_type != 0 &&
1318 trace_surface_filter_type != 2) goto finish;
1320 if (trace_surface_filter_handle != 0 &&
1321 trace_surface_filter_handle != sdata->tex &&
1322 trace_surface_filter_handle != sdata->rb) goto finish;
1325 _orig_tracepath_glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfb);
1326 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
1328 if (driver_gl_version >= 2)
1329 ret_value = _orig_tracepath_glCheckFramebufferStatus(GL_FRAMEBUFFER);
1331 ret_value = _orig_tracepath_glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
1332 if (ret_value == GL_FRAMEBUFFER_COMPLETE) {
1333 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1334 width = sdata->tex_w;
1335 height = sdata->tex_h;
1336 channel = sdata->tex_format;
1338 if (channel == 2) channel = 3;
1339 if (width <= 0 || height <= 0 || channel <= 0) goto finish;
1340 if (trace_surface_filter_size_w > 0 && trace_surface_filter_size_h > 0 &&
1341 (trace_surface_filter_size_w != width || trace_surface_filter_size_h != height))
1344 if ((trace_surface_filter_period_begin > 0 ||
1345 trace_surface_filter_period_end > 0) &&
1346 (trace_surface_filter_period_begin > alldumpcount ||
1347 trace_surface_filter_period_end < alldumpcount)) {
1349 sdata->dump_count++;
1353 TRACE("\E[40;31;1m[[TRACE SURFACE]] : '%s' is dumped (%dx%dx%d).\E[0m\n", name,
1354 width, height, channel);
1355 if (trace_surface_print_only_flag == 1 && force_output == 0) {
1357 sdata->dump_count++;
1361 if (channel == 3) channel = 4;
1363 data = (unsigned char *)calloc(1,
1364 width * height * channel * sizeof(unsigned char));
1366 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1370 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, sdata->fbo);
1371 int atttype = _COREGL_INT_INIT_VALUE;
1372 if (driver_gl_version >= 2)
1373 _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
1374 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
1376 _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
1377 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atttype);
1378 AST(atttype != sdata->tex);
1379 int attname = _COREGL_INT_INIT_VALUE;
1380 if (driver_gl_version >= 2)
1381 _orig_tracepath_glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
1382 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
1384 _orig_tracepath_glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER,
1385 GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attname);
1388 AST(attname == sdata->tex);
1390 case GL_RENDERBUFFER:
1391 AST(attname == sdata->rb);
1397 _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
1400 //case 3: _orig_tracepath_glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); break;
1402 _orig_tracepath_glReadPixels(0, 0, width, height, GL_ALPHA, GL_UNSIGNED_BYTE,
1407 _orig_tracepath_glBindFramebuffer(GL_FRAMEBUFFER, oldfb);
1412 if (data == NULL) goto finish;
1415 write_fd = fopen(name, "wb");
1417 if (write_fd == NULL) {
1418 COREGL_ERR("Can't trace surface : Failed to create png file");
1422 rows = (png_byte **)malloc(height * sizeof(png_byte *));
1424 COREGL_ERR("Can't trace surface : Failed to allocate memory");
1428 for (int i = 0; i < height; i++) {
1429 rows[i] = data + (height - i - 1) * (width * channel);
1432 png = dl_png_create_write_struct(PNG_LIBPNG_VER_STRING,
1437 COREGL_ERR("Can't trace surface : Failed to create write structure of png file");
1441 info = dl_png_create_info_struct(png);
1443 COREGL_ERR("Can't trace surface : Failed to create info structure of png file");
1447 dl_png_init_io(png, write_fd);
1451 dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
1452 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1454 //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;
1456 dl_png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY,
1457 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1461 dl_png_write_info(png, info);
1463 dl_png_write_image(png, rows);
1465 dl_png_write_end(png, info);
1467 dl_png_destroy_write_struct(&png, &info);
1470 sdata->dump_count++;
1480 if (write_fd != NULL) {
1490 if (dl_png_destroy_write_struct)
1491 dl_png_destroy_write_struct(&png, &info);
1494 if (dl_png_destroy_write_struct)
1495 dl_png_destroy_write_struct(&png, NULL);
1502 tracepath_surface_trace_add(const char *desc, GLDisplay dpy, GLContext ctx,
1503 GLSurface surf, GLint fbo, GLint tex, GLint rb, GLint tex_w, GLint tex_h,
1504 GLint tex_format, const char *dump)
1506 Surface_Data *std = NULL;
1508 if (trace_surface_flag == 1) {
1509 AST(mutex_lock(&std_access_mutex) == 1);
1511 if (std_table == NULL) {
1512 std_table = (Surface_Data **)calloc(1,
1513 sizeof(Surface_Data *) * MAX_TRACE_TABLE_SIZE);
1516 std = (Surface_Data *)_get_trace_data((Trace_Data **)std_table,
1517 sizeof(Surface_Data), desc);
1522 _dump_surface(0, 0, dump, std);
1526 std->surface = surf;
1528 if (fbo >= 0) std->fbo = fbo;
1531 if (tex_w >= 0) std->tex_w = tex_w;
1532 if (tex_h >= 0) std->tex_h = tex_h;
1533 if (tex_format >= 0) std->tex_format = tex_format;
1535 AST(mutex_unlock(&std_access_mutex) == 1);
1542 tracepath_surface_trace(int force_output, int type, const char *position)
1546 if (trace_surface_flag != 1) {
1550 AST(mutex_lock(&std_access_mutex) == 1);
1552 if (std_table != NULL) {
1553 EGLDisplay olddpy = _orig_tracepath_eglGetCurrentDisplay();
1554 EGLContext oldctx = _orig_tracepath_eglGetCurrentContext();
1555 EGLSurface oldsurf_read = _orig_tracepath_eglGetCurrentSurface(EGL_READ);
1556 EGLSurface oldsurf_draw = _orig_tracepath_eglGetCurrentSurface(EGL_DRAW);
1558 for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++) {
1559 if (std_table[i] != NULL) {
1560 Surface_Data *current = std_table[i];
1562 while (current != NULL) {
1563 if (current->surface != EGL_NO_SURFACE && current->display != EGL_NO_DISPLAY &&
1564 current->context != EGL_NO_CONTEXT) {
1565 if (_orig_tracepath_eglMakeCurrent(current->display, current->surface,
1566 current->surface, current->context) == EGL_TRUE) {
1567 _dump_surface(force_output, type, position, current);
1571 current = (Surface_Data *)current->trace_data.next;
1575 _orig_tracepath_eglMakeCurrent(olddpy, oldsurf_read, oldsurf_draw, oldctx);
1579 AST(mutex_unlock(&std_access_mutex) == 1);
1589 coregl_dump_surface()
1591 _COREGL_TRACE_SURFACE(1, 0, "USER CALL");