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 _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
39 for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++)
41 _sym_glActiveTexture(GL_TEXTURE0 + i);
42 _sym_glGetIntegerv(pname, &(((GLint *)params)[i]));
44 _sym_glActiveTexture(cur_active_tex);
48 _get_stencil_max_mask()
50 GLuint stencil_bit = 0;
52 _sym_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"));
87 fastpath_apply_overrides();
92 deinit_modules_fastpath()
94 GLContext_List *current = NULL;
96 AST(mutex_lock(&ctx_list_access_mutex) == 1);
98 // Destroy remained context & Detect leaks
99 int retry_destroy = 0;
104 current = glctx_list;
107 if (current->cstate != NULL)
109 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);
111 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
112 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
114 fastpath_remove_context_states_from_list(current->cstate, NULL);
119 glctx_list = current->next;
121 current = glctx_list;
123 if (retry_destroy == 0) break;
128 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
132 init_modules_tstate_fastpath(GLThreadState *tstate)
134 MY_MODULE_TSTATE *tstate_mt = NULL;
136 tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
138 tstate_mt->binded_api = EGL_OPENGL_ES_API;
140 tstate->module_data[MY_MODULE_ID] = tstate_mt;
144 deinit_modules_tstate_fastpath(GLThreadState *tstate)
146 if (tstate->module_data[MY_MODULE_ID] != NULL)
148 free(tstate->module_data[MY_MODULE_ID]);
149 tstate->module_data[MY_MODULE_ID] = NULL;
154 fastpath_apply_overrides()
159 fastpath_apply_overrides_egl(1);
160 fastpath_apply_overrides_gl(1);
165 ERR("Invalide GL Override Option!!!\n");
170 #define OVERRIDE(f) \
173 COREGL_OVERRIDE_API(_orig_fastpath_, f, ovr_); \
174 COREGL_OVERRIDE_API(ovr_, f, fastpath_); \
178 AST(ovr_##f != NULL); \
179 COREGL_OVERRIDE_API(ovr_, f, _orig_fastpath_); \
180 _orig_fastpath_##f = NULL; \
184 fastpath_apply_overrides_egl(int enable)
186 // Fast-Path Core Functions
187 OVERRIDE(eglGetProcAddress);
189 OVERRIDE(eglBindAPI);
190 OVERRIDE(eglQueryAPI);
192 OVERRIDE(eglCreateContext);
193 OVERRIDE(eglCreateImageKHR);
194 OVERRIDE(eglMakeCurrent);
195 OVERRIDE(eglDestroyContext);
196 OVERRIDE(eglQueryContext);
197 OVERRIDE(eglGetCurrentContext);
198 OVERRIDE(eglReleaseThread);
199 OVERRIDE(eglGetCurrentSurface);
200 OVERRIDE(eglTerminate);
205 fastpath_apply_overrides_gl(int enable)
207 // Fast-Path Functions
210 OVERRIDE(glGetError);
212 OVERRIDE(glGetIntegerv);
213 OVERRIDE(glGetFloatv);
214 OVERRIDE(glGetBooleanv);
216 OVERRIDE(glActiveTexture);
217 OVERRIDE(glGenTextures);
218 OVERRIDE(glBindTexture);
219 OVERRIDE(glIsTexture);
220 OVERRIDE(glDeleteTextures);
221 OVERRIDE(glFramebufferTexture2D);
222 OVERRIDE(glFramebufferTexture2DMultisampleEXT);
224 OVERRIDE(glGenBuffers);
225 OVERRIDE(glBindBuffer);
226 OVERRIDE(glIsBuffer);
227 OVERRIDE(glDeleteBuffers);
229 OVERRIDE(glGenFramebuffers);
230 OVERRIDE(glBindFramebuffer);
231 OVERRIDE(glIsFramebuffer);
232 OVERRIDE(glDeleteFramebuffers);
234 OVERRIDE(glGenRenderbuffers);
235 OVERRIDE(glBindRenderbuffer);
236 OVERRIDE(glFramebufferRenderbuffer);
237 OVERRIDE(glIsRenderbuffer);
238 OVERRIDE(glDeleteRenderbuffers);
240 OVERRIDE(glCreateShader);
241 OVERRIDE(glCreateProgram);
242 OVERRIDE(glAttachShader);
243 OVERRIDE(glCompileShader);
244 OVERRIDE(glShaderBinary);
245 OVERRIDE(glDeleteShader);
246 OVERRIDE(glDetachShader);
247 OVERRIDE(glGetShaderiv);
248 OVERRIDE(glGetShaderInfoLog);
249 OVERRIDE(glGetShaderSource);
250 OVERRIDE(glIsShader);
251 OVERRIDE(glShaderSource);
252 OVERRIDE(glBindAttribLocation);
253 OVERRIDE(glDeleteProgram);
254 OVERRIDE(glDetachShader);
255 OVERRIDE(glGetActiveAttrib);
256 OVERRIDE(glGetActiveUniform);
257 OVERRIDE(glGetAttachedShaders);
258 OVERRIDE(glGetAttribLocation);
259 OVERRIDE(glGetProgramiv);
260 OVERRIDE(glGetProgramInfoLog);
261 OVERRIDE(glGetUniformfv);
262 OVERRIDE(glGetUniformiv);
263 OVERRIDE(glGetUniformLocation);
264 OVERRIDE(glIsProgram);
265 OVERRIDE(glLinkProgram);
266 OVERRIDE(glUseProgram);
267 OVERRIDE(glValidateProgram);
268 OVERRIDE(glGetProgramBinary);
269 OVERRIDE(glProgramBinary);
271 OVERRIDE(glBlendColor);
272 OVERRIDE(glBlendEquation);
273 OVERRIDE(glBlendEquationSeparate);
274 OVERRIDE(glBlendFunc);
275 OVERRIDE(glBlendFuncSeparate);
276 OVERRIDE(glClearColor);
277 OVERRIDE(glClearDepthf);
278 OVERRIDE(glClearStencil);
279 OVERRIDE(glColorMask);
280 OVERRIDE(glCullFace);
281 OVERRIDE(glDepthFunc);
282 OVERRIDE(glDepthMask);
283 OVERRIDE(glDepthRangef);
285 OVERRIDE(glDisableVertexAttribArray);
286 OVERRIDE(glDrawArrays);
287 OVERRIDE(glDrawElements);
289 OVERRIDE(glEnableVertexAttribArray);
290 OVERRIDE(glFrontFace);
291 OVERRIDE(glGetVertexAttribfv);
292 OVERRIDE(glGetVertexAttribiv);
293 OVERRIDE(glGetVertexAttribPointerv);
295 OVERRIDE(glLineWidth);
296 OVERRIDE(glPixelStorei);
297 OVERRIDE(glPolygonOffset);
298 OVERRIDE(glSampleCoverage);
300 OVERRIDE(glStencilFunc);
301 OVERRIDE(glStencilFuncSeparate);
302 OVERRIDE(glStencilMask);
303 OVERRIDE(glStencilMaskSeparate);
304 OVERRIDE(glStencilOp);
305 OVERRIDE(glStencilOpSeparate);
306 OVERRIDE(glVertexAttrib1f);
307 OVERRIDE(glVertexAttrib1fv);
308 OVERRIDE(glVertexAttrib2f);
309 OVERRIDE(glVertexAttrib2fv);
310 OVERRIDE(glVertexAttrib3f);
311 OVERRIDE(glVertexAttrib3fv);
312 OVERRIDE(glVertexAttrib4f);
313 OVERRIDE(glVertexAttrib4fv);
314 OVERRIDE(glVertexAttribPointer);
315 OVERRIDE(glViewport);
317 OVERRIDE(glEGLImageTargetTexture2DOES);
322 LOG("\E[0;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
329 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
333 case GL_OBJECT_TYPE_TEXTURE:
334 return sostate->texture;
335 case GL_OBJECT_TYPE_BUFFER:
336 return sostate->buffer;
337 case GL_OBJECT_TYPE_FRAMEBUFFER:
338 return sostate->framebuffer;
339 case GL_OBJECT_TYPE_RENDERBUFFER:
340 return sostate->renderbuffer;
341 case GL_OBJECT_TYPE_PROGRAM:
342 return sostate->program;
349 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
353 GLContext_List *current = NULL;
354 GLContext_List *newitm = NULL;
356 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
360 tid = get_current_thread();
362 current = glctx_list;
363 while (current != NULL)
365 if (current->option_len == option_len &&
366 memcmp(current->option, option, option_len) == 0 &&
367 current->thread_id == tid)
369 AST(current->cstate == cstate);
372 current = current->next;
375 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
378 ERR("Failed to create context list.\n");
382 newitm->cstate = cstate;
383 newitm->thread_id = tid;
384 newitm->option_len = option_len;
385 newitm->option = (void *)malloc(option_len);
386 memcpy(newitm->option, option, option_len);
388 if (glctx_list != NULL)
389 newitm->next = glctx_list;
410 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
416 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
418 GLContextState *ret = NULL;
419 GLContext_List *current = NULL;
422 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
424 tid = get_current_thread();
426 current = glctx_list;
427 while (current != NULL)
429 if (current->option_len == option_len &&
430 memcmp(current->option, option, option_len) == 0 &&
431 current->thread_id == tid)
433 ret = current->cstate;
436 current = current->next;
441 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
446 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
450 GLContext_List *olditm = NULL;
451 GLContext_List *current = NULL;
453 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
457 tid = get_current_thread();
458 current = glctx_list;
460 while (current != NULL)
462 if (current->cstate == cstate)
464 GLContext_List *nextitm = NULL;
467 olditm->next = current->next;
468 nextitm = olditm->next;
472 glctx_list = current->next;
473 nextitm = glctx_list;
481 current = current->next;
486 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
491 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
493 GL_Object **object = NULL;
494 GLuint ret = _COREGL_INT_INIT_VALUE;
497 object = _get_shared_object(sostate, type);
499 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
501 if (object[i] == NULL)
503 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
504 newobj->id = (int)type + i;
505 newobj->real_id = real_name;
518 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
520 GL_Object **object = NULL;
521 GLuint ret = _COREGL_INT_INIT_VALUE;
522 int hash = _COREGL_INT_INIT_VALUE;
524 object = _get_shared_object(sostate, type);
526 hash = glue_name - (int)type;
528 hash > MAX_GL_OBJECT_SIZE ||
529 object[hash] == NULL ||
530 object[hash]->id != glue_name)
546 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
548 GL_Object **object = NULL;
549 GLuint ret = _COREGL_INT_INIT_VALUE;
550 int hash = _COREGL_INT_INIT_VALUE;
552 object = _get_shared_object(sostate, type);
554 hash = glue_name - (int)type;
556 hash > MAX_GL_OBJECT_SIZE ||
557 object[hash] == NULL ||
558 object[hash]->id != glue_name)
563 ret = object[hash]->real_id;
571 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
573 GL_Object **object = NULL;
574 GLuint ret = _COREGL_INT_INIT_VALUE;
577 object = _get_shared_object(sostate, type);
579 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
581 if (object[i] != NULL && object[i]->real_id == real_name)
595 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
597 static struct timeval tv_last = { 0, 0 };
599 if (unlikely(trace_state_flag != 1)) return;
603 struct timeval tv_now = { 0, 0 };
604 AST(gettimeofday(&tv_now, NULL) == 0);
605 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
613 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
614 TRACE("\E[0;32;1m State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
615 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
617 #define PRINTF_CHAR_GLenum "%10d"
618 #define PRINTF_CHAR_GLboolean "%10d"
619 #define PRINTF_CHAR_GLint "%10d"
620 #define PRINTF_CHAR_GLsizei "%10u"
621 #define PRINTF_CHAR_GLuint "%10u"
622 #define PRINTF_CHAR_GLuintmask "0x%8X"
624 #define PRINTF_CHAR_GLclampf "%10.6f"
625 #define PRINTF_CHAR_GLfloat "%10.6f"
627 #define PRINTF_CHAR_GLvoidptr "%10p"
629 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
631 #define INITIAL_CTX initial_ctx
632 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
634 TYPE valuedata[SIZE]; \
635 TYPE *value = NULL; \
636 value = valuedata; GET_STMT; value = valuedata; \
637 TRACE("\E[0;37;1m %-30.30s : (\E[0m ", #NAME); \
638 for (int i = 0; i < SIZE; i++) \
642 TRACE("\n %-30.30s ", "");\
646 TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
647 TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
649 TRACE(" \E[0;37;1m)\E[0m\n"); \
651 # include "coregl_fastpath_state.h"
655 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
665 fastpath_init_context_states(GLGlueContext *ctx)
669 AST(mutex_lock(&init_context_mutex) == 1);
673 ERR("Context NULL\n");
678 AST(ctx->initialized == 0);
679 AST(ctx->sostate != NULL);
681 if (initial_ctx == NULL)
683 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
684 AST(initial_ctx != NULL);
686 //#define FORCE_DEFAULT_VALUE
687 #ifdef FORCE_DEFAULT_VALUE
688 # define INITIAL_CTX initial_ctx
689 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
692 TYPE valuedata[SIZE]; \
693 TYPE *value = NULL; \
694 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
695 value = valuedata; DEFAULT_STMT; value = valuedata; \
696 for (i = 0; i < SIZE; i++) \
698 if (*((char *)(&value[i])) == 0xcc) \
700 memset(&value[i], 0xaa, sizeof(TYPE)); \
701 value = valuedata; DEFAULT_STMT; value = valuedata; \
702 if (*((char *)(&value[i])) == 0xaa) \
704 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
708 initial_ctx->NAME[i] = value[i]; \
711 # include "coregl_fastpath_state.h"
715 # define INITIAL_CTX initial_ctx
716 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
719 value = valuedata; DEFAULT_STMT; value = valuedata; \
723 value = valuedata; FALLBACK_STMT; value = valuedata; \
726 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
730 TYPE valuedata[SIZE]; \
731 TYPE *value = NULL; \
732 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
735 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
736 for (i = 0; i < SIZE; i++) \
738 if (*((char *)(&value[i])) == 0xcc) \
740 memset(&value[i], 0xaa, sizeof(TYPE)); \
741 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
742 if (*((char *)(&value[i])) == 0xaa) \
747 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
752 initial_ctx->NAME[i] = value[i]; \
756 value = valuedata; DEFAULT_STMT; value = valuedata; \
757 for (i = 0; i < SIZE; i++) \
759 if (initial_ctx->NAME[i] != value[i]) \
761 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]); \
766 while (try_step == 2); \
768 # include "coregl_fastpath_state.h"
769 # undef SET_GLUE_VALUE
774 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
776 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]);
778 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
780 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]);
786 #define INITIAL_CTX initial_ctx
787 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
788 for (i = 0; i < SIZE; i++) \
790 ctx->NAME[i] = initial_ctx->NAME[i]; \
792 # include "coregl_fastpath_state.h"
797 ctx->initialized = 1;
802 AST(mutex_unlock(&init_context_mutex) == 1);
807 #ifdef COREGL_USE_MODULE_TRACEPATH
808 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
809 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
813 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
815 unsigned char flag = 0;
818 if (debug_nofp == 1) goto finish;
820 // Return if they're the same
821 if (oldctx == newctx) goto finish;
823 #define STATE_COMPARE(state) \
824 if ((oldctx->state) != (newctx->state))
826 #define STATES_COMPARE(state_ptr, bytes) \
827 if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
830 #ifdef COREGL_USE_MODULE_TRACEPATH
831 static void *trace_hint_glfinish = NULL;
832 trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
833 #endif // COREGL_USE_MODULE_TRACEPATH
837 #ifdef COREGL_USE_MODULE_TRACEPATH
838 tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
839 #endif // COREGL_USE_MODULE_TRACEPATH
841 #ifdef COREGL_USE_MODULE_TRACEPATH
842 static void *trace_hint_bindbuffers = NULL;
843 trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
844 #endif // COREGL_USE_MODULE_TRACEPATH
846 //------------------//
848 flag = oldctx->_bind_flag | newctx->_bind_flag;
851 STATE_COMPARE(gl_array_buffer_binding[0])
853 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
855 STATE_COMPARE(gl_element_array_buffer_binding[0])
857 _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
859 STATE_COMPARE(gl_framebuffer_binding[0])
861 _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
863 STATE_COMPARE(gl_renderbuffer_binding[0])
865 _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
869 #ifdef COREGL_USE_MODULE_TRACEPATH
870 tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
871 #endif // COREGL_USE_MODULE_TRACEPATH
874 //------------------//
877 #ifdef COREGL_USE_MODULE_TRACEPATH
878 static void *trace_hint_enable_states = NULL;
879 trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
880 #endif // COREGL_USE_MODULE_TRACEPATH
882 flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
885 STATE_COMPARE(gl_blend[0])
887 if (newctx->gl_blend[0])
888 _sym_glEnable(GL_BLEND);
890 _sym_glDisable(GL_BLEND);
892 STATE_COMPARE(gl_cull_face[0])
894 if (newctx->gl_cull_face[0])
895 _sym_glEnable(GL_CULL_FACE);
897 _sym_glDisable(GL_CULL_FACE);
899 STATE_COMPARE(gl_depth_test[0])
901 if (newctx->gl_depth_test[0])
902 _sym_glEnable(GL_DEPTH_TEST);
904 _sym_glDisable(GL_DEPTH_TEST);
906 STATE_COMPARE(gl_dither[0])
908 if (newctx->gl_dither[0])
909 _sym_glEnable(GL_DITHER);
911 _sym_glDisable(GL_DITHER);
916 flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
919 STATE_COMPARE(gl_polygon_offset_fill[0])
921 if (newctx->gl_polygon_offset_fill[0])
922 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
924 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
926 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
928 if (newctx->gl_sample_alpha_to_coverage[0])
929 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
931 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
933 STATE_COMPARE(gl_sample_coverage[0])
935 if (newctx->gl_sample_coverage[0])
936 _sym_glEnable(GL_SAMPLE_COVERAGE);
938 _sym_glDisable(GL_SAMPLE_COVERAGE);
940 STATE_COMPARE(gl_scissor_test[0])
942 if (newctx->gl_scissor_test[0])
943 _sym_glEnable(GL_SCISSOR_TEST);
945 _sym_glDisable(GL_SCISSOR_TEST);
947 STATE_COMPARE(gl_stencil_test[0])
949 if (newctx->gl_stencil_test[0])
950 _sym_glEnable(GL_STENCIL_TEST);
952 _sym_glDisable(GL_STENCIL_TEST);
956 #ifdef COREGL_USE_MODULE_TRACEPATH
957 tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
958 #endif // COREGL_USE_MODULE_TRACEPATH
960 //------------------//
962 #ifdef COREGL_USE_MODULE_TRACEPATH
963 static void *trace_hint_clear_viewport = NULL;
964 trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
965 #endif // COREGL_USE_MODULE_TRACEPATH
967 flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
971 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
973 _sym_glViewport(newctx->gl_viewport[0],
974 newctx->gl_viewport[1],
975 newctx->gl_viewport[2],
976 newctx->gl_viewport[3]);
979 STATE_COMPARE(gl_current_program[0])
981 _sym_glUseProgram(newctx->gl_current_program[0]);
983 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
985 _sym_glClearColor(newctx->gl_color_clear_value[0],
986 newctx->gl_color_clear_value[1],
987 newctx->gl_color_clear_value[2],
988 newctx->gl_color_clear_value[3]);
994 flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
997 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
999 _sym_glColorMask(newctx->gl_color_writemask[0],
1000 newctx->gl_color_writemask[1],
1001 newctx->gl_color_writemask[2],
1002 newctx->gl_color_writemask[3]);
1004 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
1006 _sym_glDepthRangef(newctx->gl_depth_range[0],
1007 newctx->gl_depth_range[1]);
1009 STATE_COMPARE(gl_depth_clear_value[0])
1011 _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
1013 STATE_COMPARE(gl_depth_func[0])
1015 _sym_glDepthFunc(newctx->gl_depth_func[0]);
1017 STATE_COMPARE(gl_depth_writemask[0])
1019 _sym_glDepthMask(newctx->gl_depth_writemask[0]);
1021 STATE_COMPARE(gl_cull_face_mode[0])
1023 _sym_glCullFace(newctx->gl_cull_face_mode[0]);
1028 #ifdef COREGL_USE_MODULE_TRACEPATH
1029 tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1030 #endif // COREGL_USE_MODULE_TRACEPATH
1032 //------------------//
1034 #ifdef COREGL_USE_MODULE_TRACEPATH
1035 static void *trace_hint_bind_textures = NULL;
1036 trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1037 #endif // COREGL_USE_MODULE_TRACEPATH
1039 flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1043 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1045 STATE_COMPARE(gl_tex_2d_state[i])
1047 _sym_glActiveTexture(GL_TEXTURE0 + i);
1048 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
1051 STATE_COMPARE(gl_tex_cube_state[i])
1053 _sym_glActiveTexture(GL_TEXTURE0 + i);
1054 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
1058 // Restore active texture
1059 _sym_glActiveTexture(newctx->gl_active_texture[0]);
1061 STATE_COMPARE(gl_generate_mipmap_hint[0])
1063 _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
1066 #ifdef COREGL_USE_MODULE_TRACEPATH
1067 tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1068 #endif // COREGL_USE_MODULE_TRACEPATH
1070 //------------------//
1071 #ifdef COREGL_USE_MODULE_TRACEPATH
1072 static void *trace_hint_etc = NULL;
1073 trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1074 #endif // COREGL_USE_MODULE_TRACEPATH
1076 flag = oldctx->_blend_flag | newctx->_blend_flag;
1079 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1081 _sym_glBlendColor(newctx->gl_blend_color[0],
1082 newctx->gl_blend_color[1],
1083 newctx->gl_blend_color[2],
1084 newctx->gl_blend_color[3]);
1086 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1087 (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1088 (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1089 (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1091 _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1092 newctx->gl_blend_dst_rgb[0],
1093 newctx->gl_blend_src_alpha[0],
1094 newctx->gl_blend_dst_alpha[0]);
1096 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1097 (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1099 _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
1104 //------------------//
1106 flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1109 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1110 (oldctx->gl_stencil_ref[0] != newctx->gl_stencil_ref[0]) ||
1111 (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1113 _sym_glStencilFuncSeparate(GL_FRONT,
1114 newctx->gl_stencil_func[0],
1115 newctx->gl_stencil_ref[0],
1116 newctx->gl_stencil_value_mask[0]);
1118 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1119 (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1120 (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1122 _sym_glStencilOpSeparate(GL_FRONT,
1123 newctx->gl_stencil_fail[0],
1124 newctx->gl_stencil_pass_depth_fail[0],
1125 newctx->gl_stencil_pass_depth_pass[0]);
1128 STATE_COMPARE(gl_stencil_writemask[0])
1130 _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
1136 flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1139 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1140 (oldctx->gl_stencil_back_ref[0] != newctx->gl_stencil_back_ref[0]) ||
1141 (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1143 _sym_glStencilFuncSeparate(GL_BACK,
1144 newctx->gl_stencil_back_func[0],
1145 newctx->gl_stencil_back_ref[0],
1146 newctx->gl_stencil_back_value_mask[0]);
1148 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1149 (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1150 (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1152 _sym_glStencilOpSeparate(GL_BACK,
1153 newctx->gl_stencil_back_fail[0],
1154 newctx->gl_stencil_back_pass_depth_fail[0],
1155 newctx->gl_stencil_back_pass_depth_pass[0]);
1158 STATE_COMPARE(gl_stencil_back_writemask[0])
1160 _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
1162 STATE_COMPARE(gl_stencil_clear_value[0])
1164 _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
1168 //------------------//
1170 flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1173 STATE_COMPARE(gl_front_face[0])
1175 _sym_glFrontFace(newctx->gl_front_face[0]);
1177 STATE_COMPARE(gl_line_width[0])
1179 _sym_glLineWidth(newctx->gl_line_width[0]);
1181 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1182 (oldctx->gl_polygon_offset_units[0] != newctx->gl_polygon_offset_units[0]))
1184 _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1185 newctx->gl_polygon_offset_units[0]);
1187 if ((oldctx->gl_sample_coverage_value[0] != newctx->gl_sample_coverage_value[0]) ||
1188 (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1190 _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1191 newctx->gl_sample_coverage_invert[0]);
1196 flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1199 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1201 _sym_glScissor(newctx->gl_scissor_box[0],
1202 newctx->gl_scissor_box[1],
1203 newctx->gl_scissor_box[2],
1204 newctx->gl_scissor_box[3]);
1206 STATE_COMPARE(gl_pack_alignment[0])
1208 _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
1210 STATE_COMPARE(gl_unpack_alignment[0])
1212 _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
1215 #ifdef COREGL_USE_MODULE_TRACEPATH
1216 tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1217 #endif // COREGL_USE_MODULE_TRACEPATH
1220 #ifdef COREGL_USE_MODULE_TRACEPATH
1221 static void *trace_hint_vertex_attrib = NULL;
1222 trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1223 #endif // COREGL_USE_MODULE_TRACEPATH
1225 flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1228 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1230 if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1232 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
1234 else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
1236 _sym_glVertexAttribPointer(i,
1237 newctx->gl_vertex_array_size[i],
1238 newctx->gl_vertex_array_type[i],
1239 newctx->gl_vertex_array_normalized[i],
1240 newctx->gl_vertex_array_stride[i],
1241 newctx->gl_vertex_array_pointer[i]);
1243 STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1245 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
1248 if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1250 _sym_glEnableVertexAttribArray(i);
1254 _sym_glDisableVertexAttribArray(i);
1258 STATE_COMPARE(gl_array_buffer_binding[0])
1260 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
1262 STATE_COMPARE(gl_element_array_buffer_binding[0])
1264 _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
1269 #ifdef COREGL_USE_MODULE_TRACEPATH
1270 tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1271 #endif // COREGL_USE_MODULE_TRACEPATH
1277 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1278 if (unlikely(trace_state_flag == 1))
1279 fastpath_dump_context_states(newctx, 0);
1280 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1282 #undef STATE_COMPARE
1283 #undef STATES_COMPARE