[Trace] Add 'MAX elapsed time' at API tracing module
[platform/core/uifw/coregl.git] / src / modules / fastpath / coregl_fastpath.c
1 #include "coregl_fastpath.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/time.h>
6
7 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST)     RET_TYPE (*_orig_fastpath_##FUNC_NAME) PARAM_LIST = NULL;
8 #include "../../headers/sym.h"
9 #undef _COREGL_SYMBOL
10
11 Fastpath_Opt_Flag   fp_opt = FP_UNKNOWN_PATH;
12
13 int                 debug_nofp = 0;
14 FILE               *trace_fp = NULL;
15
16 GLenum              FPGL_Error = GL_NO_ERROR;
17
18 GLGlueContext_List *gctx_list = NULL;
19
20 Mutex               init_context_mutex = MUTEX_INITIALIZER;
21 GLGlueContext      *initial_ctx = NULL;
22
23 Mutex               ctx_list_access_mutex = MUTEX_INITIALIZER;
24
25 GLContext_List     *glctx_list = NULL;
26
27 static void
28 _get_texture_states(GLenum pname, GLint *params)
29 {
30         GLuint cur_active_tex = 0;
31
32         AST(initial_ctx != NULL);
33
34         _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
35         int i;
36         for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++)
37         {
38                 _sym_glActiveTexture(GL_TEXTURE0 + i);
39                 _sym_glGetIntegerv(pname, &(((GLint *)params)[i]));
40         }
41         _sym_glActiveTexture(cur_active_tex);
42 }
43
44 static GLuint
45 _get_stencil_max_mask()
46 {
47         GLuint stencil_bit = 0;
48
49         _sym_glGetIntegerv(GL_STENCIL_BITS, (GLint *)&stencil_bit);
50         return (1 << stencil_bit) - 1;
51 }
52
53 void
54 init_modules_fastpath()
55 {
56         int fastpath_opt = 0;
57
58         LOG("[CoreGL] <Fastpath> : ");
59
60         fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
61
62         switch (fastpath_opt)
63         {
64                 case 1:
65                         LOG("(%d) Fastpath enabled...\n", fastpath_opt);
66                         fp_opt = FP_FAST_PATH;
67                         break;
68                 default:
69                         LOG("(%d) Default API path enabled...\n", fastpath_opt);
70                         fp_opt = FP_NORMAL_PATH;
71                         break;
72         }
73
74         debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
75
76         fastpath_apply_overrides();
77
78 }
79
80 void
81 deinit_modules_fastpath()
82 {
83         GLContext_List *current = NULL;
84
85         AST(mutex_lock(&ctx_list_access_mutex) == 1);
86
87         // Destroy remained context & Detect leaks
88         int retry_destroy = 0;
89
90         while (1)
91         {
92                 retry_destroy = 0;
93                 current = glctx_list;
94                 while (current)
95                 {
96                         if (current->cstate != NULL)
97                         {
98                                 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);
99
100                                 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
101                                 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
102
103                                 fastpath_remove_context_states_from_list(current->cstate, NULL);
104                                 retry_destroy = 1;
105                                 break;
106                         }
107
108                         glctx_list = current->next;
109                         free(current);
110                         current = glctx_list;
111                 }
112                 if (retry_destroy == 0) break;
113         }
114         goto finish;
115
116 finish:
117         AST(mutex_unlock(&ctx_list_access_mutex) == 1);
118 }
119
120 void
121 init_modules_tstate_fastpath(GLThreadState *tstate)
122 {
123         MY_MODULE_TSTATE *tstate_mt = NULL;
124
125         tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
126
127         tstate_mt->binded_api = EGL_OPENGL_ES_API;
128
129         tstate->module_data[MY_MODULE_ID] = tstate_mt;
130 }
131
132 void
133 deinit_modules_tstate_fastpath(GLThreadState *tstate)
134 {
135         if (tstate->module_data[MY_MODULE_ID] != NULL)
136         {
137                 free(tstate->module_data[MY_MODULE_ID]);
138                 tstate->module_data[MY_MODULE_ID] = NULL;
139         }
140 }
141
142 void
143 fastpath_apply_overrides()
144 {
145         switch(fp_opt)
146         {
147                 case FP_FAST_PATH:
148                         fastpath_apply_overrides_egl(1);
149                         fastpath_apply_overrides_gl(1);
150                         break;
151                 case FP_NORMAL_PATH:
152                         break;
153                 default:
154                         ERR("Invalide GL Override Option!!!\n");
155                         break;
156         }
157 }
158
159 #define OVERRIDE(f) \
160         if (enable == 1) \
161         { \
162                 COREGL_OVERRIDE_API(_orig_fastpath_, f, ovr_); \
163                 COREGL_OVERRIDE_API(ovr_, f, fastpath_); \
164         } \
165         else \
166         { \
167                 AST(ovr_##f != NULL); \
168                 COREGL_OVERRIDE_API(ovr_, f, _orig_fastpath_); \
169                 _orig_fastpath_##f = NULL; \
170         }
171
172 void
173 fastpath_apply_overrides_egl(int enable)
174 {
175         // Fast-Path Core Functions
176         OVERRIDE(eglGetProcAddress);
177
178         OVERRIDE(eglBindAPI);
179         OVERRIDE(eglQueryAPI);
180
181         OVERRIDE(eglCreateContext);
182         OVERRIDE(eglCreateImageKHR);
183         OVERRIDE(eglMakeCurrent);
184         OVERRIDE(eglDestroyContext);
185         OVERRIDE(eglQueryContext);
186         OVERRIDE(eglGetCurrentContext);
187         OVERRIDE(eglReleaseThread);
188         OVERRIDE(eglGetCurrentSurface);
189         OVERRIDE(eglTerminate);
190
191 }
192
193 void
194 fastpath_apply_overrides_gl(int enable)
195 {
196         // Fast-Path Functions
197         if (debug_nofp != 1)
198         {
199                 OVERRIDE(glGetError);
200
201                 OVERRIDE(glGetIntegerv);
202                 OVERRIDE(glGetFloatv);
203                 OVERRIDE(glGetBooleanv);
204
205                 OVERRIDE(glActiveTexture);
206                 OVERRIDE(glGenTextures);
207                 OVERRIDE(glBindTexture);
208                 OVERRIDE(glIsTexture);
209                 OVERRIDE(glDeleteTextures);
210                 OVERRIDE(glFramebufferTexture2D);
211                 OVERRIDE(glFramebufferTexture2DMultisampleEXT);
212
213                 OVERRIDE(glGenBuffers);
214                 OVERRIDE(glBindBuffer);
215                 OVERRIDE(glIsBuffer);
216                 OVERRIDE(glDeleteBuffers);
217
218                 OVERRIDE(glGenFramebuffers);
219                 OVERRIDE(glBindFramebuffer);
220                 OVERRIDE(glIsFramebuffer);
221                 OVERRIDE(glDeleteFramebuffers);
222
223                 OVERRIDE(glGenRenderbuffers);
224                 OVERRIDE(glBindRenderbuffer);
225                 OVERRIDE(glFramebufferRenderbuffer);
226                 OVERRIDE(glIsRenderbuffer);
227                 OVERRIDE(glDeleteRenderbuffers);
228
229                 OVERRIDE(glCreateShader);
230                 OVERRIDE(glCreateProgram);
231                 OVERRIDE(glAttachShader);
232                 OVERRIDE(glCompileShader);
233                 OVERRIDE(glShaderBinary);
234                 OVERRIDE(glDeleteShader);
235                 OVERRIDE(glDetachShader);
236                 OVERRIDE(glGetShaderiv);
237                 OVERRIDE(glGetShaderInfoLog);
238                 OVERRIDE(glGetShaderSource);
239                 OVERRIDE(glIsShader);
240                 OVERRIDE(glShaderSource);
241                 OVERRIDE(glBindAttribLocation);
242                 OVERRIDE(glDeleteProgram);
243                 OVERRIDE(glDetachShader);
244                 OVERRIDE(glGetActiveAttrib);
245                 OVERRIDE(glGetActiveUniform);
246                 OVERRIDE(glGetAttachedShaders);
247                 OVERRIDE(glGetAttribLocation);
248                 OVERRIDE(glGetProgramiv);
249                 OVERRIDE(glGetProgramInfoLog);
250                 OVERRIDE(glGetUniformfv);
251                 OVERRIDE(glGetUniformiv);
252                 OVERRIDE(glGetUniformLocation);
253                 OVERRIDE(glIsProgram);
254                 OVERRIDE(glLinkProgram);
255                 OVERRIDE(glUseProgram);
256                 OVERRIDE(glValidateProgram);
257                 OVERRIDE(glGetProgramBinary);
258                 OVERRIDE(glProgramBinary);
259
260                 OVERRIDE(glBlendColor);
261                 OVERRIDE(glBlendEquation);
262                 OVERRIDE(glBlendEquationSeparate);
263                 OVERRIDE(glBlendFunc);
264                 OVERRIDE(glBlendFuncSeparate);
265                 OVERRIDE(glClearColor);
266                 OVERRIDE(glClearDepthf);
267                 OVERRIDE(glClearStencil);
268                 OVERRIDE(glColorMask);
269                 OVERRIDE(glCullFace);
270                 OVERRIDE(glDepthFunc);
271                 OVERRIDE(glDepthMask);
272                 OVERRIDE(glDepthRangef);
273                 OVERRIDE(glDisable);
274                 OVERRIDE(glDisableVertexAttribArray);
275                 OVERRIDE(glDrawArrays);
276                 OVERRIDE(glDrawElements);
277                 OVERRIDE(glEnable);
278                 OVERRIDE(glEnableVertexAttribArray);
279                 OVERRIDE(glFrontFace);
280                 OVERRIDE(glGetVertexAttribfv);
281                 OVERRIDE(glGetVertexAttribiv);
282                 OVERRIDE(glGetVertexAttribPointerv);
283                 OVERRIDE(glHint);
284                 OVERRIDE(glLineWidth);
285                 OVERRIDE(glPixelStorei);
286                 OVERRIDE(glPolygonOffset);
287                 OVERRIDE(glSampleCoverage);
288                 OVERRIDE(glScissor);
289                 OVERRIDE(glStencilFunc);
290                 OVERRIDE(glStencilFuncSeparate);
291                 OVERRIDE(glStencilMask);
292                 OVERRIDE(glStencilMaskSeparate);
293                 OVERRIDE(glStencilOp);
294                 OVERRIDE(glStencilOpSeparate);
295                 OVERRIDE(glVertexAttrib1f);
296                 OVERRIDE(glVertexAttrib1fv);
297                 OVERRIDE(glVertexAttrib2f);
298                 OVERRIDE(glVertexAttrib2fv);
299                 OVERRIDE(glVertexAttrib3f);
300                 OVERRIDE(glVertexAttrib3fv);
301                 OVERRIDE(glVertexAttrib4f);
302                 OVERRIDE(glVertexAttrib4fv);
303                 OVERRIDE(glVertexAttribPointer);
304                 OVERRIDE(glViewport);
305
306                 OVERRIDE(glEGLImageTargetTexture2DOES);
307
308         }
309         else
310         {
311                 LOG("\E[0;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
312         }
313 }
314
315 #undef OVERRIDE
316
317 static GL_Object **
318 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
319 {
320         switch (type)
321         {
322                 case GL_OBJECT_TYPE_TEXTURE:
323                         return sostate->texture;
324                 case GL_OBJECT_TYPE_BUFFER:
325                         return sostate->buffer;
326                 case GL_OBJECT_TYPE_FRAMEBUFFER:
327                         return sostate->framebuffer;
328                 case GL_OBJECT_TYPE_RENDERBUFFER:
329                         return sostate->renderbuffer;
330                 case GL_OBJECT_TYPE_PROGRAM:
331                         return sostate->program;
332                 default:
333                         return NULL;
334         }
335 }
336
337 int
338 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
339 {
340         int ret = 0;
341         int tid = 0;
342         GLContext_List *current = NULL;
343         GLContext_List *newitm = NULL;
344
345         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
346
347         AST(cstate != NULL);
348
349         tid = get_current_thread();
350
351         current = glctx_list;
352         while (current != NULL)
353         {
354                 if (current->option_len == option_len &&
355                     memcmp(current->option, option, option_len) == 0 &&
356                     current->thread_id == tid)
357                 {
358                         AST(current->cstate == cstate);
359                         goto finish;
360                 }
361                 current = current->next;
362         }
363
364         newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
365         if (newitm == NULL)
366         {
367                 ERR("Failed to create context list.\n");
368                 goto finish;
369         }
370
371         newitm->cstate = cstate;
372         newitm->thread_id = tid;
373         newitm->option_len = option_len;
374         newitm->option = (void *)malloc(option_len);
375         memcpy(newitm->option, option, option_len);
376
377         if (glctx_list != NULL)
378                 newitm->next = glctx_list;
379
380         glctx_list = newitm;
381
382         ret = 1;
383         goto finish;
384
385 finish:
386         if (ret != 1)
387         {
388                 if (newitm != NULL)
389                 {
390                         free(newitm);
391                         newitm = NULL;
392                 }
393                 if (cstate != NULL)
394                 {
395                         free(cstate);
396                         cstate = NULL;
397                 }
398         }
399         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
400
401         return ret;
402 }
403
404 GLContextState *
405 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
406 {
407         GLContextState *ret = NULL;
408         GLContext_List *current = NULL;
409         int tid = 0;
410
411         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
412
413         tid = get_current_thread();
414
415         current = glctx_list;
416         while (current != NULL)
417         {
418                 if (current->option_len == option_len &&
419                     memcmp(current->option, option, option_len) == 0 &&
420                     current->thread_id == tid)
421                 {
422                         ret = current->cstate;
423                         goto finish;
424                 }
425                 current = current->next;
426         }
427         goto finish;
428
429 finish:
430         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
431         return ret;
432 }
433
434 int
435 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
436 {
437         int ret = 0;
438         int tid = 0;
439         GLContext_List *olditm = NULL;
440         GLContext_List *current = NULL;
441
442         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
443
444         AST(cstate != NULL);
445
446         tid = get_current_thread();
447         current = glctx_list;
448
449         while (current != NULL)
450         {
451                 if (current->cstate == cstate)
452                 {
453                         GLContext_List *nextitm = NULL;
454                         if (olditm != NULL)
455                         {
456                                 olditm->next = current->next;
457                                 nextitm = olditm->next;
458                         }
459                         else
460                         {
461                                 glctx_list = current->next;
462                                 nextitm = glctx_list;
463                         }
464                         free(current);
465                         ret = 1;
466                         current = nextitm;
467                         continue;
468                 }
469                 olditm = current;
470                 current = current->next;
471         }
472         goto finish;
473
474 finish:
475         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
476         return ret;
477 }
478
479 GLuint
480 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
481 {
482         GL_Object **object = NULL;
483         GLuint ret = _COREGL_INT_INIT_VALUE;
484         int i;
485
486         object = _get_shared_object(sostate, type);
487
488         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
489         {
490                 if (object[i] == NULL)
491                 {
492                         GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
493                         newobj->id = (int)type + i;
494                         newobj->real_id = real_name;
495                         object[i] = newobj;
496                         ret = newobj->id;
497                         goto finish;
498                 }
499         }
500         goto finish;
501
502 finish:
503         return ret;
504 }
505
506 GLuint
507 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
508 {
509         GL_Object **object = NULL;
510         GLuint ret = _COREGL_INT_INIT_VALUE;
511         int hash = _COREGL_INT_INIT_VALUE;
512
513         object = _get_shared_object(sostate, type);
514
515         hash = glue_name - (int)type;
516         if (hash < 0 ||
517             hash > MAX_GL_OBJECT_SIZE ||
518             object[hash] == NULL ||
519             object[hash]->id != glue_name)
520         {
521                 ret = 0;
522                 goto finish;
523         }
524
525         free(object[hash]);
526         object[hash] = NULL;
527         ret = 1;
528         goto finish;
529
530 finish:
531         return ret;
532 }
533
534 GLuint
535 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
536 {
537         GL_Object **object = NULL;
538         GLuint ret = _COREGL_INT_INIT_VALUE;
539         int hash = _COREGL_INT_INIT_VALUE;
540
541         object = _get_shared_object(sostate, type);
542
543         hash = glue_name - (int)type;
544         if (hash < 0 ||
545             hash > MAX_GL_OBJECT_SIZE ||
546             object[hash] == NULL ||
547             object[hash]->id != glue_name)
548         {
549                 ret = 0;
550                 goto finish;
551         }
552         ret = object[hash]->real_id;
553         goto finish;
554
555 finish:
556         return ret;
557 }
558
559 GLuint
560 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
561 {
562         GL_Object **object = NULL;
563         GLuint ret = _COREGL_INT_INIT_VALUE;
564         int i;
565
566         object = _get_shared_object(sostate, type);
567
568         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
569         {
570                 if (object[i] != NULL && object[i]->real_id == real_name)
571                 {
572                         ret = object[i]->id;
573                         goto finish;
574                 }
575         }
576         ret = 0;
577         goto finish;
578
579 finish:
580         return ret;
581 }
582
583 void
584 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
585 {
586         static struct timeval tv_last = { 0, 0 };
587
588         if (unlikely(trace_state_flag != 1)) return;
589
590         if (!force_output)
591         {
592                 struct timeval tv_now = { 0, 0 };
593                 AST(gettimeofday(&tv_now, NULL) == 0);
594                 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
595                 {
596                         goto finish;
597                 }
598                 tv_last = tv_now;
599         }
600
601         TRACE("\n");
602         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
603         TRACE("\E[0;32;1m  State info \E[1;37;1m: GlueCTX = %p\E[0m\n", ctx);
604         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
605
606 #define PRINTF_CHAR_GLenum "%10d"
607 #define PRINTF_CHAR_GLboolean "%10d"
608 #define PRINTF_CHAR_GLint "%10d"
609 #define PRINTF_CHAR_GLsizei "%10u"
610 #define PRINTF_CHAR_GLuint "%10u"
611 #define PRINTF_CHAR_GLuintmask "0x%8X"
612
613 #define PRINTF_CHAR_GLclampf "%10.6f"
614 #define PRINTF_CHAR_GLfloat "%10.6f"
615
616 #define PRINTF_CHAR_GLvoidptr "%10p"
617
618 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
619
620 #define INITIAL_CTX initial_ctx
621 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
622    { \
623       TYPE valuedata[SIZE]; \
624       TYPE *value = NULL; \
625       value = valuedata; GET_STMT; value = valuedata; \
626       TRACE("\E[0;37;1m %-30.30s : (\E[0m ", #NAME); \
627       for (int i = 0; i < SIZE; i++) \
628       { \
629          if (i > 0) { \
630             if (i % 4 == 0) \
631                TRACE("\n %-30.30s     ", "");\
632             else \
633                TRACE(", "); \
634          } \
635          TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
636          TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
637       } \
638       TRACE(" \E[0;37;1m)\E[0m\n"); \
639    }
640 # include "coregl_fastpath_state.h"
641 #undef GLUE_STATE
642 #undef INITIAL_CTX
643
644         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
645         TRACE("\n");
646
647         TRACE_END();
648
649 finish:
650         return;
651 }
652
653 int
654 fastpath_init_context_states(GLGlueContext *ctx)
655 {
656         int ret = 0;
657
658         AST(mutex_lock(&init_context_mutex) == 1);
659
660         if (ctx == NULL)
661         {
662                 ERR("Context NULL\n");
663                 ret = 0;
664                 goto finish;
665         }
666
667         AST(ctx->initialized == 0);
668         AST(ctx->sostate != NULL);
669
670         if (initial_ctx == NULL)
671         {
672                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
673                 AST(initial_ctx != NULL);
674
675 //#define FORCE_DEFAULT_VALUE
676 #ifdef FORCE_DEFAULT_VALUE
677 # define INITIAL_CTX initial_ctx
678 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
679       { \
680          int i; \
681          TYPE valuedata[SIZE]; \
682          TYPE *value = NULL; \
683          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
684          value = valuedata; DEFAULT_STMT; value = valuedata; \
685          for (i = 0; i < SIZE; i++) \
686          { \
687             if (*((char *)(&value[i])) == 0xcc) \
688             { \
689                memset(&value[i], 0xaa, sizeof(TYPE)); \
690                value = valuedata; DEFAULT_STMT; value = valuedata; \
691                if (*((char *)(&value[i])) == 0xaa) \
692                { \
693                   ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
694                   break; \
695                } \
696             } \
697             initial_ctx->NAME[i] = value[i]; \
698          } \
699       }
700 #  include "coregl_fastpath_state.h"
701 # undef GLUE_STATE
702 # undef INITIAL_CTX
703 #else
704 # define INITIAL_CTX initial_ctx
705 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
706       if (try_step == 1) \
707       { \
708          value = valuedata; DEFAULT_STMT; value = valuedata; \
709       } \
710       else \
711       { \
712          value = valuedata; FALLBACK_STMT; value = valuedata; \
713       }
714
715 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
716       { \
717          int i; \
718          int try_step = 0;\
719          TYPE valuedata[SIZE]; \
720          TYPE *value = NULL; \
721          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
722          do { \
723             try_step++; \
724             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
725             for (i = 0; i < SIZE; i++) \
726             { \
727                if (*((char *)(&value[i])) == 0xcc) \
728                { \
729                   memset(&value[i], 0xaa, sizeof(TYPE)); \
730                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
731                   if (*((char *)(&value[i])) == 0xaa) \
732                   { \
733                      try_step++; \
734                      if (try_step == 2) \
735                      { \
736                         ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
737                      } \
738                      break; \
739                   } \
740                } \
741                initial_ctx->NAME[i] = value[i]; \
742             } \
743             if (try_step != 2) \
744             { \
745                value = valuedata; DEFAULT_STMT; value = valuedata; \
746                for (i = 0; i < SIZE; i++) \
747                { \
748                   if (initial_ctx->NAME[i] != value[i]) \
749                   { \
750                      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]); \
751                   } \
752                } \
753             } \
754          } \
755          while (try_step == 2); \
756       }
757 #  include "coregl_fastpath_state.h"
758 # undef SET_GLUE_VALUE
759 # undef GLUE_STATE
760 # undef INITIAL_CTX
761 #endif
762
763                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
764                 {
765                         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]);
766                 }
767                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
768                 {
769                         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]);
770                 }
771         }
772
773         {
774                 int i;
775 #define INITIAL_CTX initial_ctx
776 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
777          for (i = 0; i < SIZE; i++) \
778          { \
779             ctx->NAME[i] = initial_ctx->NAME[i]; \
780          }
781 # include "coregl_fastpath_state.h"
782 #undef GLUE_STATE
783 #undef INITIAL_CTX
784         }
785
786         ctx->initialized = 1;
787         ret = 1;
788         goto finish;
789
790 finish:
791         AST(mutex_unlock(&init_context_mutex) == 1);
792
793         return ret;
794 }
795
796 #ifdef COREGL_USE_MODULE_TRACEPATH
797 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
798 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
799 #endif
800
801 void
802 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
803 {
804         unsigned char flag = 0;
805         int i = 0;
806
807         if (debug_nofp == 1) goto finish;
808
809         // Return if they're the same
810         if (oldctx == newctx) goto finish;
811
812 #define STATE_COMPARE(state) \
813    if ((oldctx->state) != (newctx->state))
814
815 #define STATES_COMPARE(state_ptr, bytes) \
816    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
817
818
819 #ifdef COREGL_USE_MODULE_TRACEPATH
820         static void *trace_hint_glfinish = NULL;
821         trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
822 #endif // COREGL_USE_MODULE_TRACEPATH
823
824         _sym_glFlush();
825
826 #ifdef COREGL_USE_MODULE_TRACEPATH
827         tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
828 #endif // COREGL_USE_MODULE_TRACEPATH
829
830 #ifdef COREGL_USE_MODULE_TRACEPATH
831         static void *trace_hint_bindbuffers = NULL;
832         trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
833 #endif // COREGL_USE_MODULE_TRACEPATH
834
835         //------------------//
836         // _bind_flag
837         flag = oldctx->_bind_flag | newctx->_bind_flag;
838         if (flag)
839         {
840                 STATE_COMPARE(gl_array_buffer_binding[0])
841                 {
842                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
843                 }
844                 STATE_COMPARE(gl_element_array_buffer_binding[0])
845                 {
846                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
847                 }
848                 STATE_COMPARE(gl_framebuffer_binding[0])
849                 {
850                         _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
851                 }
852                 STATE_COMPARE(gl_renderbuffer_binding[0])
853                 {
854                         _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
855                 }
856         }
857
858 #ifdef COREGL_USE_MODULE_TRACEPATH
859         tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
860 #endif // COREGL_USE_MODULE_TRACEPATH
861
862
863         //------------------//
864         // Enable States
865         // _enable_flag1
866 #ifdef COREGL_USE_MODULE_TRACEPATH
867         static void *trace_hint_enable_states = NULL;
868         trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
869 #endif // COREGL_USE_MODULE_TRACEPATH
870
871         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
872         if (flag)
873         {
874                 STATE_COMPARE(gl_blend[0])
875                 {
876                         if (newctx->gl_blend[0])
877                                 _sym_glEnable(GL_BLEND);
878                         else
879                                 _sym_glDisable(GL_BLEND);
880                 }
881                 STATE_COMPARE(gl_cull_face[0])
882                 {
883                         if (newctx->gl_cull_face[0])
884                                 _sym_glEnable(GL_CULL_FACE);
885                         else
886                                 _sym_glDisable(GL_CULL_FACE);
887                 }
888                 STATE_COMPARE(gl_depth_test[0])
889                 {
890                         if (newctx->gl_depth_test[0])
891                                 _sym_glEnable(GL_DEPTH_TEST);
892                         else
893                                 _sym_glDisable(GL_DEPTH_TEST);
894                 }
895                 STATE_COMPARE(gl_dither[0])
896                 {
897                         if (newctx->gl_dither[0])
898                                 _sym_glEnable(GL_DITHER);
899                         else
900                                 _sym_glDisable(GL_DITHER);
901                 }
902         }
903
904         // _enable_flag2
905         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
906         if (flag)
907         {
908                 STATE_COMPARE(gl_polygon_offset_fill[0])
909                 {
910                         if (newctx->gl_polygon_offset_fill[0])
911                                 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
912                         else
913                                 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
914                 }
915                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
916                 {
917                         if (newctx->gl_sample_alpha_to_coverage[0])
918                                 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
919                         else
920                                 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
921                 }
922                 STATE_COMPARE(gl_sample_coverage[0])
923                 {
924                         if (newctx->gl_sample_coverage[0])
925                                 _sym_glEnable(GL_SAMPLE_COVERAGE);
926                         else
927                                 _sym_glDisable(GL_SAMPLE_COVERAGE);
928                 }
929                 STATE_COMPARE(gl_scissor_test[0])
930                 {
931                         if (newctx->gl_scissor_test[0])
932                                 _sym_glEnable(GL_SCISSOR_TEST);
933                         else
934                                 _sym_glDisable(GL_SCISSOR_TEST);
935                 }
936                 STATE_COMPARE(gl_stencil_test[0])
937                 {
938                         if (newctx->gl_stencil_test[0])
939                                 _sym_glEnable(GL_STENCIL_TEST);
940                         else
941                                 _sym_glDisable(GL_STENCIL_TEST);
942                 }
943         }
944
945 #ifdef COREGL_USE_MODULE_TRACEPATH
946         tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
947 #endif // COREGL_USE_MODULE_TRACEPATH
948
949         //------------------//
950         // _clear_flag1
951 #ifdef COREGL_USE_MODULE_TRACEPATH
952         static void *trace_hint_clear_viewport = NULL;
953         trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
954 #endif // COREGL_USE_MODULE_TRACEPATH
955
956         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
957         if (flag)
958         {
959                 // Viewport.
960                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
961                 {
962                         _sym_glViewport(newctx->gl_viewport[0],
963                                         newctx->gl_viewport[1],
964                                         newctx->gl_viewport[2],
965                                         newctx->gl_viewport[3]);
966                 }
967
968                 STATE_COMPARE(gl_current_program[0])
969                 {
970                         _sym_glUseProgram(newctx->gl_current_program[0]);
971                 }
972                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
973                 {
974                         _sym_glClearColor(newctx->gl_color_clear_value[0],
975                                           newctx->gl_color_clear_value[1],
976                                           newctx->gl_color_clear_value[2],
977                                           newctx->gl_color_clear_value[3]);
978                 }
979         }
980
981
982         // _clear_flag2
983         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
984         if (flag)
985         {
986                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
987                 {
988                         _sym_glColorMask(newctx->gl_color_writemask[0],
989                                          newctx->gl_color_writemask[1],
990                                          newctx->gl_color_writemask[2],
991                                          newctx->gl_color_writemask[3]);
992                 }
993                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
994                 {
995                         _sym_glDepthRangef(newctx->gl_depth_range[0],
996                                            newctx->gl_depth_range[1]);
997                 }
998                 STATE_COMPARE(gl_depth_clear_value[0])
999                 {
1000                         _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
1001                 }
1002                 STATE_COMPARE(gl_depth_func[0])
1003                 {
1004                         _sym_glDepthFunc(newctx->gl_depth_func[0]);
1005                 }
1006                 STATE_COMPARE(gl_depth_writemask[0])
1007                 {
1008                         _sym_glDepthMask(newctx->gl_depth_writemask[0]);
1009                 }
1010                 STATE_COMPARE(gl_cull_face_mode[0])
1011                 {
1012                         _sym_glCullFace(newctx->gl_cull_face_mode[0]);
1013                 }
1014
1015         }
1016
1017 #ifdef COREGL_USE_MODULE_TRACEPATH
1018         tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1019 #endif // COREGL_USE_MODULE_TRACEPATH
1020
1021         //------------------//
1022         // Texture here...
1023 #ifdef COREGL_USE_MODULE_TRACEPATH
1024         static void *trace_hint_bind_textures = NULL;
1025         trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1026 #endif // COREGL_USE_MODULE_TRACEPATH
1027
1028         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1029         if (flag)
1030         {
1031
1032                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1033                 {
1034                         STATE_COMPARE(gl_tex_2d_state[i])
1035                         {
1036                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
1037                                 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
1038                         }
1039
1040                         STATE_COMPARE(gl_tex_cube_state[i])
1041                         {
1042                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
1043                                 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
1044                         }
1045                 }
1046
1047                 // Restore active texture
1048                 _sym_glActiveTexture(newctx->gl_active_texture[0]);
1049
1050                 STATE_COMPARE(gl_generate_mipmap_hint[0])
1051                 {
1052                         _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
1053                 }
1054         }
1055 #ifdef COREGL_USE_MODULE_TRACEPATH
1056         tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1057 #endif // COREGL_USE_MODULE_TRACEPATH
1058
1059         //------------------//
1060 #ifdef COREGL_USE_MODULE_TRACEPATH
1061         static void *trace_hint_etc = NULL;
1062         trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1063 #endif // COREGL_USE_MODULE_TRACEPATH
1064
1065         flag = oldctx->_blend_flag | newctx->_blend_flag;
1066         if (flag)
1067         {
1068                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1069                 {
1070                         _sym_glBlendColor(newctx->gl_blend_color[0],
1071                                           newctx->gl_blend_color[1],
1072                                           newctx->gl_blend_color[2],
1073                                           newctx->gl_blend_color[3]);
1074                 }
1075                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1076                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1077                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1078                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1079                 {
1080                         _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1081                                                  newctx->gl_blend_dst_rgb[0],
1082                                                  newctx->gl_blend_src_alpha[0],
1083                                                  newctx->gl_blend_dst_alpha[0]);
1084                 }
1085                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1086                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1087                 {
1088                         _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
1089                 }
1090
1091         }
1092
1093         //------------------//
1094         // _stencil_flag1
1095         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1096         if (flag)
1097         {
1098                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1099                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
1100                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1101                 {
1102                         _sym_glStencilFuncSeparate(GL_FRONT,
1103                                                    newctx->gl_stencil_func[0],
1104                                                    newctx->gl_stencil_ref[0],
1105                                                    newctx->gl_stencil_value_mask[0]);
1106                 }
1107                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1108                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1109                     (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1110                 {
1111                         _sym_glStencilOpSeparate(GL_FRONT,
1112                                                  newctx->gl_stencil_fail[0],
1113                                                  newctx->gl_stencil_pass_depth_fail[0],
1114                                                  newctx->gl_stencil_pass_depth_pass[0]);
1115                 }
1116
1117                 STATE_COMPARE(gl_stencil_writemask[0])
1118                 {
1119                         _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
1120                 }
1121         }
1122
1123
1124         // _stencil_flag1
1125         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1126         if (flag)
1127         {
1128                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1129                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
1130                     (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1131                 {
1132                         _sym_glStencilFuncSeparate(GL_BACK,
1133                                                    newctx->gl_stencil_back_func[0],
1134                                                    newctx->gl_stencil_back_ref[0],
1135                                                    newctx->gl_stencil_back_value_mask[0]);
1136                 }
1137                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1138                     (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1139                     (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1140                 {
1141                         _sym_glStencilOpSeparate(GL_BACK,
1142                                                  newctx->gl_stencil_back_fail[0],
1143                                                  newctx->gl_stencil_back_pass_depth_fail[0],
1144                                                  newctx->gl_stencil_back_pass_depth_pass[0]);
1145                 }
1146
1147                 STATE_COMPARE(gl_stencil_back_writemask[0])
1148                 {
1149                         _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
1150                 }
1151                 STATE_COMPARE(gl_stencil_clear_value[0])
1152                 {
1153                         _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
1154                 }
1155         }
1156
1157         //------------------//
1158         // _misc_flag1
1159         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1160         if (flag)
1161         {
1162                 STATE_COMPARE(gl_front_face[0])
1163                 {
1164                         _sym_glFrontFace(newctx->gl_front_face[0]);
1165                 }
1166                 STATE_COMPARE(gl_line_width[0])
1167                 {
1168                         _sym_glLineWidth(newctx->gl_line_width[0]);
1169                 }
1170                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1171                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0]))
1172                 {
1173                         _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1174                                              newctx->gl_polygon_offset_units[0]);
1175                 }
1176                 if ((oldctx->gl_sample_coverage_value[0]  != newctx->gl_sample_coverage_value[0]) ||
1177                     (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1178                 {
1179                         _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1180                                               newctx->gl_sample_coverage_invert[0]);
1181                 }
1182         }
1183
1184         // _misc_flag2
1185         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1186         if (flag)
1187         {
1188                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1189                 {
1190                         _sym_glScissor(newctx->gl_scissor_box[0],
1191                                        newctx->gl_scissor_box[1],
1192                                        newctx->gl_scissor_box[2],
1193                                        newctx->gl_scissor_box[3]);
1194                 }
1195                 STATE_COMPARE(gl_pack_alignment[0])
1196                 {
1197                         _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
1198                 }
1199                 STATE_COMPARE(gl_unpack_alignment[0])
1200                 {
1201                         _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
1202                 }
1203         }
1204 #ifdef COREGL_USE_MODULE_TRACEPATH
1205         tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1206 #endif // COREGL_USE_MODULE_TRACEPATH
1207
1208         // _varray_flag
1209 #ifdef COREGL_USE_MODULE_TRACEPATH
1210         static void *trace_hint_vertex_attrib = NULL;
1211         trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1212 #endif // COREGL_USE_MODULE_TRACEPATH
1213
1214         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1215         if (flag)
1216         {
1217                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1218                 {
1219                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1220                         {
1221                                 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
1222                         }
1223                         else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
1224
1225                         _sym_glVertexAttribPointer(i,
1226                                                    newctx->gl_vertex_array_size[i],
1227                                                    newctx->gl_vertex_array_type[i],
1228                                                    newctx->gl_vertex_array_normalized[i],
1229                                                    newctx->gl_vertex_array_stride[i],
1230                                                    newctx->gl_vertex_array_pointer[i]);
1231
1232                         STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1233                         {
1234                                 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
1235                         }
1236
1237                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1238                         {
1239                                 _sym_glEnableVertexAttribArray(i);
1240                         }
1241                         else
1242                         {
1243                                 _sym_glDisableVertexAttribArray(i);
1244                         }
1245                 }
1246
1247                 STATE_COMPARE(gl_array_buffer_binding[0])
1248                 {
1249                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
1250                 }
1251                 STATE_COMPARE(gl_element_array_buffer_binding[0])
1252                 {
1253                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
1254                 }
1255
1256         }
1257
1258 #ifdef COREGL_USE_MODULE_TRACEPATH
1259         tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1260 #endif // COREGL_USE_MODULE_TRACEPATH
1261
1262         goto finish;
1263
1264 finish:
1265
1266 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1267         if (unlikely(trace_state_flag == 1))
1268                 fastpath_dump_context_states(newctx, 0);
1269 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1270         return;
1271 #undef STATE_COMPARE
1272 #undef STATES_COMPARE
1273 }
1274