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()
61 LOG("[CoreGL] <Fastpath> : ");
63 fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
68 LOG("(%d) Fastpath enabled...\n", fastpath_opt);
69 fp_opt = FP_FAST_PATH;
72 LOG("(%d) Default API path enabled...\n", fastpath_opt);
73 fp_opt = FP_NORMAL_PATH;
77 debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
79 fastpath_apply_overrides();
84 deinit_modules_fastpath()
86 GLContext_List *current = NULL;
88 AST(mutex_lock(&ctx_list_access_mutex) == 1);
90 // Destroy remained context & Detect leaks
91 int retry_destroy = 0;
99 if (current->cstate != NULL)
101 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);
103 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
104 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
106 fastpath_remove_context_states_from_list(current->cstate, NULL);
111 glctx_list = current->next;
113 current = glctx_list;
115 if (retry_destroy == 0) break;
120 AST(mutex_unlock(&ctx_list_access_mutex) == 1);
124 init_modules_tstate_fastpath(GLThreadState *tstate)
126 MY_MODULE_TSTATE *tstate_mt = NULL;
128 tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
130 tstate_mt->binded_api = EGL_OPENGL_ES_API;
132 tstate->module_data[MY_MODULE_ID] = tstate_mt;
136 deinit_modules_tstate_fastpath(GLThreadState *tstate)
138 if (tstate->module_data[MY_MODULE_ID] != NULL)
140 free(tstate->module_data[MY_MODULE_ID]);
141 tstate->module_data[MY_MODULE_ID] = NULL;
146 fastpath_apply_overrides()
151 fastpath_apply_overrides_egl(1);
152 fastpath_apply_overrides_gl(1);
157 ERR("Invalide GL Override Option!!!\n");
162 #define OVERRIDE(f) \
165 COREGL_OVERRIDE_API(_orig_fastpath_, f, ovr_); \
166 COREGL_OVERRIDE_API(ovr_, f, fastpath_); \
170 AST(ovr_##f != NULL); \
171 COREGL_OVERRIDE_API(ovr_, f, _orig_fastpath_); \
172 _orig_fastpath_##f = NULL; \
176 fastpath_apply_overrides_egl(int enable)
178 // Fast-Path Core Functions
179 OVERRIDE(eglGetProcAddress);
181 OVERRIDE(eglBindAPI);
182 OVERRIDE(eglQueryAPI);
184 OVERRIDE(eglCreateContext);
185 OVERRIDE(eglCreateImageKHR);
186 OVERRIDE(eglMakeCurrent);
187 OVERRIDE(eglDestroyContext);
188 OVERRIDE(eglQueryContext);
189 OVERRIDE(eglGetCurrentContext);
190 OVERRIDE(eglReleaseThread);
191 OVERRIDE(eglGetCurrentSurface);
192 OVERRIDE(eglTerminate);
197 fastpath_apply_overrides_gl(int enable)
199 // Fast-Path Functions
202 OVERRIDE(glGetError);
204 OVERRIDE(glGetIntegerv);
205 OVERRIDE(glGetFloatv);
206 OVERRIDE(glGetBooleanv);
208 OVERRIDE(glActiveTexture);
209 OVERRIDE(glGenTextures);
210 OVERRIDE(glBindTexture);
211 OVERRIDE(glIsTexture);
212 OVERRIDE(glDeleteTextures);
213 OVERRIDE(glFramebufferTexture2D);
214 OVERRIDE(glFramebufferTexture2DMultisampleEXT);
216 OVERRIDE(glGenBuffers);
217 OVERRIDE(glBindBuffer);
218 OVERRIDE(glIsBuffer);
219 OVERRIDE(glDeleteBuffers);
221 OVERRIDE(glGenFramebuffers);
222 OVERRIDE(glBindFramebuffer);
223 OVERRIDE(glIsFramebuffer);
224 OVERRIDE(glDeleteFramebuffers);
226 OVERRIDE(glGenRenderbuffers);
227 OVERRIDE(glBindRenderbuffer);
228 OVERRIDE(glFramebufferRenderbuffer);
229 OVERRIDE(glIsRenderbuffer);
230 OVERRIDE(glDeleteRenderbuffers);
232 OVERRIDE(glCreateShader);
233 OVERRIDE(glCreateProgram);
234 OVERRIDE(glAttachShader);
235 OVERRIDE(glCompileShader);
236 OVERRIDE(glShaderBinary);
237 OVERRIDE(glDeleteShader);
238 OVERRIDE(glDetachShader);
239 OVERRIDE(glGetShaderiv);
240 OVERRIDE(glGetShaderInfoLog);
241 OVERRIDE(glGetShaderSource);
242 OVERRIDE(glIsShader);
243 OVERRIDE(glShaderSource);
244 OVERRIDE(glBindAttribLocation);
245 OVERRIDE(glDeleteProgram);
246 OVERRIDE(glDetachShader);
247 OVERRIDE(glGetActiveAttrib);
248 OVERRIDE(glGetActiveUniform);
249 OVERRIDE(glGetAttachedShaders);
250 OVERRIDE(glGetAttribLocation);
251 OVERRIDE(glGetProgramiv);
252 OVERRIDE(glGetProgramInfoLog);
253 OVERRIDE(glGetUniformfv);
254 OVERRIDE(glGetUniformiv);
255 OVERRIDE(glGetUniformLocation);
256 OVERRIDE(glIsProgram);
257 OVERRIDE(glLinkProgram);
258 OVERRIDE(glUseProgram);
259 OVERRIDE(glValidateProgram);
260 OVERRIDE(glGetProgramBinary);
261 OVERRIDE(glProgramBinary);
263 OVERRIDE(glBlendColor);
264 OVERRIDE(glBlendEquation);
265 OVERRIDE(glBlendEquationSeparate);
266 OVERRIDE(glBlendFunc);
267 OVERRIDE(glBlendFuncSeparate);
268 OVERRIDE(glClearColor);
269 OVERRIDE(glClearDepthf);
270 OVERRIDE(glClearStencil);
271 OVERRIDE(glColorMask);
272 OVERRIDE(glCullFace);
273 OVERRIDE(glDepthFunc);
274 OVERRIDE(glDepthMask);
275 OVERRIDE(glDepthRangef);
277 OVERRIDE(glDisableVertexAttribArray);
278 OVERRIDE(glDrawArrays);
279 OVERRIDE(glDrawElements);
281 OVERRIDE(glEnableVertexAttribArray);
282 OVERRIDE(glFrontFace);
283 OVERRIDE(glGetVertexAttribfv);
284 OVERRIDE(glGetVertexAttribiv);
285 OVERRIDE(glGetVertexAttribPointerv);
287 OVERRIDE(glLineWidth);
288 OVERRIDE(glPixelStorei);
289 OVERRIDE(glPolygonOffset);
290 OVERRIDE(glSampleCoverage);
292 OVERRIDE(glStencilFunc);
293 OVERRIDE(glStencilFuncSeparate);
294 OVERRIDE(glStencilMask);
295 OVERRIDE(glStencilMaskSeparate);
296 OVERRIDE(glStencilOp);
297 OVERRIDE(glStencilOpSeparate);
298 OVERRIDE(glVertexAttrib1f);
299 OVERRIDE(glVertexAttrib1fv);
300 OVERRIDE(glVertexAttrib2f);
301 OVERRIDE(glVertexAttrib2fv);
302 OVERRIDE(glVertexAttrib3f);
303 OVERRIDE(glVertexAttrib3fv);
304 OVERRIDE(glVertexAttrib4f);
305 OVERRIDE(glVertexAttrib4fv);
306 OVERRIDE(glVertexAttribPointer);
307 OVERRIDE(glViewport);
309 OVERRIDE(glEGLImageTargetTexture2DOES);
314 LOG("\E[0;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
321 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
325 case GL_OBJECT_TYPE_TEXTURE:
326 return sostate->texture;
327 case GL_OBJECT_TYPE_BUFFER:
328 return sostate->buffer;
329 case GL_OBJECT_TYPE_FRAMEBUFFER:
330 return sostate->framebuffer;
331 case GL_OBJECT_TYPE_RENDERBUFFER:
332 return sostate->renderbuffer;
333 case GL_OBJECT_TYPE_PROGRAM:
334 return sostate->program;
341 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
345 GLContext_List *current = NULL;
346 GLContext_List *newitm = NULL;
348 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
352 tid = get_current_thread();
354 current = glctx_list;
355 while (current != NULL)
357 if (current->option_len == option_len &&
358 memcmp(current->option, option, option_len) == 0 &&
359 current->thread_id == tid)
361 AST(current->cstate == cstate);
364 current = current->next;
367 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
370 ERR("Failed to create context list.\n");
374 newitm->cstate = cstate;
375 newitm->thread_id = tid;
376 newitm->option_len = option_len;
377 newitm->option = (void *)malloc(option_len);
378 memcpy(newitm->option, option, option_len);
380 if (glctx_list != NULL)
381 newitm->next = glctx_list;
402 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
408 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
410 GLContextState *ret = NULL;
411 GLContext_List *current = NULL;
414 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
416 tid = get_current_thread();
418 current = glctx_list;
419 while (current != NULL)
421 if (current->option_len == option_len &&
422 memcmp(current->option, option, option_len) == 0 &&
423 current->thread_id == tid)
425 ret = current->cstate;
428 current = current->next;
433 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
438 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
442 GLContext_List *olditm = NULL;
443 GLContext_List *current = NULL;
445 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
449 tid = get_current_thread();
450 current = glctx_list;
452 while (current != NULL)
454 if (current->cstate == cstate)
456 GLContext_List *nextitm = NULL;
459 olditm->next = current->next;
460 nextitm = olditm->next;
464 glctx_list = current->next;
465 nextitm = glctx_list;
473 current = current->next;
478 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
483 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
485 GL_Object **object = NULL;
486 GLuint ret = _COREGL_INT_INIT_VALUE;
489 object = _get_shared_object(sostate, type);
491 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
493 if (object[i] == NULL)
495 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
496 newobj->id = (int)type + i;
497 newobj->real_id = real_name;
510 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
512 GL_Object **object = NULL;
513 GLuint ret = _COREGL_INT_INIT_VALUE;
514 int hash = _COREGL_INT_INIT_VALUE;
516 object = _get_shared_object(sostate, type);
518 hash = glue_name - (int)type;
520 hash > MAX_GL_OBJECT_SIZE ||
521 object[hash] == NULL ||
522 object[hash]->id != glue_name)
538 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
540 GL_Object **object = NULL;
541 GLuint ret = _COREGL_INT_INIT_VALUE;
542 int hash = _COREGL_INT_INIT_VALUE;
544 object = _get_shared_object(sostate, type);
546 hash = glue_name - (int)type;
548 hash > MAX_GL_OBJECT_SIZE ||
549 object[hash] == NULL ||
550 object[hash]->id != glue_name)
555 ret = object[hash]->real_id;
563 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
565 GL_Object **object = NULL;
566 GLuint ret = _COREGL_INT_INIT_VALUE;
569 object = _get_shared_object(sostate, type);
571 for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
573 if (object[i] != NULL && object[i]->real_id == real_name)
587 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
589 static struct timeval tv_last = { 0, 0 };
591 if (unlikely(trace_state_flag != 1)) return;
595 struct timeval tv_now = { 0, 0 };
596 AST(gettimeofday(&tv_now, NULL) == 0);
597 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
605 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
606 TRACE("\E[0;32;1m State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
607 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
609 #define PRINTF_CHAR_GLenum "%10d"
610 #define PRINTF_CHAR_GLboolean "%10d"
611 #define PRINTF_CHAR_GLint "%10d"
612 #define PRINTF_CHAR_GLsizei "%10u"
613 #define PRINTF_CHAR_GLuint "%10u"
614 #define PRINTF_CHAR_GLuintmask "0x%8X"
616 #define PRINTF_CHAR_GLclampf "%10.6f"
617 #define PRINTF_CHAR_GLfloat "%10.6f"
619 #define PRINTF_CHAR_GLvoidptr "%10p"
621 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
623 #define INITIAL_CTX initial_ctx
624 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
626 TYPE valuedata[SIZE]; \
627 TYPE *value = NULL; \
628 value = valuedata; GET_STMT; value = valuedata; \
629 TRACE("\E[0;37;1m %-30.30s : (\E[0m ", #NAME); \
630 for (int i = 0; i < SIZE; i++) \
634 TRACE("\n %-30.30s ", "");\
638 TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
639 TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
641 TRACE(" \E[0;37;1m)\E[0m\n"); \
643 # include "coregl_fastpath_state.h"
647 TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
657 fastpath_init_context_states(GLGlueContext *ctx)
661 AST(mutex_lock(&init_context_mutex) == 1);
665 ERR("Context NULL\n");
670 AST(ctx->initialized == 0);
671 AST(ctx->sostate != NULL);
673 if (initial_ctx == NULL)
675 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
676 AST(initial_ctx != NULL);
678 //#define FORCE_DEFAULT_VALUE
679 #ifdef FORCE_DEFAULT_VALUE
680 # define INITIAL_CTX initial_ctx
681 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
684 TYPE valuedata[SIZE]; \
685 TYPE *value = NULL; \
686 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
687 value = valuedata; DEFAULT_STMT; value = valuedata; \
688 for (i = 0; i < SIZE; i++) \
690 if (*((char *)(&value[i])) == 0xcc) \
692 memset(&value[i], 0xaa, sizeof(TYPE)); \
693 value = valuedata; DEFAULT_STMT; value = valuedata; \
694 if (*((char *)(&value[i])) == 0xaa) \
696 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
700 initial_ctx->NAME[i] = value[i]; \
703 # include "coregl_fastpath_state.h"
707 # define INITIAL_CTX initial_ctx
708 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
711 value = valuedata; DEFAULT_STMT; value = valuedata; \
715 value = valuedata; FALLBACK_STMT; value = valuedata; \
718 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
722 TYPE valuedata[SIZE]; \
723 TYPE *value = NULL; \
724 memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
727 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
728 for (i = 0; i < SIZE; i++) \
730 if (*((char *)(&value[i])) == 0xcc) \
732 memset(&value[i], 0xaa, sizeof(TYPE)); \
733 SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
734 if (*((char *)(&value[i])) == 0xaa) \
739 ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
744 initial_ctx->NAME[i] = value[i]; \
748 value = valuedata; DEFAULT_STMT; value = valuedata; \
749 for (i = 0; i < SIZE; i++) \
751 if (initial_ctx->NAME[i] != value[i]) \
753 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]); \
758 while (try_step == 2); \
760 # include "coregl_fastpath_state.h"
761 # undef SET_GLUE_VALUE
766 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
768 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]);
770 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
772 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]);
778 #define INITIAL_CTX initial_ctx
779 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT) \
780 for (i = 0; i < SIZE; i++) \
782 ctx->NAME[i] = initial_ctx->NAME[i]; \
784 # include "coregl_fastpath_state.h"
789 ctx->initialized = 1;
794 AST(mutex_unlock(&init_context_mutex) == 1);
799 #ifdef COREGL_USE_MODULE_TRACEPATH
800 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
801 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
805 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
807 unsigned char flag = 0;
810 if (debug_nofp == 1) goto finish;
812 // Return if they're the same
813 if (oldctx == newctx) goto finish;
815 #define STATE_COMPARE(state) \
816 if ((oldctx->state) != (newctx->state))
818 #define STATES_COMPARE(state_ptr, bytes) \
819 if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
822 #ifdef COREGL_USE_MODULE_TRACEPATH
823 static void *trace_hint_glfinish = NULL;
824 trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
825 #endif // COREGL_USE_MODULE_TRACEPATH
829 #ifdef COREGL_USE_MODULE_TRACEPATH
830 tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
831 #endif // COREGL_USE_MODULE_TRACEPATH
833 #ifdef COREGL_USE_MODULE_TRACEPATH
834 static void *trace_hint_bindbuffers = NULL;
835 trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
836 #endif // COREGL_USE_MODULE_TRACEPATH
838 //------------------//
840 flag = oldctx->_bind_flag | newctx->_bind_flag;
843 STATE_COMPARE(gl_array_buffer_binding[0])
845 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
847 STATE_COMPARE(gl_element_array_buffer_binding[0])
849 _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
851 STATE_COMPARE(gl_framebuffer_binding[0])
853 _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
855 STATE_COMPARE(gl_renderbuffer_binding[0])
857 _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
861 #ifdef COREGL_USE_MODULE_TRACEPATH
862 tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
863 #endif // COREGL_USE_MODULE_TRACEPATH
866 //------------------//
869 #ifdef COREGL_USE_MODULE_TRACEPATH
870 static void *trace_hint_enable_states = NULL;
871 trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
872 #endif // COREGL_USE_MODULE_TRACEPATH
874 flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
877 STATE_COMPARE(gl_blend[0])
879 if (newctx->gl_blend[0])
880 _sym_glEnable(GL_BLEND);
882 _sym_glDisable(GL_BLEND);
884 STATE_COMPARE(gl_cull_face[0])
886 if (newctx->gl_cull_face[0])
887 _sym_glEnable(GL_CULL_FACE);
889 _sym_glDisable(GL_CULL_FACE);
891 STATE_COMPARE(gl_depth_test[0])
893 if (newctx->gl_depth_test[0])
894 _sym_glEnable(GL_DEPTH_TEST);
896 _sym_glDisable(GL_DEPTH_TEST);
898 STATE_COMPARE(gl_dither[0])
900 if (newctx->gl_dither[0])
901 _sym_glEnable(GL_DITHER);
903 _sym_glDisable(GL_DITHER);
908 flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
911 STATE_COMPARE(gl_polygon_offset_fill[0])
913 if (newctx->gl_polygon_offset_fill[0])
914 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
916 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
918 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
920 if (newctx->gl_sample_alpha_to_coverage[0])
921 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
923 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
925 STATE_COMPARE(gl_sample_coverage[0])
927 if (newctx->gl_sample_coverage[0])
928 _sym_glEnable(GL_SAMPLE_COVERAGE);
930 _sym_glDisable(GL_SAMPLE_COVERAGE);
932 STATE_COMPARE(gl_scissor_test[0])
934 if (newctx->gl_scissor_test[0])
935 _sym_glEnable(GL_SCISSOR_TEST);
937 _sym_glDisable(GL_SCISSOR_TEST);
939 STATE_COMPARE(gl_stencil_test[0])
941 if (newctx->gl_stencil_test[0])
942 _sym_glEnable(GL_STENCIL_TEST);
944 _sym_glDisable(GL_STENCIL_TEST);
948 #ifdef COREGL_USE_MODULE_TRACEPATH
949 tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
950 #endif // COREGL_USE_MODULE_TRACEPATH
952 //------------------//
954 #ifdef COREGL_USE_MODULE_TRACEPATH
955 static void *trace_hint_clear_viewport = NULL;
956 trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
957 #endif // COREGL_USE_MODULE_TRACEPATH
959 flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
963 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
965 _sym_glViewport(newctx->gl_viewport[0],
966 newctx->gl_viewport[1],
967 newctx->gl_viewport[2],
968 newctx->gl_viewport[3]);
971 STATE_COMPARE(gl_current_program[0])
973 _sym_glUseProgram(newctx->gl_current_program[0]);
975 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
977 _sym_glClearColor(newctx->gl_color_clear_value[0],
978 newctx->gl_color_clear_value[1],
979 newctx->gl_color_clear_value[2],
980 newctx->gl_color_clear_value[3]);
986 flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
989 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
991 _sym_glColorMask(newctx->gl_color_writemask[0],
992 newctx->gl_color_writemask[1],
993 newctx->gl_color_writemask[2],
994 newctx->gl_color_writemask[3]);
996 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
998 _sym_glDepthRangef(newctx->gl_depth_range[0],
999 newctx->gl_depth_range[1]);
1001 STATE_COMPARE(gl_depth_clear_value[0])
1003 _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
1005 STATE_COMPARE(gl_depth_func[0])
1007 _sym_glDepthFunc(newctx->gl_depth_func[0]);
1009 STATE_COMPARE(gl_depth_writemask[0])
1011 _sym_glDepthMask(newctx->gl_depth_writemask[0]);
1013 STATE_COMPARE(gl_cull_face_mode[0])
1015 _sym_glCullFace(newctx->gl_cull_face_mode[0]);
1020 #ifdef COREGL_USE_MODULE_TRACEPATH
1021 tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1022 #endif // COREGL_USE_MODULE_TRACEPATH
1024 //------------------//
1026 #ifdef COREGL_USE_MODULE_TRACEPATH
1027 static void *trace_hint_bind_textures = NULL;
1028 trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1029 #endif // COREGL_USE_MODULE_TRACEPATH
1031 flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1035 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1037 STATE_COMPARE(gl_tex_2d_state[i])
1039 _sym_glActiveTexture(GL_TEXTURE0 + i);
1040 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
1043 STATE_COMPARE(gl_tex_cube_state[i])
1045 _sym_glActiveTexture(GL_TEXTURE0 + i);
1046 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
1050 // Restore active texture
1051 _sym_glActiveTexture(newctx->gl_active_texture[0]);
1053 STATE_COMPARE(gl_generate_mipmap_hint[0])
1055 _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
1058 #ifdef COREGL_USE_MODULE_TRACEPATH
1059 tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1060 #endif // COREGL_USE_MODULE_TRACEPATH
1062 //------------------//
1063 #ifdef COREGL_USE_MODULE_TRACEPATH
1064 static void *trace_hint_etc = NULL;
1065 trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1066 #endif // COREGL_USE_MODULE_TRACEPATH
1068 flag = oldctx->_blend_flag | newctx->_blend_flag;
1071 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1073 _sym_glBlendColor(newctx->gl_blend_color[0],
1074 newctx->gl_blend_color[1],
1075 newctx->gl_blend_color[2],
1076 newctx->gl_blend_color[3]);
1078 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1079 (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1080 (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1081 (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1083 _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1084 newctx->gl_blend_dst_rgb[0],
1085 newctx->gl_blend_src_alpha[0],
1086 newctx->gl_blend_dst_alpha[0]);
1088 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1089 (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1091 _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
1096 //------------------//
1098 flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1101 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1102 (oldctx->gl_stencil_ref[0] != newctx->gl_stencil_ref[0]) ||
1103 (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1105 _sym_glStencilFuncSeparate(GL_FRONT,
1106 newctx->gl_stencil_func[0],
1107 newctx->gl_stencil_ref[0],
1108 newctx->gl_stencil_value_mask[0]);
1110 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1111 (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1112 (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1114 _sym_glStencilOpSeparate(GL_FRONT,
1115 newctx->gl_stencil_fail[0],
1116 newctx->gl_stencil_pass_depth_fail[0],
1117 newctx->gl_stencil_pass_depth_pass[0]);
1120 STATE_COMPARE(gl_stencil_writemask[0])
1122 _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
1128 flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1131 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1132 (oldctx->gl_stencil_back_ref[0] != newctx->gl_stencil_back_ref[0]) ||
1133 (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1135 _sym_glStencilFuncSeparate(GL_BACK,
1136 newctx->gl_stencil_back_func[0],
1137 newctx->gl_stencil_back_ref[0],
1138 newctx->gl_stencil_back_value_mask[0]);
1140 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1141 (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1142 (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1144 _sym_glStencilOpSeparate(GL_BACK,
1145 newctx->gl_stencil_back_fail[0],
1146 newctx->gl_stencil_back_pass_depth_fail[0],
1147 newctx->gl_stencil_back_pass_depth_pass[0]);
1150 STATE_COMPARE(gl_stencil_back_writemask[0])
1152 _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
1154 STATE_COMPARE(gl_stencil_clear_value[0])
1156 _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
1160 //------------------//
1162 flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1165 STATE_COMPARE(gl_front_face[0])
1167 _sym_glFrontFace(newctx->gl_front_face[0]);
1169 STATE_COMPARE(gl_line_width[0])
1171 _sym_glLineWidth(newctx->gl_line_width[0]);
1173 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1174 (oldctx->gl_polygon_offset_units[0] != newctx->gl_polygon_offset_units[0]))
1176 _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1177 newctx->gl_polygon_offset_units[0]);
1179 if ((oldctx->gl_sample_coverage_value[0] != newctx->gl_sample_coverage_value[0]) ||
1180 (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1182 _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1183 newctx->gl_sample_coverage_invert[0]);
1188 flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1191 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1193 _sym_glScissor(newctx->gl_scissor_box[0],
1194 newctx->gl_scissor_box[1],
1195 newctx->gl_scissor_box[2],
1196 newctx->gl_scissor_box[3]);
1198 STATE_COMPARE(gl_pack_alignment[0])
1200 _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
1202 STATE_COMPARE(gl_unpack_alignment[0])
1204 _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
1207 #ifdef COREGL_USE_MODULE_TRACEPATH
1208 tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1209 #endif // COREGL_USE_MODULE_TRACEPATH
1212 #ifdef COREGL_USE_MODULE_TRACEPATH
1213 static void *trace_hint_vertex_attrib = NULL;
1214 trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1215 #endif // COREGL_USE_MODULE_TRACEPATH
1217 flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1220 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1222 if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1224 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
1226 else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
1228 _sym_glVertexAttribPointer(i,
1229 newctx->gl_vertex_array_size[i],
1230 newctx->gl_vertex_array_type[i],
1231 newctx->gl_vertex_array_normalized[i],
1232 newctx->gl_vertex_array_stride[i],
1233 newctx->gl_vertex_array_pointer[i]);
1235 STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1237 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
1240 if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1242 _sym_glEnableVertexAttribArray(i);
1246 _sym_glDisableVertexAttribArray(i);
1250 STATE_COMPARE(gl_array_buffer_binding[0])
1252 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
1254 STATE_COMPARE(gl_element_array_buffer_binding[0])
1256 _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
1261 #ifdef COREGL_USE_MODULE_TRACEPATH
1262 tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1263 #endif // COREGL_USE_MODULE_TRACEPATH
1269 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1270 if (unlikely(trace_state_flag == 1))
1271 fastpath_dump_context_states(newctx, 0);
1272 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1274 #undef STATE_COMPARE
1275 #undef STATES_COMPARE