[Title] Added a new memory tracing feature(and some minor updates)
authorHaegeun Park <haegeun.park@samsung.com>
Fri, 27 Jul 2012 09:19:23 +0000 (02:19 -0700)
committerHaegeun Park <haegeun.park@samsung.com>
Fri, 27 Jul 2012 09:19:23 +0000 (02:19 -0700)
[Issue#] J number N/A
[Problem] N/A
[Cause] N/A
[Solution] Changed following items

  - Added a new memory tracing feature (client allocated textures and renderbuffers)
      COREGL_TRACE_MEM=1

  - A PID is notified on the top of all tracing message

  - Added context tracing when FASTPATH is disabled

  - Added a BUILD-DATE info on the launching message
      [COREGL] <PID> (BUILD-DATE) Library initializing...

  - Disabled APPOPT logs

  - Fix minor bugs
      invalid value of 'Swaps per sec' of the API trace

Makefile
src/coregl.c
src/coregl_internal.h
src/coregl_trace.c
src/modules/appopt/coregl_appopt.c
src/modules/fastpath/coregl_fastpath.c
src/modules/fastpath/coregl_fastpath_egl.c
src/modules/tracepath/coregl_tracepath.c
src/modules/tracepath/coregl_tracepath.h
src/modules/tracepath/coregl_tracepath_egl.c
src/modules/tracepath/coregl_tracepath_gl.c

index a56a55a..a168876 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
 CC = gcc
 
-CFLAGS = -g -O2 -fvisibility=hidden -fPIC -Wall -std=c99
+COMPILE_DATE = "\"`git log -1 --pretty=format:%ci`\""
 
+CFLAGS = -g -O2 -fvisibility=hidden -fPIC -Wall -std=c99 -D_COREGL_COMPILE_DATE=$(COMPILE_DATE)
 
 LDFLAGS = -g -O2 -fvisibility=hidden -Wall -std=c99 -ldl -lpthread
 
index fe98420..de7161c 100644 (file)
@@ -2,6 +2,10 @@
 #include <stdio.h>
 #include <dlfcn.h>
 #include <string.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
 #include "coregl_internal.h"
 #include "coregl_export.h"
 
@@ -34,6 +38,7 @@ cleanup_current_thread_state()
        {
                LOG("[COREGL] de-init thread state \n");
                deinit_modules_tstate(tstate);
+               remove_from_general_trace_list(&thread_trace_list, tstate);
                free(tstate);
                tstate = NULL;
        }
@@ -52,14 +57,11 @@ init_new_thread_state()
 
        tstate = (GLThreadState *)calloc(1, sizeof(GLThreadState));
        tstate->thread_id = get_current_thread();
+       add_to_general_trace_list(&thread_trace_list, tstate);
 
        init_modules_tstate(tstate);
-
        set_current_thread_state(tstate);
 
-#ifdef COREGL_TRACE_CONTEXT_INFO
-       add_to_general_trace_list(&thread_trace_list, tstate);
-#endif // COREGL_TRACE_CONTEXT_INFO
        ret = 1;
        goto finish;
 
@@ -189,7 +191,7 @@ _gl_lib_deinit(void)
 int
 coregl_initialize()
 {
-       LOG("[CoreGL] Library initializing...");
+       LOG("[CoreGL] <%d> (%s) Library initializing...", getpid(), _COREGL_COMPILE_DATE);
 
        if (!_gl_lib_init()) return 0;
 
index 76a18f6..758c67e 100644 (file)
@@ -55,8 +55,6 @@ typedef GLuint       GLuintmask;
 # define GLERR(fn, fl, ln, op)
 #endif
 
-typedef struct _Trace_Data Trace_Data;
-
 #define COREGL_OVERRIDE_API(mangle, func, prefix) \
    mangle##func = prefix##func
 
@@ -64,6 +62,8 @@ typedef EGLSurface     GLSurface;
 typedef EGLDisplay     GLDisplay;
 typedef EGLContext     GLContext;
 
+#define COREGL_GL_NO_CONTEXT EGL_NO_CONTEXT
+
 typedef struct _GLThreadState
 {
        int                      thread_id;
@@ -88,11 +88,12 @@ extern FILE               *trace_fp;
 
 extern int                 trace_api_flag;
 extern int                 trace_api_all_flag;
+extern int                 trace_mem_flag;
 extern int                 trace_ctx_flag;
 extern int                 trace_ctx_force_flag;
 extern int                 trace_state_flag;
 
-#define USE_TRACEPATH          (trace_api_flag == 1 || trace_ctx_flag == 1 || trace_state_flag == 1)
+#define USE_TRACEPATH          (trace_api_flag == 1 || trace_ctx_flag == 1 || trace_state_flag == 1 || trace_mem_flag == 1)
 
 // Environment functions
 extern const char         *get_env_setting(const char *name);
index 4d1c335..88141ff 100644 (file)
@@ -8,6 +8,7 @@ int                 trace_api_flag = 0;
 int                 trace_api_all_flag = 0;
 int                 trace_ctx_flag = 0;
 int                 trace_ctx_force_flag = 0;
+int                 trace_mem_flag = 0;
 int                 trace_state_flag = 0;
 
 General_Trace_List *thread_trace_list = NULL;
index f872fa8..3337f6b 100644 (file)
@@ -11,9 +11,9 @@
 void
 init_modules_appopt()
 {
-       LOG("[CoreGL] <Appopt> : ");
+//     LOG("[CoreGL] <Appopt> : ");
 
-       LOG("Not yet implemented\n");
+//     LOG("Not yet implemented\n");
 
        appopt_apply_overrides();
 }
index e4cb861..0a4a9fa 100644 (file)
@@ -4,6 +4,9 @@
 #include <string.h>
 #include <sys/time.h>
 
+#include <sys/types.h>
+#include <unistd.h>
+
 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST)     RET_TYPE (*_orig_fastpath_##FUNC_NAME) PARAM_LIST = NULL;
 #include "../../headers/sym.h"
 #undef _COREGL_SYMBOL
@@ -600,7 +603,7 @@ fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
 
        TRACE("\n");
        TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
-       TRACE("\E[0;32;1m  State info \E[1;37;1m: GlueCTX = %p\E[0m\n", ctx);
+       TRACE("\E[0;32;1m  State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
        TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
 
 #define PRINTF_CHAR_GLenum "%10d"
index 74dd03b..ae628e9 100644 (file)
@@ -5,6 +5,9 @@
 #include <sys/time.h>
 #include <execinfo.h>
 
+#include <sys/types.h>
+#include <unistd.h>
+
 #ifdef COREGL_FASTPATH_TRACE_CONTEXT_INFO
 
 General_Trace_List *glue_ctx_trace_list = NULL;
@@ -36,7 +39,7 @@ _dump_context_info(const char *ment, int force_output)
 
        TRACE("\n");
        TRACE("\E[40;34m========================================================================================================================\E[0m\n");
-       TRACE("\E[40;32;1m  Context info \E[1;37;1m: %s\E[0m\n", ment);
+       TRACE("\E[40;32;1m  Context info \E[1;37;1m: <PID = %d> %s\E[0m\n", getpid(), ment);
        TRACE("\E[40;34m========================================================================================================================\E[0m\n");
 
 
index ed09df7..351750e 100644 (file)
@@ -4,18 +4,25 @@
 #include <string.h>
 #include <sys/time.h>
 
+#include <sys/types.h>
+#include <unistd.h>
+
 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST)     RET_TYPE (*_orig_tracepath_##FUNC_NAME) PARAM_LIST = NULL;
 #include "../../headers/sym.h"
 #undef _COREGL_SYMBOL
 
 #define TIMEVAL_INIT            { 0, 0 }
 
-#define MAX_TRACE_NAME_LENGTH  256
-#define MAX_TRACE_TABLE_SIZE   65536
-
 struct _Trace_Data
 {
        char                         name[MAX_TRACE_NAME_LENGTH];
+       struct _Trace_Data          *next;
+};
+
+struct _Apicall_Data
+{
+       struct _Trace_Data          trace_data;
+
        int                          call_count;
        int                          last_call_count;
        struct timeval              elapsed_time;
@@ -26,8 +33,15 @@ struct _Trace_Data
        struct timeval              last_time;
 
        int                          traced;
+};
 
-       struct _Trace_Data          *next;
+struct _Memuse_Data
+{
+       struct _Trace_Data          trace_data;
+
+       int                          memsize;
+       int                          alloc_count;
+       int                          remove_count;
 };
 
 typedef struct _GLGlueFakeContext
@@ -46,6 +60,9 @@ struct timeval     last_trace_time = TIMEVAL_INIT;
 struct timeval     other_elapsed_time = TIMEVAL_INIT;
 struct timeval     traced_other_elapsed_time = TIMEVAL_INIT;
 
+Mutex               mtd_access_mutex = MUTEX_INITIALIZER;
+Memuse_Data       **mtd_table;
+
 static void
 _get_texture_states(GLenum pname, GLint *params)
 {
@@ -81,6 +98,9 @@ init_modules_tracepath()
        trace_api_flag = atoi(get_env_setting("COREGL_TRACE_API"));
        trace_api_all_flag = atoi(get_env_setting("COREGL_TRACE_API_ALL"));
 #endif
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       trace_mem_flag = atoi(get_env_setting("COREGL_TRACE_MEM"));
+#endif
 #ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
        trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
        trace_ctx_force_flag = atoi(get_env_setting("COREGL_TRACE_CTX_FORCE"));
@@ -91,20 +111,24 @@ init_modules_tracepath()
 
        if (USE_TRACEPATH)
        {
-               LOG("[CoreGL] <Trace> : ");
+               LOG("[CoreGL] \E[40;32;1m<Trace> \E[40;37;1m: ");
 
                if (trace_api_flag == 1)
                {
-                       LOG("(API) ");
-                       if (trace_api_all_flag == 1) LOG("(API-ALL) ");
+                       LOG("\E[40;31;1m(API)\E[0m ");
+                       if (trace_api_all_flag == 1) LOG("\E[40;31;1m(API-ALL)\E[0m ");
                }
                if (trace_ctx_flag == 1) {
-                       LOG("(CONTEXT) ");
-                       if (trace_ctx_force_flag == 1) LOG("(CONTEXT-FORCE) ");
+                       LOG("\E[40;33;1m(CONTEXT)\E[0m ");
+                       if (trace_ctx_force_flag == 1) LOG("\E[40;33;1m(CONTEXT-FORCE)\E[0m ");
+               }
+               if (trace_state_flag == 1) LOG("\E[40;36;1m(STATE)\E[0m ");
+               if (trace_mem_flag == 1)
+               {
+                       LOG("\E[40;35;1m(MEM)\E[0m ");
                }
-               if (trace_state_flag == 1) LOG("(STATE) ");
 
-               LOG("enabled\n");
+               LOG("\E[40;37;1menabled\E[0m\n");
        }
 
        tracepath_apply_overrides();
@@ -202,7 +226,7 @@ tracepath_dump_context_states(int force_output)
 
        TRACE("\n");
        TRACE("\E[0;40;34m===================================================================================================================\E[0m\n");
-       TRACE("\E[0;32;1m  State info \E[1;37;1m: (CURRENT BINDED CONTEXT)\E[0m\n");
+       TRACE("\E[0;32;1m  State info \E[1;37;1m: <PID = %d> (CURRENT BINDED CONTEXT)\E[0m\n", getpid());
        TRACE("\E[0;40;34m===================================================================================================================\E[0m\n");
 
 #define PRINTF_CHAR_GLenum "%10d"
@@ -304,7 +328,7 @@ _generate_hash_short(const char *string)
 }
 
 static Trace_Data *
-_get_trace_data(Trace_Data **ftd_table, const char *name)
+_get_trace_data(Trace_Data **ftd_table, size_t td_size, const char *name)
 {
        Trace_Data *ret = NULL;
        Trace_Data *current = NULL;
@@ -332,7 +356,7 @@ _get_trace_data(Trace_Data **ftd_table, const char *name)
        else
        {
                Trace_Data *newitm = NULL;
-               newitm = (Trace_Data *)calloc(1, sizeof(Trace_Data));
+               newitm = (Trace_Data *)calloc(1, td_size);
                strcpy(newitm->name, name);
                newitm->next = NULL;
 
@@ -353,17 +377,73 @@ finish:
        return ret;
 }
 
+void
+tracepath_mem_trace_add(const char *desc, int alloc_size)
+{
+       Memuse_Data *mtd = NULL;
+
+       if (trace_mem_flag == 1)
+       {
+               AST(mutex_lock(&mtd_access_mutex) == 1);
+
+               if (mtd_table == NULL)
+               {
+                       mtd_table = (Memuse_Data **)calloc(1, sizeof(Memuse_Data *) * MAX_TRACE_TABLE_SIZE);
+               }
+
+               mtd = (Memuse_Data *)_get_trace_data((Trace_Data **)mtd_table, sizeof(Memuse_Data), desc);
+
+               AST(mtd != NULL);
+
+               mtd->alloc_count++;
+
+               if (mtd->memsize == 0)
+                       mtd->memsize = alloc_size;
+
+               AST(mtd->memsize == alloc_size);
+
+               AST(mutex_unlock(&mtd_access_mutex) == 1);
+       }
+
+}
+
+void
+tracepath_mem_trace_remove(const char *desc, int alloc_size)
+{
+       Memuse_Data *mtd = NULL;
+
+       if (trace_mem_flag == 1)
+       {
+               AST(mutex_lock(&mtd_access_mutex) == 1);
+
+               if (mtd_table == NULL)
+               {
+                       mtd_table = (Memuse_Data **)calloc(1, sizeof(Memuse_Data *) * MAX_TRACE_TABLE_SIZE);
+               }
+
+               mtd = (Memuse_Data *)_get_trace_data((Trace_Data **)mtd_table, sizeof(Memuse_Data), desc);
+
+               AST(mtd != NULL);
+               AST(mtd->memsize == alloc_size);
+
+               AST(mtd->alloc_count > mtd->remove_count);
+               mtd->remove_count++;
+
+               AST(mutex_unlock(&mtd_access_mutex) == 1);
+       }
+}
+
 void *
 tracepath_api_trace_begin(const char *funcname, void *hint, int trace_total_time)
 {
-       Trace_Data *ftd = NULL;
+       Apicall_Data *ftd = NULL;
        struct timeval t = TIMEVAL_INIT;
 
        if (trace_api_flag == 1)
        {
                AST(gettimeofday(&t, NULL) == 0);
 
-               ftd = (Trace_Data *)hint;
+               ftd = (Apicall_Data *)hint;
 
                if (ftd == NULL)
                {
@@ -380,10 +460,10 @@ tracepath_api_trace_begin(const char *funcname, void *hint, int trace_total_time
 
                        if (tstate->ftd_table == NULL)
                        {
-                               tstate->ftd_table = (Trace_Data **)calloc(1, sizeof(Trace_Data *) * MAX_TRACE_TABLE_SIZE);
+                               tstate->ftd_table = (Apicall_Data **)calloc(1, sizeof(Apicall_Data *) * MAX_TRACE_TABLE_SIZE);
                        }
 
-                       ftd = _get_trace_data(tstate->ftd_table, funcname);
+                       ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table, sizeof(Apicall_Data), funcname);
                }
 
                AST(ftd != NULL);
@@ -416,7 +496,7 @@ tracepath_api_trace_begin(const char *funcname, void *hint, int trace_total_time
 void *
 tracepath_api_trace_end(const char *funcname, void *hint, int trace_total_time)
 {
-       Trace_Data *ftd = NULL;
+       Apicall_Data *ftd = NULL;
        struct timeval t = TIMEVAL_INIT;
 
        if (trace_api_flag == 1)
@@ -426,7 +506,7 @@ tracepath_api_trace_end(const char *funcname, void *hint, int trace_total_time)
 
                AST(gettimeofday(&t, NULL) == 0);
 
-               ftd = (Trace_Data *)hint;
+               ftd = (Apicall_Data *)hint;
 
                if (ftd == NULL)
                {
@@ -443,7 +523,7 @@ tracepath_api_trace_end(const char *funcname, void *hint, int trace_total_time)
                        AST(tstate != NULL);
                        AST(tstate->ftd_table != NULL);
 
-                       ftd = _get_trace_data(tstate->ftd_table, funcname);
+                       ftd = (Apicall_Data *)_get_trace_data((Trace_Data **)tstate->ftd_table, sizeof(Apicall_Data), funcname);
                }
 
                AST(ftd != NULL);
@@ -487,7 +567,7 @@ tracepath_api_trace_output(int force_output)
        struct timeval total_now = TIMEVAL_INIT;
        GLThreadState *tstate = NULL;
        MY_MODULE_TSTATE *tstate_tm = NULL;
-       Trace_Data **ftd_table = NULL;
+       Apicall_Data **ftd_table = NULL;
 
        double total_elapsed_time = 0.0;
        double total_elapsed_time_period = 0.0;
@@ -543,9 +623,9 @@ tracepath_api_trace_output(int force_output)
        if (ftd_table == NULL) return;
 
        {
-               static Trace_Data *trace_hint_swap = NULL;
+               static Apicall_Data *trace_hint_swap = NULL;
                if (trace_hint_swap == NULL)
-                       trace_hint_swap = _get_trace_data(ftd_table, "eglSwapBuffers");
+                       trace_hint_swap = (Apicall_Data *)_get_trace_data((Trace_Data **)ftd_table, sizeof(Apicall_Data), "tracepath_eglSwapBuffers");
 
                if (trace_hint_swap != NULL && total_elapsed_time_period > 0)
                {
@@ -556,7 +636,7 @@ tracepath_api_trace_output(int force_output)
 
        TRACE("\n");
        TRACE("\E[40;34m========================================================================================================================\E[0m\n");
-       TRACE("\E[40;32;1m  API call info \E[1;37;1m: Thread ID = %d  [Swaps per Second(P) = %7.2f]\E[0m\n", tstate->thread_id, swaps_per_sec);
+       TRACE("\E[40;32;1m  API call info \E[1;37;1m: <PID = %d> Thread ID = %d  [Swaps per Second(P) = %7.2f]\E[0m\n", getpid(), tstate->thread_id, swaps_per_sec);
        TRACE("\E[40;34m========================================================================================================================\E[0m\n");
 
        // highlighted
@@ -564,7 +644,7 @@ tracepath_api_trace_output(int force_output)
        {
                if (ftd_table[i] != NULL)
                {
-                       Trace_Data *current = ftd_table[i];
+                       Apicall_Data *current = ftd_table[i];
 
                        while (current != NULL)
                        {
@@ -581,10 +661,10 @@ tracepath_api_trace_output(int force_output)
                                        double elapsed_time_period = _get_timeval_period(current->elapsed_time, current->last_elapsed_time);
                                        double elapsed_time_max = _get_timeval(current->elapsed_time_max);
                                        double elapsed_time_per_call_period = elapsed_time_period / (current->call_count - current->last_call_count);
-                                       char *fname = current->name;
+                                       char *fname = current->trace_data.name;
 
                                        if (!strncmp(fname, "tracepath_", 10))
-                                               fname = &current->name[10];
+                                               fname = &current->trace_data.name[10];
 
                                        if (elapsed_time_per_call_period >= 0.01 || current->call_count - current->last_call_count > 1000)
                                        {
@@ -593,7 +673,7 @@ tracepath_api_trace_output(int force_output)
                                                current->traced = 1;
                                        }
                                }
-                               current = current->next;
+                               current = (Apicall_Data *)current->trace_data.next;
                        }
                }
        }
@@ -608,7 +688,7 @@ tracepath_api_trace_output(int force_output)
                        {
                                if (ftd_table[i] != NULL)
                                {
-                                       Trace_Data *current = ftd_table[i];
+                                       Apicall_Data *current = ftd_table[i];
 
                                        while (current != NULL)
                                        {
@@ -617,15 +697,15 @@ tracepath_api_trace_output(int force_output)
                                                        double elapsed_time = _get_timeval(current->elapsed_time);
                                                        double elapsed_time_per_call = elapsed_time / current->call_count;
                                                        double elapsed_time_max = _get_timeval(current->elapsed_time_max);
-                                                       char *fname = current->name;
+                                                       char *fname = current->trace_data.name;
 
                                                        if (!strncmp(fname, "tracepath_", 10))
-                                                               fname = &current->name[10];
+                                                               fname = &current->trace_data.name[10];
 
                                                        TRACE(" %-39.39s : %10d call(s), %9.3f ms/API, %9.2f ms(MAX)\n",
                                                              fname, current->call_count, elapsed_time_per_call, elapsed_time_max);
                                                }
-                                               current = current->next;
+                                               current = (Apicall_Data *)current->trace_data.next;
                                        }
                                }
                        }
@@ -670,18 +750,98 @@ tracepath_api_trace_output(int force_output)
        {
                if (ftd_table[i] != NULL)
                {
-                       Trace_Data *current = ftd_table[i];
+                       Apicall_Data *current = ftd_table[i];
 
                        while (current != NULL)
                        {
                                current->last_call_count = current->call_count;
                                current->last_elapsed_time = current->elapsed_time;
                                current->last_total_elapsed_time = current->total_elapsed_time;
-                               current = current->next;
+                               current = (Apicall_Data *)current->trace_data.next;
+                       }
+               }
+       }
+
+       TRACE_END();
+
+       goto finish;
+
+finish:
+       return;
+}
+
+void
+tracepath_mem_trace_output(int force_output)
+{
+       static struct timeval tv_last = TIMEVAL_INIT;
+
+       int i;
+
+       if (trace_mem_flag != 1)
+       {
+               goto finish;
+       }
+
+       if (!force_output)
+       {
+               struct timeval tv_now = TIMEVAL_INIT;
+               AST(gettimeofday(&tv_now, NULL) == 0);
+               if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
+               {
+                       goto finish;
+               }
+               tv_last = tv_now;
+       }
+
+       TRACE("\n");
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+       TRACE("\E[40;32;1m  Memory usage info \E[1;37;1m: <PID = %d>\E[0m\n", getpid());
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+
+       if (mtd_table != NULL)
+       {
+               for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++)
+               {
+                       if (mtd_table[i] != NULL)
+                       {
+                               Memuse_Data *current = mtd_table[i];
+
+                               while (current != NULL)
+                               {
+                                       int obj_count = current->alloc_count - current->remove_count;
+                                       if (obj_count > 0)
+                                       {
+                                               TRACE("\E[40;37;1m %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\E[0m\n",
+                                                     current->trace_data.name, current->memsize, obj_count, current->alloc_count, current->remove_count);
+                                       }
+                                       current = (Memuse_Data *)current->trace_data.next;
+                               }
+                       }
+               }
+
+               for (i = 0; i < MAX_TRACE_TABLE_SIZE; i++)
+               {
+                       if (mtd_table[i] != NULL)
+                       {
+                               Memuse_Data *current = mtd_table[i];
+
+                               while (current != NULL)
+                               {
+                                       int obj_count = current->alloc_count - current->remove_count;
+                                       if (obj_count == 0)
+                                       {
+                                               TRACE(" %-46.46s : %12d byte(s)(E), %9d object(s) [%9d+/%9d-]\n",
+                                                     current->trace_data.name, current->memsize, obj_count, current->alloc_count, current->remove_count);
+                                       }
+                                       current = (Memuse_Data *)current->trace_data.next;
+                               }
                        }
                }
        }
 
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+       TRACE("\n");
+
        TRACE_END();
 
        goto finish;
index 8d6dd2b..09bc995 100644 (file)
 # include "../../headers/sym.h"\r
 #undef _COREGL_SYMBOL\r
 \r
+#define MAX_TRACE_NAME_LENGTH  256
+#define MAX_TRACE_TABLE_SIZE   65536
+\r
 #define COREGL_TRACEPATH_TRACE_ALL\r
 
 #ifdef COREGL_TRACEPATH_TRACE_ALL\r
 #define COREGL_TRACEPATH_TRACE_CONTEXT_INFO   // Context state & thread state & Glue-context info\r
 #define COREGL_TRACEPATH_TRACE_STATE_INFO     // Glue-context state info\r
 #define COREGL_TRACEPATH_TRACE_APICALL_INFO   // API call frequency info\r
+#define COREGL_TRACEPATH_TRACE_MEMUSE_INFO   // Memory usage info\r
 #endif
 
 #ifdef COREGL_TRACEPATH_TRACE_APICALL_INFO\r
 # define _COREGL_TRACE_API_OUTPUT(force_output)
 #endif
 \r
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO\r
+# define _COREGL_TRACE_MEM_ADD(desc, alloc_size) \\r
+   tracepath_mem_trace_add(desc, alloc_size);\r
+# define _COREGL_TRACE_MEM_REMOVE(desc, alloc_size) \\r
+   tracepath_mem_trace_remove(desc, alloc_size);\r
+# define _COREGL_TRACE_MEM_OUTPUT(force_output) \\r
+   tracepath_mem_trace_output(force_output);\r
+#else
+# define _COREGL_TRACE_MEM_ADD(desc, alloc_size)\r
+# define _COREGL_TRACE_MEM_REMOVE(desc, alloc_size)\r
+# define _COREGL_TRACE_MEM_OUTPUT(force_output)\r
+#endif
+\r
 #define _COREGL_TRACEPATH_FUNC_BEGIN() \\r
        if (unlikely(trace_api_flag == 1)) \
                _COREGL_TRACE_API_BEGIN(__func__, NULL, 1);
        if (unlikely(trace_api_flag == 1)) \
                _COREGL_TRACE_API_END(__func__, NULL, 1);
 \r
+typedef struct _Trace_Data Trace_Data;
+typedef struct _Apicall_Data Apicall_Data;\r
+typedef struct _Memuse_Data Memuse_Data;\r
+\r
+#define MTD_GLBUF_HASH_ARRAY 10000\r
+\r
+typedef struct _Glbuf_Data Glbuf_Data;\r
+typedef struct _Sostate_Data\r
+{\r
+       int                         ref_count;\r
+\r
+       Glbuf_Data                 *glbuf_tex[MTD_GLBUF_HASH_ARRAY];\r
+       Glbuf_Data                 *glbuf_rb[MTD_GLBUF_HASH_ARRAY];\r
+} Sostate_Data;\r
+\r
+typedef struct _Ctx_Data\r
+{\r
+       GLDisplay                dpy;\r
+       GLContext                handle;\r
+       int                      ref_count;\r
+       int                      mc_count;\r
+       Sostate_Data            *sostate;\r
+\r
+       struct _Ctx_Data       *next;\r
+} Ctx_Data;\r
+\r
+extern Mutex               ctx_access_mutex;\r
+\r
+extern Mutex               access_mutex;\r
+extern Memuse_Data       **table;\r
+\r
 typedef struct _Tracepath_ThreadState\r
 {
-       Trace_Data             **ftd_table;
+       Apicall_Data            **ftd_table;\r
+       Ctx_Data                 *ctx;\r
+\r
+       GLSurface                *surf_draw;\r
+       GLSurface                *surf_read;\r
 } Tracepath_ThreadState;\r
 \r
 extern void                init_modules_tracepath();\r
@@ -72,5 +124,11 @@ extern void               *tracepath_api_trace_begin(const char *name, void *hin
 extern void               *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);\r
 extern void                tracepath_api_trace_output(int force_output);\r
 \r
+extern void                tracepath_mem_trace_add(const char *desc, int alloc_size);\r
+extern void                tracepath_mem_trace_remove(const char *desc, int alloc_size);\r
+extern void                tracepath_mem_trace_output(int force_output);\r
+\r
+extern void                tracepath_glbuf_clear(Glbuf_Data **glbuf);\r
+\r
 #endif // COREGL_TRACEPATH_H\r
 \r
index 2482d21..6bc4850 100644 (file)
@@ -1,5 +1,304 @@
 #include "coregl_tracepath.h"
 
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+Mutex ctx_access_mutex = MUTEX_INITIALIZER;
+Ctx_Data *ctx_data = NULL;
+
+static Sostate_Data *
+_get_sostate(GLContext ctx)
+{
+       Sostate_Data *ret = NULL;
+
+       Ctx_Data *current = ctx_data;
+       while (current != NULL)
+       {
+               if (current->handle == ctx)
+               {
+                       current->sostate->ref_count++;
+                       ret = current->sostate;
+                       break;
+               }
+               current = current->next;
+       }
+
+       return ret;
+}
+
+#ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
+
+static void
+_dump_context_info(const char *ment, int force_output)
+{
+       MY_MODULE_TSTATE *tstate = NULL;
+       static struct timeval tv_last = { 0, 0 };
+
+       if (trace_ctx_flag != 1) return;
+
+       AST(mutex_lock(&ctx_access_mutex) == 1);
+       AST(mutex_lock(&general_trace_lists_access_mutex) == 1);
+
+       if (!force_output && !trace_ctx_force_flag)
+       {
+               struct timeval tv_now = { 0, 0 };
+               AST(gettimeofday(&tv_now, NULL) == 0);
+               if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
+               {
+                       goto finish;
+               }
+               tv_last = tv_now;
+       }
+
+       GET_MY_TSTATE(tstate, get_current_thread_state());
+
+       TRACE("\n");
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+       TRACE("\E[40;32;1m  Context info \E[1;37;1m: <PID = %d> %s\E[0m\n", getpid(), ment);
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+
+
+       // Thread State List
+       {
+               General_Trace_List *current = NULL;
+               current = thread_trace_list;
+
+               while (current != NULL)
+               {
+                       GLThreadState *cur_tstate = (GLThreadState *)current->value;
+                       MY_MODULE_TSTATE *cur_tstate_tm = NULL;
+
+                       GET_MY_TSTATE(cur_tstate_tm, cur_tstate);
+                       AST(cur_tstate_tm != NULL);
+
+                       TRACE(" %c Thread  [%12d] : Surf <D=[%12p] R=[%12p]>",
+                             (tstate == cur_tstate_tm) ? '*' : ' ',
+                             cur_tstate->thread_id,
+                             cur_tstate_tm->surf_draw,
+                             cur_tstate_tm->surf_read);
+
+                       if (cur_tstate_tm->ctx != NULL)
+                       {
+                               TRACE(" EGLCTX=[%12p]\E[0m\n",
+                                     cur_tstate_tm->ctx->handle);
+                       }
+                       else
+                       {
+                               TRACE(" (NOT BINDED TO THREAD)\E[0m\n");
+                       }
+
+                       // Binded Context State List
+                       {
+                               Ctx_Data *current = NULL;
+                               current = ctx_data;
+
+                               while (current != NULL)
+                               {
+                                       if (cur_tstate_tm->ctx == current)
+                                       {
+                                               TRACE("   -> EGLCTX [%12p] : EGLDPY=[%12p] <MC count [%10d]> <Ref [%2d]>\E[0m\n",
+                                                     current->handle,
+                                                     current->dpy,
+                                                     current->mc_count,
+                                                     current->ref_count);
+                                       }
+
+                                       current = current->next;
+                               }
+
+                       }
+
+
+                       current = current->next;
+               }
+       }
+
+       TRACE("\E[40;33m........................................................................................................................\E[0m\n");
+
+       // Not-binded Context State List
+       {
+               Ctx_Data *current = NULL;
+               current = ctx_data;
+
+               while (current != NULL)
+               {
+                       int isbinded = 0;
+
+                       General_Trace_List *current_t = NULL;
+                       current_t = thread_trace_list;
+
+                       while (current_t != NULL)
+                       {
+                               GLThreadState *cur_tstate = (GLThreadState *)current_t->value;
+                               MY_MODULE_TSTATE *cur_tstate_tm = NULL;
+
+                               GET_MY_TSTATE(cur_tstate_tm, cur_tstate);
+                               AST(cur_tstate_tm != NULL);
+
+                               if (cur_tstate_tm->ctx == current)
+                               {
+                                       isbinded = 1;
+                                       break;
+                               }
+                               current_t = current_t->next;
+                       }
+
+                       if (isbinded == 0)
+                       {
+                               TRACE("   EGLCTX    [%12p] : EGLDPY=[%12p] <MC count [%10d]> <Ref [%2d]>\E[0m\n",
+                                     current->handle,
+                                     current->dpy,
+                                     current->mc_count,
+                                     current->ref_count);
+                       }
+
+                       current = current->next;
+               }
+
+       }
+
+       TRACE("\E[40;34m========================================================================================================================\E[0m\n");
+       TRACE("\n");
+
+       TRACE_END();
+
+       goto finish;
+
+finish:
+
+       AST(mutex_unlock(&general_trace_lists_access_mutex) == 1);
+       AST(mutex_unlock(&ctx_access_mutex) == 1);
+
+}
+
+#endif // COREGL_TRACEPATH_TRACE_CONTEXT_INFO
+
+
+void
+tracepath_add_context(GLContext ctx, GLDisplay dpy, GLContext share_ctx)
+{
+       Ctx_Data *current = NULL;
+       Ctx_Data *data = NULL;
+
+       AST(mutex_lock(&ctx_access_mutex) == 1);
+
+       current = ctx_data;
+
+       while (current != NULL)
+       {
+               if (current->handle == ctx)
+               {
+                       data = current;
+                       break;
+               }
+               current = current->next;
+       }
+
+       if (data == NULL)
+       {
+               data = (Ctx_Data *)calloc(1, sizeof(Ctx_Data));
+               data->ref_count = 1;
+               data->handle = ctx;
+               data->dpy = dpy;
+
+               data->sostate = _get_sostate(share_ctx);
+               if (data->sostate == NULL)
+               {
+                       data->sostate = (Sostate_Data *)calloc(1, sizeof(Sostate_Data));
+                       data->sostate->ref_count = 1;
+               }
+
+               if (ctx_data != NULL)
+                       data->next = ctx_data;
+
+               ctx_data = data;
+       }
+       goto finish;
+
+finish:
+       AST(mutex_unlock(&ctx_access_mutex) == 1);
+       return;
+}
+
+Ctx_Data *
+tracepath_get_context(GLContext ctx)
+{
+       Ctx_Data *current = NULL;
+       Ctx_Data *data = NULL;
+
+       AST(mutex_lock(&ctx_access_mutex) == 1);
+
+       current = ctx_data;
+
+       while (current != NULL)
+       {
+               if (current->handle == ctx)
+               {
+                       data = current;
+                       break;
+               }
+               current = current->next;
+       }
+       if (data == NULL)
+       {
+               ERR("WARNING : Error making context [%p] current. (invalid EGL context)\n", ctx);
+               goto finish;
+       }
+       data->ref_count++;
+       goto finish;
+
+finish:
+       AST(mutex_unlock(&ctx_access_mutex) == 1);
+       return data;
+}
+
+void
+tracepath_remove_context(GLContext ctx)
+{
+       Ctx_Data *current = NULL;
+       Ctx_Data *prev = NULL;
+
+       AST(mutex_lock(&ctx_access_mutex) == 1);
+
+       current = ctx_data;
+
+       while (current != NULL)
+       {
+               if (current->handle == ctx)
+               {
+                       if (--current->ref_count <= 0)
+                       {
+                               if (prev != NULL)
+                                       prev->next = current->next;
+                               else
+                                       ctx_data = current->next;
+
+                               if (--current->sostate->ref_count <= 0)
+                               {
+                                       tracepath_glbuf_clear(current->sostate->glbuf_rb);
+                                       tracepath_glbuf_clear(current->sostate->glbuf_tex);
+                                       free(current->sostate);
+                                       current->sostate = NULL;
+                               }
+
+                               free(current);
+                               current = NULL;
+                       }
+                       break;
+               }
+               prev = current;
+               current = current->next;
+       }
+       goto finish;
+
+finish:
+       AST(mutex_unlock(&ctx_access_mutex) == 1);
+       return;
+}
+
 EGLint
 tracepath_eglGetError(void)
 {
@@ -305,6 +604,23 @@ tracepath_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_co
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+       {
+               if (ret != EGL_NO_CONTEXT)
+               {
+                       tracepath_add_context(ret, dpy, share_context);
+               }
+       }
+#ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
+       if (unlikely(trace_ctx_flag == 1))
+       {
+               if (_orig_tracepath_eglCreateContext == _sym_eglCreateContext)
+               {
+                       char ment[256];
+                       sprintf(ment, "eglCreateContext completed (EGLCTX=[%12p])", ret);
+                       _dump_context_info(ment, 1);
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_CONTEXT_INFO
        return ret;
 }
 
@@ -319,6 +635,22 @@ tracepath_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+       {
+               AST(ctx != EGL_NO_CONTEXT);
+
+               tracepath_remove_context(ctx);
+       }
+#ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
+       if (unlikely(trace_ctx_flag == 1))
+       {
+               if (_orig_tracepath_eglDestroyContext == _sym_eglDestroyContext)
+               {
+                       char ment[256];
+                       sprintf(ment, "eglDestroyContext completed (EGLCTX=[%12p])", ctx);
+                       _dump_context_info(ment, 1);
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_CONTEXT_INFO
        return ret;
 }
 
@@ -333,6 +665,37 @@ tracepath_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLCo
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               if (tstate == NULL)
+               {
+                       init_new_thread_state();
+
+                       GET_MY_TSTATE(tstate, get_current_thread_state());
+                       AST(tstate != NULL);
+               }
+
+               Ctx_Data *oldctx = tstate->ctx;
+
+               if (ctx != EGL_NO_CONTEXT)
+               {
+                       tstate->ctx = tracepath_get_context(ctx);
+                       if (tstate->ctx != NULL)
+                               tstate->ctx->mc_count++;
+               }
+               else
+               {
+                       tstate->ctx = NULL;
+               }
+
+               if (oldctx != NULL)
+                       tracepath_remove_context(oldctx->handle);
+
+               tstate->surf_draw = draw;
+               tstate->surf_read = read;
+       }
 #ifdef COREGL_TRACEPATH_TRACE_STATE_INFO
        if (unlikely(trace_state_flag == 1))
        {
@@ -340,6 +703,17 @@ finish:
                        tracepath_dump_context_states(0);
        }
 #endif // COREGL_TRACEPATH_TRACE_STATE_INFO
+#ifdef COREGL_TRACEPATH_TRACE_CONTEXT_INFO
+       if (unlikely(trace_ctx_flag == 1))
+       {
+               if (_orig_tracepath_eglMakeCurrent == _sym_eglMakeCurrent)
+               {
+                       char ment[256];
+                       sprintf(ment, "eglMakeCurrent finished (EGLCTX=[%12p] Surf=[D:%12p R:%12p])", ctx, draw, read);
+                       _dump_context_info(ment, 0);
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_CONTEXT_INFO
        return ret;
 }
 
@@ -440,6 +814,7 @@ tracepath_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 finish:
        _COREGL_TRACEPATH_FUNC_END();
        _COREGL_TRACE_API_OUTPUT(0);
+       _COREGL_TRACE_MEM_OUTPUT(0);
        return ret;
 }
 
index 2d6517e..bafb61b 100644 (file)
@@ -1,5 +1,158 @@
 #include "coregl_tracepath.h"
 
+#include <stdlib.h>
+
+struct _Glbuf_Data
+{
+       int obj_idx;
+       int width;
+       int height;
+       int bpp;
+       char format[80];
+
+       struct _Glbuf_Data *next;
+};
+
+static void
+__addhash_glbuf_object(Glbuf_Data **glbuf, Glbuf_Data *target)
+{
+       Glbuf_Data *data = glbuf[target->obj_idx % MTD_GLBUF_HASH_ARRAY];
+       if (data == NULL)
+       {
+               glbuf[target->obj_idx % MTD_GLBUF_HASH_ARRAY] = target;
+       }
+       else
+       {
+               while (data->next != NULL)
+               {
+                       AST(data->obj_idx != target->obj_idx);
+                       data = data->next;
+               }
+               AST(data->obj_idx != target->obj_idx);
+               data->next = target;
+       }
+       goto finish;
+
+finish:
+       return;
+}
+
+static void
+__removehash_glbuf_object(Glbuf_Data **glbuf, Glbuf_Data **target)
+{
+       Glbuf_Data *data = glbuf[(*target)->obj_idx % MTD_GLBUF_HASH_ARRAY];
+       Glbuf_Data *prev = NULL;
+       while (data != NULL)
+       {
+               if (data->obj_idx == (*target)->obj_idx)
+               {
+                       if (prev != NULL)
+                               prev->next = data->next;
+                       else
+                               glbuf[(*target)->obj_idx % MTD_GLBUF_HASH_ARRAY] = data->next;
+
+                       free(*target);
+                       *target = NULL;
+                       break;
+               }
+               data = data->next;
+       }
+       goto finish;
+
+finish:
+       return;
+}
+
+static Glbuf_Data *
+__findhash_glbuf_object(Glbuf_Data **glbuf, int obj_idx)
+{
+       Glbuf_Data *data = glbuf[obj_idx % MTD_GLBUF_HASH_ARRAY];
+       while (data != NULL)
+       {
+               if (data->obj_idx == obj_idx)
+                       break;
+               data = data->next;
+       }
+       goto finish;
+
+finish:
+       return data;
+}
+
+void
+tracepath_glbuf_clear(Glbuf_Data **glbuf)
+{
+       int i;
+
+       for (i = 0; i < MTD_GLBUF_HASH_ARRAY; i++)
+       {
+               Glbuf_Data *data = glbuf[i];
+
+               while (data)
+               {
+                       Glbuf_Data *delitm = data;
+                       data = data->next;
+                       free(delitm);
+                       delitm = NULL;
+               }
+       }
+}
+
+static void
+_add_glbuf_object(Glbuf_Data **glbuf, int obj_idx, const char *obj_type, int width, int height, int bpp, const char *format)
+{
+       Glbuf_Data *data = __findhash_glbuf_object(glbuf, obj_idx);
+       if (data == NULL)
+       {
+               data = (Glbuf_Data *)calloc(1, sizeof(Glbuf_Data));
+               data->obj_idx = obj_idx;
+               __addhash_glbuf_object(glbuf, data);
+       }
+       else
+       {
+               // Update
+               {
+                       char ment[MAX_TRACE_NAME_LENGTH];
+                       sprintf(ment, "%s(%4dx%4d %s)", obj_type, data->width, data->height, data->format);
+                       _COREGL_TRACE_MEM_REMOVE(ment, data->width * data->height * data->bpp);
+               }
+       }
+
+       data->width = width;
+       data->height = height;
+       data->bpp = bpp;
+       sprintf(data->format, "%s", format);
+
+       {
+               char ment[MAX_TRACE_NAME_LENGTH];
+               sprintf(ment, "%s(%4dx%4d %s)", obj_type, data->width, data->height, data->format);
+               _COREGL_TRACE_MEM_ADD(ment, data->width * data->height * data->bpp);
+       }
+       goto finish;
+
+finish:
+       return;
+}
+
+static void
+_remove_glbuf_object(Glbuf_Data **glbuf, int obj_idx, const char *obj_type)
+{
+       Glbuf_Data *data = __findhash_glbuf_object(glbuf, obj_idx);
+       AST(data != NULL);
+
+       {
+               char ment[MAX_TRACE_NAME_LENGTH];
+               sprintf(ment, "%s(%4dx%4d %s)", obj_type, data->width, data->height, data->format);
+               _COREGL_TRACE_MEM_REMOVE(ment, data->width * data->height * data->bpp);
+       }
+
+       __removehash_glbuf_object(glbuf, &data);
+       goto finish;
+
+finish:
+       return;
+}
+
 void
 tracepath_glActiveTexture(GLenum texture)
 {
@@ -391,6 +544,22 @@ tracepath_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               for (int i = 0; i < n; i++)
+               {
+                       if (renderbuffers[i] == 0) continue;
+                       _remove_glbuf_object(tstate->ctx->sostate->glbuf_rb, renderbuffers[i], "Renderbuffer");
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -415,6 +584,22 @@ tracepath_glDeleteTextures(GLsizei n, const GLuint* textures)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               for (int i = 0; i < n; i++)
+               {
+                       if (textures[i] == 0) continue;
+                       _remove_glbuf_object(tstate->ctx->sostate->glbuf_tex, textures[i], "Texture");
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -548,6 +733,7 @@ tracepath_glFinish(void)
 finish:
        _COREGL_TRACEPATH_FUNC_END();
        _COREGL_TRACE_API_OUTPUT(0);
+       _COREGL_TRACE_MEM_OUTPUT(0);
 }
 
 void
@@ -561,6 +747,7 @@ tracepath_glFlush(void)
 finish:
        _COREGL_TRACEPATH_FUNC_END();
        _COREGL_TRACE_API_OUTPUT(0);
+       _COREGL_TRACE_MEM_OUTPUT(0);
 }
 
 void
@@ -697,6 +884,22 @@ tracepath_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               for (int i = 0; i < n; i++)
+               {
+                       if (renderbuffers[i] == 0) continue;
+                       _add_glbuf_object(tstate->ctx->sostate->glbuf_rb, renderbuffers[i], "Renderbuffer", 0, 0, 0, "Unknown");
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -709,6 +912,22 @@ tracepath_glGenTextures(GLsizei n, GLuint* textures)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               for (int i = 0; i < n; i++)
+               {
+                       if (textures[i] == 0) continue;
+                       _add_glbuf_object(tstate->ctx->sostate->glbuf_tex, textures[i], "Texture", 0, 0, 0, "Unknown");
+               }
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -1179,6 +1398,44 @@ tracepath_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei wi
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               int objidx = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_RENDERBUFFER_BINDING, &objidx);
+               AST(objidx != _COREGL_INT_INIT_VALUE);
+
+               // Detect byte per pixel
+               int bpp = 0;
+               char formatment[80];
+               switch (internalformat)
+               {
+                       case GL_ALPHA: sprintf(formatment, "ALPHA"); bpp = 1; break;
+                       case GL_LUMINANCE: sprintf(formatment, "LUMINANCE"); bpp = 1; break;
+                       case GL_LUMINANCE_ALPHA: sprintf(formatment, "LUMINANCE_ALPHA"); bpp = 1; break;
+                       case GL_RGB: sprintf(formatment, "RGB"); bpp = 2; break;
+                       case GL_RGBA: sprintf(formatment, "RGBA"); bpp = 4; break;
+                       case 0x80E1: sprintf(formatment, "BGRA_EXT"); bpp = 4; break;
+                       case 0x84F9: sprintf(formatment, "DEPTH_STENCIL_OES"); bpp = 4; break;
+                       case GL_DEPTH_COMPONENT : sprintf(formatment, "DEPTH_COMPONENT"); bpp = 1; break;
+                       case 0x81A5: sprintf(formatment, "DEPTH_COMPONENT16_ARB"); bpp = 2; break;
+                       case 0x81A6: sprintf(formatment, "DEPTH_COMPONENT24_ARB"); bpp = 3; break;
+                       case 0x81A7: sprintf(formatment, "DEPTH_COMPONENT32_ARB"); bpp = 4; break;
+                       case 0x8D46 : sprintf(formatment, "STENCIL_INDEX1_OES"); bpp = 1; break;
+                       case 0x8D47 : sprintf(formatment, "STENCIL_INDEX4_OES"); bpp = 1; break;
+                       case 0x8D48 : sprintf(formatment, "STENCIL_INDEX8_OES"); bpp = 1; break;
+                       default: sprintf(formatment, "0x%X", internalformat); bpp = 0; break;
+               }
+
+               _add_glbuf_object(tstate->ctx->sostate->glbuf_rb, objidx, "Renderbuffer", width, height, bpp, formatment);
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -1311,6 +1568,44 @@ tracepath_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               int objidx = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_TEXTURE_BINDING_2D, &objidx);
+               AST(objidx != _COREGL_INT_INIT_VALUE);
+
+               // Detect byte per pixel
+               int bpp = 0;
+               char formatment[80];
+               switch (internalformat)
+               {
+                       case GL_ALPHA: sprintf(formatment, "ALPHA"); bpp = 1; break;
+                       case GL_LUMINANCE: sprintf(formatment, "LUMINANCE"); bpp = 1; break;
+                       case GL_LUMINANCE_ALPHA: sprintf(formatment, "LUMINANCE_ALPHA"); bpp = 1; break;
+                       case GL_RGB: sprintf(formatment, "RGB"); bpp = 2; break;
+                       case GL_RGBA: sprintf(formatment, "RGBA"); bpp = 4; break;
+                       case 0x80E1: sprintf(formatment, "BGRA_EXT"); bpp = 4; break;
+                       case 0x84F9: sprintf(formatment, "DEPTH_STENCIL_OES"); bpp = 4; break;
+                       case GL_DEPTH_COMPONENT : sprintf(formatment, "DEPTH_COMPONENT"); bpp = 1; break;
+                       case 0x81A5: sprintf(formatment, "DEPTH_COMPONENT16_ARB"); bpp = 2; break;
+                       case 0x81A6: sprintf(formatment, "DEPTH_COMPONENT24_ARB"); bpp = 3; break;
+                       case 0x81A7: sprintf(formatment, "DEPTH_COMPONENT32_ARB"); bpp = 4; break;
+                       case 0x8D46 : sprintf(formatment, "STENCIL_INDEX1_OES"); bpp = 1; break;
+                       case 0x8D47 : sprintf(formatment, "STENCIL_INDEX4_OES"); bpp = 1; break;
+                       case 0x8D48 : sprintf(formatment, "STENCIL_INDEX8_OES"); bpp = 1; break;
+                       default: sprintf(formatment, "0x%X", internalformat); bpp = 0; break;
+               }
+
+               _add_glbuf_object(tstate->ctx->sostate->glbuf_tex, objidx, "Texture", width, height, bpp, formatment);
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -1756,6 +2051,22 @@ tracepath_glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               int objidx = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_TEXTURE_BINDING_2D, &objidx);
+               AST(objidx != _COREGL_INT_INIT_VALUE);
+
+               _add_glbuf_object(tstate->ctx->sostate->glbuf_tex, objidx, "Texture", 0, 0, 0, "Unknown");
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -1767,6 +2078,22 @@ tracepath_glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES im
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               int objidx = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_RENDERBUFFER_BINDING, &objidx);
+               AST(objidx != _COREGL_INT_INIT_VALUE);
+
+               _add_glbuf_object(tstate->ctx->sostate->glbuf_rb, objidx, "Renderbuffer", 0, 0, 0, "Unknown");
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void
@@ -1816,6 +2143,44 @@ tracepath_glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GL
 
 finish:
        _COREGL_TRACEPATH_FUNC_END();
+#ifdef COREGL_TRACEPATH_TRACE_MEMUSE_INFO
+       if (trace_mem_flag == 1)
+       {
+               MY_MODULE_TSTATE *tstate = NULL;
+
+               GET_MY_TSTATE(tstate, get_current_thread_state());
+               AST(tstate != NULL);
+               AST(tstate->ctx != NULL);
+
+               int objidx = _COREGL_INT_INIT_VALUE;
+               _orig_tracepath_glGetIntegerv(GL_RENDERBUFFER_BINDING, &objidx);
+               AST(objidx != _COREGL_INT_INIT_VALUE);
+
+               // Detect byte per pixel
+               int bpp = 0;
+               char formatment[80];
+               switch (internalformat)
+               {
+                       case GL_ALPHA: sprintf(formatment, "ALPHA"); bpp = 1; break;
+                       case GL_LUMINANCE: sprintf(formatment, "LUMINANCE"); bpp = 1; break;
+                       case GL_LUMINANCE_ALPHA: sprintf(formatment, "LUMINANCE_ALPHA"); bpp = 1; break;
+                       case GL_RGB: sprintf(formatment, "RGB"); bpp = 2; break;
+                       case GL_RGBA: sprintf(formatment, "RGBA"); bpp = 4; break;
+                       case 0x80E1: sprintf(formatment, "BGRA_EXT"); bpp = 4; break;
+                       case 0x84F9: sprintf(formatment, "DEPTH_STENCIL_OES"); bpp = 4; break;
+                       case GL_DEPTH_COMPONENT : sprintf(formatment, "DEPTH_COMPONENT"); bpp = 1; break;
+                       case 0x81A5: sprintf(formatment, "DEPTH_COMPONENT16_ARB"); bpp = 2; break;
+                       case 0x81A6: sprintf(formatment, "DEPTH_COMPONENT24_ARB"); bpp = 3; break;
+                       case 0x81A7: sprintf(formatment, "DEPTH_COMPONENT32_ARB"); bpp = 4; break;
+                       case 0x8D46 : sprintf(formatment, "STENCIL_INDEX1_OES"); bpp = 1; break;
+                       case 0x8D47 : sprintf(formatment, "STENCIL_INDEX4_OES"); bpp = 1; break;
+                       case 0x8D48 : sprintf(formatment, "STENCIL_INDEX8_OES"); bpp = 1; break;
+                       default: sprintf(formatment, "0x%X", internalformat); bpp = 0; break;
+               }
+
+               _add_glbuf_object(tstate->ctx->sostate->glbuf_rb, objidx, "Renderbuffer", width, height, bpp, formatment);
+       }
+#endif // COREGL_TRACEPATH_TRACE_MEMUSE_INFO
 }
 
 void