1 #include "coregl_fastpath.h"
10 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) RET_TYPE (*_orig_fastpath_##FUNC_NAME) PARAM_LIST = NULL;
11 #include "../../headers/sym.h"
14 Fastpath_Opt_Flag fp_opt = FP_UNKNOWN_PATH;
17 FILE *trace_fp = NULL;
19 GLenum FPGL_Error = GL_NO_ERROR;
21 GLGlueContext_List *gctx_list = NULL;
23 Mutex init_context_mutex = MUTEX_INITIALIZER;
24 GLGlueContext *initial_ctx = NULL;
26 Mutex ctx_list_access_mutex = MUTEX_INITIALIZER;
28 GLContext_List *glctx_list = NULL;
31 _get_texture_states(GLenum pname, GLint *params)
33 GLuint cur_active_tex = 0;
35 AST(initial_ctx != NULL);
37 _orig_fastpath_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
39 for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++)
41 _orig_fastpath_glActiveTexture(GL_TEXTURE0 + i);
42 _orig_fastpath_glGetIntegerv(pname, &(((GLint *)params)[i]));
44 _orig_fastpath_glActiveTexture(cur_active_tex);
48 _get_stencil_max_mask()
50 GLuint stencil_bit = 0;
52 _orig_fastpath_glGetIntegerv(GL_STENCIL_BITS, (GLint *)&stencil_bit);
53 return (1 << stencil_bit) - 1;
57 init_modules_fastpath()
60 int fastpath_force_off_opt = 0;
62 LOG("[CoreGL] <Fastpath> : ");
64 fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
65 fastpath_force_off_opt = atoi(get_env_setting("COREGL_FASTPATH_FORCE_OFF"));
67 if (fastpath_force_off_opt == 1)
69 LOG("\E[0;31;1m(DISABLED by force option)\E[0m ");
76 LOG("(%d) Fastpath enabled...\n", fastpath_opt);
77 fp_opt = FP_FAST_PATH;
80 LOG("(%d) Default API path enabled...\n", fastpath_opt);
81 fp_opt = FP_NORMAL_PATH;
85 debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
90 deinit_modules_fastpath()
92 GLContext_List *current = NULL;
94 AST(mutex_lock(&ctx_list_access_mutex) == 1);
96 // Destroy remained context & Detect leaks
97 int retry_destroy = 0;
102 current = glctx_list;
105 if (current->cstate != NULL)
107 ERR("\E[0;31;1mWARNING : Context attached to [dpy=%p|rctx=%p] has not been completely destroyed.(leak)\E[0m\n", current->cstate->rdpy, current->cstate->rctx);
109 _orig_fastpath_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
110 _orig_fastpath_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
112 fastpath_remove_context_states_from_list(current->cstate, NULL);
117 glctx_list = current->next;
119 current = glctx_list;
121 if (retry_destroy == 0) break;
126 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
130 init_modules_tstate_fastpath(GLThreadState *tstate)
132 MY_MODULE_TSTATE *tstate_mt = NULL;
134 tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
136 tstate_mt->binded_api = EGL_OPENGL_ES_API;
138 tstate->module_data[MY_MODULE_ID] = tstate_mt;
142 deinit_modules_tstate_fastpath(GLThreadState *tstate)
144 if (tstate->module_data[MY_MODULE_ID] != NULL)
146 free(tstate->module_data[MY_MODULE_ID]);
147 tstate->module_data[MY_MODULE_ID] = NULL;
152 fastpath_apply_overrides()
157 fastpath_apply_overrides_egl(1);
158 fastpath_apply_overrides_gl(1);
163 ERR("Invalide GL Override Option!!!\n");
170 fastpath_apply_overrides_egl(int enable)
172 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
173 # include "../../headers/sym_egl.h"
174 #undef _COREGL_SYMBOL
176 COREGL_OVERRIDE(fastpath_, eglGetProcAddress);
178 COREGL_OVERRIDE(fastpath_, eglBindAPI);
179 COREGL_OVERRIDE(fastpath_, eglQueryAPI);
181 COREGL_OVERRIDE(fastpath_, eglCreateContext);
182 COREGL_OVERRIDE(fastpath_, eglCreateImageKHR);
183 COREGL_OVERRIDE(fastpath_, eglMakeCurrent);
184 COREGL_OVERRIDE(fastpath_, eglDestroyContext);
185 COREGL_OVERRIDE(fastpath_, eglQueryContext);
186 COREGL_OVERRIDE(fastpath_, eglGetCurrentContext);
187 COREGL_OVERRIDE(fastpath_, eglReleaseThread);
188 COREGL_OVERRIDE(fastpath_, eglGetCurrentSurface);
189 COREGL_OVERRIDE(fastpath_, eglTerminate);
194 fastpath_apply_overrides_gl(int enable)
196 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
197 # include "../../headers/sym_gl.h"
198 #undef _COREGL_SYMBOL
202 COREGL_OVERRIDE(fastpath_, glGetError);
204 COREGL_OVERRIDE(fastpath_, glGetIntegerv);
205 COREGL_OVERRIDE(fastpath_, glGetFloatv);
206 COREGL_OVERRIDE(fastpath_, glGetBooleanv);
208 COREGL_OVERRIDE(fastpath_, glActiveTexture);
209 COREGL_OVERRIDE(fastpath_, glGenTextures);
210 COREGL_OVERRIDE(fastpath_, glBindTexture);
211 COREGL_OVERRIDE(fastpath_, glIsTexture);
212 COREGL_OVERRIDE(fastpath_, glDeleteTextures);
213 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2D);
214 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2DMultisampleEXT);
216 COREGL_OVERRIDE(fastpath_, glGenBuffers);
217 COREGL_OVERRIDE(fastpath_, glBindBuffer);
218 COREGL_OVERRIDE(fastpath_, glIsBuffer);
219 COREGL_OVERRIDE(fastpath_, glDeleteBuffers);
221 COREGL_OVERRIDE(fastpath_, glGenFramebuffers);
222 COREGL_OVERRIDE(fastpath_, glBindFramebuffer);
223 COREGL_OVERRIDE(fastpath_, glIsFramebuffer);
224 COREGL_OVERRIDE(fastpath_, glDeleteFramebuffers);
226 COREGL_OVERRIDE(fastpath_, glGenRenderbuffers);
227 COREGL_OVERRIDE(fastpath_, glBindRenderbuffer);
228 COREGL_OVERRIDE(fastpath_, glFramebufferRenderbuffer);
229 COREGL_OVERRIDE(fastpath_, glIsRenderbuffer);
230 COREGL_OVERRIDE(fastpath_, glDeleteRenderbuffers);
232 COREGL_OVERRIDE(fastpath_, glCreateShader);
233 COREGL_OVERRIDE(fastpath_, glCreateProgram);
234 COREGL_OVERRIDE(fastpath_, glAttachShader);
235 COREGL_OVERRIDE(fastpath_, glCompileShader);
236 COREGL_OVERRIDE(fastpath_, glShaderBinary);
237 COREGL_OVERRIDE(fastpath_, glDeleteShader);
238 COREGL_OVERRIDE(fastpath_, glDetachShader);
239 COREGL_OVERRIDE(fastpath_, glGetShaderiv);
240 COREGL_OVERRIDE(fastpath_, glGetShaderInfoLog);
241 COREGL_OVERRIDE(fastpath_, glGetShaderSource);
242 COREGL_OVERRIDE(fastpath_, glIsShader);
243 COREGL_OVERRIDE(fastpath_, glShaderSource);
244 COREGL_OVERRIDE(fastpath_, glBindAttribLocation);
245 COREGL_OVERRIDE(fastpath_, glDeleteProgram);
246 COREGL_OVERRIDE(fastpath_, glGetActiveAttrib);
247 COREGL_OVERRIDE(fastpath_, glGetActiveUniform);
248 COREGL_OVERRIDE(fastpath_, glGetAttachedShaders);
249 COREGL_OVERRIDE(fastpath_, glGetAttribLocation);
250 COREGL_OVERRIDE(fastpath_, glGetProgramiv);
251 COREGL_OVERRIDE(fastpath_, glGetProgramInfoLog);
252 COREGL_OVERRIDE(fastpath_, glGetUniformfv);
253 COREGL_OVERRIDE(fastpath_, glGetUniformiv);
254 COREGL_OVERRIDE(fastpath_, glGetUniformLocation);
255 COREGL_OVERRIDE(fastpath_, glIsProgram);
256 COREGL_OVERRIDE(fastpath_, glLinkProgram);
257 COREGL_OVERRIDE(fastpath_, glUseProgram);
258 COREGL_OVERRIDE(fastpath_, glValidateProgram);
259 COREGL_OVERRIDE(fastpath_, glGetProgramBinary);
260 COREGL_OVERRIDE(fastpath_, glProgramBinary);
262 COREGL_OVERRIDE(fastpath_, glBlendColor);
263 COREGL_OVERRIDE(fastpath_, glBlendEquation);
264 COREGL_OVERRIDE(fastpath_, glBlendEquationSeparate);
265 COREGL_OVERRIDE(fastpath_, glBlendFunc);
266 COREGL_OVERRIDE(fastpath_, glBlendFuncSeparate);
267 COREGL_OVERRIDE(fastpath_, glClearColor);
268 COREGL_OVERRIDE(fastpath_, glClearDepthf);
269 COREGL_OVERRIDE(fastpath_, glClearStencil);
270 COREGL_OVERRIDE(fastpath_, glColorMask);
271 COREGL_OVERRIDE(fastpath_, glCullFace);
272 COREGL_OVERRIDE(fastpath_, glDepthFunc);
273 COREGL_OVERRIDE(fastpath_, glDepthMask);
274 COREGL_OVERRIDE(fastpath_, glDepthRangef);
275 COREGL_OVERRIDE(fastpath_, glDisable);
276 COREGL_OVERRIDE(fastpath_, glDisableVertexAttribArray);
277 COREGL_OVERRIDE(fastpath_, glEnable);
278 COREGL_OVERRIDE(fastpath_, glEnableVertexAttribArray);
279 COREGL_OVERRIDE(fastpath_, glFrontFace);
280 COREGL_OVERRIDE(fastpath_, glHint);
281 COREGL_OVERRIDE(fastpath_, glLineWidth);
282 COREGL_OVERRIDE(fastpath_, glPixelStorei);
283 COREGL_OVERRIDE(fastpath_, glPolygonOffset);
284 COREGL_OVERRIDE(fastpath_, glSampleCoverage);
285 COREGL_OVERRIDE(fastpath_, glScissor);
286 COREGL_OVERRIDE(fastpath_, glStencilFunc);
287 COREGL_OVERRIDE(fastpath_, glStencilFuncSeparate);
288 COREGL_OVERRIDE(fastpath_, glStencilMask);
289 COREGL_OVERRIDE(fastpath_, glStencilMaskSeparate);
290 COREGL_OVERRIDE(fastpath_, glStencilOp);
291 COREGL_OVERRIDE(fastpath_, glStencilOpSeparate);
292 COREGL_OVERRIDE(fastpath_, glVertexAttrib1f);
293 COREGL_OVERRIDE(fastpath_, glVertexAttrib1fv);
294 COREGL_OVERRIDE(fastpath_, glVertexAttrib2f);
295 COREGL_OVERRIDE(fastpath_, glVertexAttrib2fv);
296 COREGL_OVERRIDE(fastpath_, glVertexAttrib3f);
297 COREGL_OVERRIDE(fastpath_, glVertexAttrib3fv);
298 COREGL_OVERRIDE(fastpath_, glVertexAttrib4f);
299 COREGL_OVERRIDE(fastpath_, glVertexAttrib4fv);
300 COREGL_OVERRIDE(fastpath_, glVertexAttribPointer);
301 COREGL_OVERRIDE(fastpath_, glViewport);
303 COREGL_OVERRIDE(fastpath_, glEGLImageTargetTexture2DOES);
308 LOG("\E[0;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
315 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
319 case GL_OBJECT_TYPE_TEXTURE:
320 return sostate->texture;
321 case GL_OBJECT_TYPE_BUFFER:
322 return sostate->buffer;
323 case GL_OBJECT_TYPE_FRAMEBUFFER:
324 return sostate->framebuffer;
325 case GL_OBJECT_TYPE_RENDERBUFFER:
326 return sostate->renderbuffer;
327 case GL_OBJECT_TYPE_PROGRAM:
328 return sostate->program;
335 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
339 GLContext_List *current = NULL;
340 GLContext_List *newitm = NULL;
342 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
346 tid = get_current_thread();
348 current = glctx_list;
349 while (current != NULL)
351 if (current->option_len == option_len &&
352 memcmp(current->option, option, option_len) == 0 &&
353 current->thread_id == tid)
355 AST(current->cstate == cstate);
358 current = current->next;
361 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
364 ERR("Failed to create context list.\n");
368 newitm->cstate = cstate;
369 newitm->thread_id = tid;
370 newitm->option_len = option_len;
371 newitm->option = (void *)malloc(option_len);
372 memcpy(newitm->option, option, option_len);
374 if (glctx_list != NULL)
375 newitm->next = glctx_list;
396 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
402 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
404 GLContextState *ret = NULL;
405 GLContext_List *current = NULL;
408 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
410 tid = get_current_thread();
412 current = glctx_list;
413 while (current != NULL)
415 if (current->option_len == option_len &&
416 memcmp(current->option, option, option_len) == 0 &&
417 current->thread_id == tid)
419 ret = current->cstate;
422 current = current->next;
427 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
432 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
436 GLContext_List *olditm = NULL;
437 GLContext_List *current = NULL;
439 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
443 tid = get_current_thread();
444 current = glctx_list;
446 while (current != NULL)
448 if (current->cstate == cstate)
450 GLContext_List *nextitm = NULL;
453 olditm->next = current->next;
454 nextitm = olditm->next;
458 glctx_list = current->next;
459 nextitm = glctx_list;
467 current = current->next;
472 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
477 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
479 GL_Object **object = NULL;
480 GLuint ret = _COREGL_INT_INIT_VALUE;
483 object = _get_shared_object(sostate, type);
485 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
487 if (object[i] == NULL)
489 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
490 newobj->id = (int)type + i;
491 newobj->real_id = real_name;
492 newobj->ref_count = 1;
505 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
507 GL_Object **object = NULL;
508 GLuint ret = _COREGL_INT_INIT_VALUE;
509 int hash = _COREGL_INT_INIT_VALUE;
511 object = _get_shared_object(sostate, type);
513 hash = glue_name - (int)type;
515 hash > MAX_GL_OBJECT_SIZE ||
516 object[hash] == NULL ||
517 object[hash]->id != glue_name)
523 object[hash]->ref_count--;
525 if (object[hash]->ref_count <= 0)
539 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
541 GL_Object **object = NULL;
542 GLuint ret = _COREGL_INT_INIT_VALUE;
543 int hash = _COREGL_INT_INIT_VALUE;
545 object = _get_shared_object(sostate, type);
547 hash = glue_name - (int)type;
549 hash > MAX_GL_OBJECT_SIZE ||
550 object[hash] == NULL ||
551 object[hash]->id != glue_name)
556 ret = object[hash]->real_id;
564 fastpath_sostate_set_object_tag(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name, GLvoid *tag)
566 GL_Object **object = NULL;
567 GLint ret = _COREGL_INT_INIT_VALUE;
568 int hash = _COREGL_INT_INIT_VALUE;
570 object = _get_shared_object(sostate, type);
572 hash = glue_name - (int)type;
574 hash > MAX_GL_OBJECT_SIZE ||
575 object[hash] == NULL ||
576 object[hash]->id != glue_name)
581 object[hash]->tag = tag;
590 fastpath_sostate_get_object_tag(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
592 GL_Object **object = NULL;
594 int hash = _COREGL_INT_INIT_VALUE;
596 object = _get_shared_object(sostate, type);
598 hash = glue_name - (int)type;
600 hash > MAX_GL_OBJECT_SIZE ||
601 object[hash] == NULL ||
602 object[hash]->id != glue_name)
607 ret = object[hash]->tag;
615 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
617 GL_Object **object = NULL;
618 GLuint ret = _COREGL_INT_INIT_VALUE;
621 object = _get_shared_object(sostate, type);
623 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
625 if (object[i] != NULL && object[i]->real_id == real_name)
639 fastpath_sostate_use_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
641 GL_Object **object = NULL;
643 int hash = _COREGL_INT_INIT_VALUE;
645 object = _get_shared_object(sostate, type);
647 hash = glue_name - (int)type;
649 hash > MAX_GL_OBJECT_SIZE ||
650 object[hash] == NULL ||
651 object[hash]->id != glue_name)
656 object[hash]->ref_count++;
665 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
667 static struct timeval tv_last = { 0, 0 };
669 if (unlikely(trace_state_flag != 1)) return;
673 struct timeval tv_now = { 0, 0 };
674 AST(gettimeofday(&tv_now, NULL) == 0);
675 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
683 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
684 TRACE("\E[0;32;1m State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
685 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
687 #define PRINTF_CHAR_GLenum "%10d"
688 #define PRINTF_CHAR_GLboolean "%10d"
689 #define PRINTF_CHAR_GLint "%10d"
690 #define PRINTF_CHAR_GLsizei "%10u"
691 #define PRINTF_CHAR_GLuint "%10u"
692 #define PRINTF_CHAR_GLuintmask "0x%8X"
694 #define PRINTF_CHAR_GLclampf "%10.6f"
695 #define PRINTF_CHAR_GLfloat "%10.6f"
697 #define PRINTF_CHAR_GLvoidptr "%10p"
699 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
701 #define INITIAL_CTX initial_ctx
702 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
704 TYPE valuedata[SIZE]; \
705 TYPE *value = NULL; \
706 value = valuedata; GET_STMT; value = valuedata; \
707 TRACE("\E[0;37;1m %-30.30s : (\E[0m ", #NAME); \
708 for (int i = 0; i < SIZE; i++) \
712 TRACE("\n %-30.30s ", "");\
716 TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
717 TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
719 TRACE(" \E[0;37;1m)\E[0m\n"); \
721 # include "coregl_fastpath_state.h"
725 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
735 fastpath_init_context_states(GLGlueContext *ctx)
739 AST(mutex_lock(&init_context_mutex) == 1);
743 ERR("Context NULL\n");
748 AST(ctx->initialized == 0);
749 AST(ctx->sostate != NULL);
751 if (initial_ctx == NULL)
753 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
754 AST(initial_ctx != NULL);
756 //#define FORCE_DEFAULT_VALUE
757 #ifdef FORCE_DEFAULT_VALUE
758 # define INITIAL_CTX initial_ctx
759 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
762 TYPE valuedata[SIZE]; \
763 TYPE *value = NULL; \
764 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
765 value = valuedata; DEFAULT_STMT; value = valuedata; \
766 for (i = 0; i < SIZE; i++) \
768 if (*((char *)(&value[i])) == 0xcc) \
770 memset(&value[i], 0xaa, sizeof(TYPE)); \
771 value = valuedata; DEFAULT_STMT; value = valuedata; \
772 if (*((char *)(&value[i])) == 0xaa) \
774 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
778 initial_ctx->NAME[i] = value[i]; \
781 # include "coregl_fastpath_state.h"
785 # define INITIAL_CTX initial_ctx
786 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
789 value = valuedata; DEFAULT_STMT; value = valuedata; \
793 value = valuedata; FALLBACK_STMT; value = valuedata; \
796 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
800 TYPE valuedata[SIZE]; \
801 TYPE *value = NULL; \
802 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
805 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
806 for (i = 0; i < SIZE; i++) \
808 if (*((char *)(&value[i])) == 0xcc) \
810 memset(&value[i], 0xaa, sizeof(TYPE)); \
811 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
812 if (*((char *)(&value[i])) == 0xaa) \
817 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
822 initial_ctx->NAME[i] = value[i]; \
826 value = valuedata; DEFAULT_STMT; value = valuedata; \
827 for (i = 0; i < SIZE; i++) \
829 if (initial_ctx->NAME[i] != value[i]) \
831 ERR("WARNING : GL-state '"#NAME"'[%d] value ["PRINTF_CHAR(TYPE)"] is different from SPEC-DEFAULT ["PRINTF_CHAR(TYPE)"]\n", i, ctx->NAME[i], value[i]); \
836 while (try_step == 2); \
838 # include "coregl_fastpath_state.h"
839 # undef SET_GLUE_VALUE
844 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
846 ERR("\E[0;31;1mWARNING : Number of vertex attrib is too big! (%d-%d)\E[0m\n", MAX_VERTEX_ATTRIBS, initial_ctx->gl_num_vertex_attribs[0]);
848 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
850 ERR("\E[0;31;1mWARNING : Number of texture unit is too big! (%d-%d)\E[0m\n", MAX_TEXTURE_UNITS, initial_ctx->gl_num_tex_units[0]);
856 #define INITIAL_CTX initial_ctx
857 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
858 for (i = 0; i < SIZE; i++) \
860 ctx->NAME[i] = initial_ctx->NAME[i]; \
862 # include "coregl_fastpath_state.h"
867 ctx->initialized = 1;
872 AST(mutex_unlock(&init_context_mutex) == 1);
877 #ifdef COREGL_USE_MODULE_TRACEPATH
878 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
879 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
882 #define CHECK_GL_ERROR(func) \
885 int err = _orig_fastpath_glGetError(); \
886 if (err != GL_NO_ERROR) \
888 ERR("\E[0;31;1mERROR(GL %p) : %s returns GL error 0x%X\E[0m\n", oldctx->cstate, #func, err); \
894 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
897 unsigned char flag = 0;
906 // Return if they're the same
907 if (oldctx == newctx)
913 #define STATE_COMPARE(state) \
914 if ((oldctx->state) != (newctx->state))
916 #define STATES_COMPARE(state_ptr, bytes) \
917 if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
920 #ifdef COREGL_USE_MODULE_TRACEPATH
921 static void *trace_hint_glfinish = NULL;
922 trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
923 #endif // COREGL_USE_MODULE_TRACEPATH
926 int err = _orig_fastpath_glGetError();
927 if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR)
928 oldctx->gl_error = err;
931 CHECK_GL_ERROR(_orig_fastpath_glFlush())
933 #ifdef COREGL_USE_MODULE_TRACEPATH
934 tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
935 #endif // COREGL_USE_MODULE_TRACEPATH
937 #ifdef COREGL_USE_MODULE_TRACEPATH
938 static void *trace_hint_bindbuffers = NULL;
939 trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
940 #endif // COREGL_USE_MODULE_TRACEPATH
943 //------------------//
945 flag = oldctx->_bind_flag | newctx->_bind_flag;
948 STATE_COMPARE(gl_array_buffer_binding[0])
950 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]))
952 STATE_COMPARE(gl_element_array_buffer_binding[0])
954 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]))
956 STATE_COMPARE(gl_framebuffer_binding[0])
958 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]))
960 STATE_COMPARE(gl_renderbuffer_binding[0])
962 CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]))
966 #ifdef COREGL_USE_MODULE_TRACEPATH
967 tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
968 #endif // COREGL_USE_MODULE_TRACEPATH
971 //------------------//
974 #ifdef COREGL_USE_MODULE_TRACEPATH
975 static void *trace_hint_enable_states = NULL;
976 trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
977 #endif // COREGL_USE_MODULE_TRACEPATH
979 flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
982 STATE_COMPARE(gl_blend[0])
984 if (newctx->gl_blend[0])
986 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
989 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
991 STATE_COMPARE(gl_cull_face[0])
993 if (newctx->gl_cull_face[0])
995 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
998 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
1000 STATE_COMPARE(gl_depth_test[0])
1002 if (newctx->gl_depth_test[0])
1004 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
1007 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
1009 STATE_COMPARE(gl_dither[0])
1011 if (newctx->gl_dither[0])
1013 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
1016 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
1021 flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
1024 STATE_COMPARE(gl_polygon_offset_fill[0])
1026 if (newctx->gl_polygon_offset_fill[0])
1028 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
1031 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
1033 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
1035 if (newctx->gl_sample_alpha_to_coverage[0])
1037 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1040 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1042 STATE_COMPARE(gl_sample_coverage[0])
1044 if (newctx->gl_sample_coverage[0])
1046 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
1049 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
1051 STATE_COMPARE(gl_scissor_test[0])
1053 if (newctx->gl_scissor_test[0])
1055 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
1058 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
1060 STATE_COMPARE(gl_stencil_test[0])
1062 if (newctx->gl_stencil_test[0])
1064 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
1067 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
1071 #ifdef COREGL_USE_MODULE_TRACEPATH
1072 tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
1073 #endif // COREGL_USE_MODULE_TRACEPATH
1075 //------------------//
1077 #ifdef COREGL_USE_MODULE_TRACEPATH
1078 static void *trace_hint_clear_viewport = NULL;
1079 trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1080 #endif // COREGL_USE_MODULE_TRACEPATH
1082 flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
1086 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
1088 CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
1089 newctx->gl_viewport[1],
1090 newctx->gl_viewport[2],
1091 newctx->gl_viewport[3]))
1094 STATE_COMPARE(gl_current_program[0])
1096 CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
1098 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
1100 CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
1101 newctx->gl_color_clear_value[1],
1102 newctx->gl_color_clear_value[2],
1103 newctx->gl_color_clear_value[3]))
1109 flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
1112 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
1114 CHECK_GL_ERROR(_orig_fastpath_glColorMask(newctx->gl_color_writemask[0],
1115 newctx->gl_color_writemask[1],
1116 newctx->gl_color_writemask[2],
1117 newctx->gl_color_writemask[3]))
1119 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
1121 CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
1122 newctx->gl_depth_range[1]))
1124 STATE_COMPARE(gl_depth_clear_value[0])
1126 CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
1128 STATE_COMPARE(gl_depth_func[0])
1130 CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
1132 STATE_COMPARE(gl_depth_writemask[0])
1134 CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
1136 STATE_COMPARE(gl_cull_face_mode[0])
1138 CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
1143 #ifdef COREGL_USE_MODULE_TRACEPATH
1144 tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1145 #endif // COREGL_USE_MODULE_TRACEPATH
1147 //------------------//
1149 #ifdef COREGL_USE_MODULE_TRACEPATH
1150 static void *trace_hint_bind_textures = NULL;
1151 trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1152 #endif // COREGL_USE_MODULE_TRACEPATH
1154 flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1158 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1160 STATE_COMPARE(gl_tex_2d_state[i])
1162 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1163 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]))
1166 STATE_COMPARE(gl_tex_cube_state[i])
1168 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1169 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]))
1173 // Restore active texture
1174 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
1176 STATE_COMPARE(gl_generate_mipmap_hint[0])
1178 CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]))
1181 #ifdef COREGL_USE_MODULE_TRACEPATH
1182 tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1183 #endif // COREGL_USE_MODULE_TRACEPATH
1185 //------------------//
1186 #ifdef COREGL_USE_MODULE_TRACEPATH
1187 static void *trace_hint_etc = NULL;
1188 trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1189 #endif // COREGL_USE_MODULE_TRACEPATH
1191 flag = oldctx->_blend_flag | newctx->_blend_flag;
1194 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1196 CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
1197 newctx->gl_blend_color[1],
1198 newctx->gl_blend_color[2],
1199 newctx->gl_blend_color[3]))
1201 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1202 (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1203 (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1204 (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1206 CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1207 newctx->gl_blend_dst_rgb[0],
1208 newctx->gl_blend_src_alpha[0],
1209 newctx->gl_blend_dst_alpha[0]))
1211 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1212 (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1214 CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]))
1219 //------------------//
1221 flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1224 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1225 (oldctx->gl_stencil_ref[0] != newctx->gl_stencil_ref[0]) ||
1226 (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1228 CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
1229 newctx->gl_stencil_func[0],
1230 newctx->gl_stencil_ref[0],
1231 newctx->gl_stencil_value_mask[0]))
1233 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1234 (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1235 (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1237 CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
1238 newctx->gl_stencil_fail[0],
1239 newctx->gl_stencil_pass_depth_fail[0],
1240 newctx->gl_stencil_pass_depth_pass[0]))
1243 STATE_COMPARE(gl_stencil_writemask[0])
1245 CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]))
1251 flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1254 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1255 (oldctx->gl_stencil_back_ref[0] != newctx->gl_stencil_back_ref[0]) ||
1256 (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1258 CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
1259 newctx->gl_stencil_back_func[0],
1260 newctx->gl_stencil_back_ref[0],
1261 newctx->gl_stencil_back_value_mask[0]))
1263 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1264 (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1265 (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1267 CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
1268 newctx->gl_stencil_back_fail[0],
1269 newctx->gl_stencil_back_pass_depth_fail[0],
1270 newctx->gl_stencil_back_pass_depth_pass[0]))
1273 STATE_COMPARE(gl_stencil_back_writemask[0])
1275 CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]))
1277 STATE_COMPARE(gl_stencil_clear_value[0])
1279 CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
1283 //------------------//
1285 flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1288 STATE_COMPARE(gl_front_face[0])
1290 CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
1292 STATE_COMPARE(gl_line_width[0])
1294 CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
1296 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1297 (oldctx->gl_polygon_offset_units[0] != newctx->gl_polygon_offset_units[0]))
1299 CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1300 newctx->gl_polygon_offset_units[0]))
1302 if ((oldctx->gl_sample_coverage_value[0] != newctx->gl_sample_coverage_value[0]) ||
1303 (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1305 CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1306 newctx->gl_sample_coverage_invert[0]))
1311 flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1314 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1316 CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
1317 newctx->gl_scissor_box[1],
1318 newctx->gl_scissor_box[2],
1319 newctx->gl_scissor_box[3]))
1321 STATE_COMPARE(gl_pack_alignment[0])
1323 CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]))
1325 STATE_COMPARE(gl_unpack_alignment[0])
1327 CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]))
1330 #ifdef COREGL_USE_MODULE_TRACEPATH
1331 tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1332 #endif // COREGL_USE_MODULE_TRACEPATH
1335 #ifdef COREGL_USE_MODULE_TRACEPATH
1336 static void *trace_hint_vertex_attrib = NULL;
1337 trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1338 #endif // COREGL_USE_MODULE_TRACEPATH
1340 flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1343 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1345 if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1347 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]))
1351 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
1354 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
1355 newctx->gl_vertex_array_size[i],
1356 newctx->gl_vertex_array_type[i],
1357 newctx->gl_vertex_array_normalized[i],
1358 newctx->gl_vertex_array_stride[i],
1359 newctx->gl_vertex_array_pointer[i]))
1361 STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1363 CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]))
1366 if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1368 CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
1372 CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
1376 STATE_COMPARE(gl_array_buffer_binding[0])
1378 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]))
1380 STATE_COMPARE(gl_element_array_buffer_binding[0])
1382 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]))
1387 #ifdef COREGL_USE_MODULE_TRACEPATH
1388 tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1389 #endif // COREGL_USE_MODULE_TRACEPATH
1396 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1397 if (unlikely(trace_state_flag == 1))
1398 fastpath_dump_context_states(newctx, 0);
1399 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1401 #undef STATE_COMPARE
1402 #undef STATES_COMPARE