[Title] Added a new memory tracing feature(and some minor updates)
[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 #include <sys/types.h>
8 #include <unistd.h>
9
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"
12 #undef _COREGL_SYMBOL
13
14 Fastpath_Opt_Flag   fp_opt = FP_UNKNOWN_PATH;
15
16 int                 debug_nofp = 0;
17 FILE               *trace_fp = NULL;
18
19 GLenum              FPGL_Error = GL_NO_ERROR;
20
21 GLGlueContext_List *gctx_list = NULL;
22
23 Mutex               init_context_mutex = MUTEX_INITIALIZER;
24 GLGlueContext      *initial_ctx = NULL;
25
26 Mutex               ctx_list_access_mutex = MUTEX_INITIALIZER;
27
28 GLContext_List     *glctx_list = NULL;
29
30 static void
31 _get_texture_states(GLenum pname, GLint *params)
32 {
33         GLuint cur_active_tex = 0;
34
35         AST(initial_ctx != NULL);
36
37         _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
38         int i;
39         for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++)
40         {
41                 _sym_glActiveTexture(GL_TEXTURE0 + i);
42                 _sym_glGetIntegerv(pname, &(((GLint *)params)[i]));
43         }
44         _sym_glActiveTexture(cur_active_tex);
45 }
46
47 static GLuint
48 _get_stencil_max_mask()
49 {
50         GLuint stencil_bit = 0;
51
52         _sym_glGetIntegerv(GL_STENCIL_BITS, (GLint *)&stencil_bit);
53         return (1 << stencil_bit) - 1;
54 }
55
56 void
57 init_modules_fastpath()
58 {
59         int fastpath_opt = 0;
60
61         LOG("[CoreGL] <Fastpath> : ");
62
63         fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
64
65         switch (fastpath_opt)
66         {
67                 case 1:
68                         LOG("(%d) Fastpath enabled...\n", fastpath_opt);
69                         fp_opt = FP_FAST_PATH;
70                         break;
71                 default:
72                         LOG("(%d) Default API path enabled...\n", fastpath_opt);
73                         fp_opt = FP_NORMAL_PATH;
74                         break;
75         }
76
77         debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
78
79         fastpath_apply_overrides();
80
81 }
82
83 void
84 deinit_modules_fastpath()
85 {
86         GLContext_List *current = NULL;
87
88         AST(mutex_lock(&ctx_list_access_mutex) == 1);
89
90         // Destroy remained context & Detect leaks
91         int retry_destroy = 0;
92
93         while (1)
94         {
95                 retry_destroy = 0;
96                 current = glctx_list;
97                 while (current)
98                 {
99                         if (current->cstate != NULL)
100                         {
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);
102
103                                 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
104                                 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
105
106                                 fastpath_remove_context_states_from_list(current->cstate, NULL);
107                                 retry_destroy = 1;
108                                 break;
109                         }
110
111                         glctx_list = current->next;
112                         free(current);
113                         current = glctx_list;
114                 }
115                 if (retry_destroy == 0) break;
116         }
117         goto finish;
118
119 finish:
120         AST(mutex_unlock(&ctx_list_access_mutex) == 1);
121 }
122
123 void
124 init_modules_tstate_fastpath(GLThreadState *tstate)
125 {
126         MY_MODULE_TSTATE *tstate_mt = NULL;
127
128         tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
129
130         tstate_mt->binded_api = EGL_OPENGL_ES_API;
131
132         tstate->module_data[MY_MODULE_ID] = tstate_mt;
133 }
134
135 void
136 deinit_modules_tstate_fastpath(GLThreadState *tstate)
137 {
138         if (tstate->module_data[MY_MODULE_ID] != NULL)
139         {
140                 free(tstate->module_data[MY_MODULE_ID]);
141                 tstate->module_data[MY_MODULE_ID] = NULL;
142         }
143 }
144
145 void
146 fastpath_apply_overrides()
147 {
148         switch(fp_opt)
149         {
150                 case FP_FAST_PATH:
151                         fastpath_apply_overrides_egl(1);
152                         fastpath_apply_overrides_gl(1);
153                         break;
154                 case FP_NORMAL_PATH:
155                         break;
156                 default:
157                         ERR("Invalide GL Override Option!!!\n");
158                         break;
159         }
160 }
161
162 #define OVERRIDE(f) \
163         if (enable == 1) \
164         { \
165                 COREGL_OVERRIDE_API(_orig_fastpath_, f, ovr_); \
166                 COREGL_OVERRIDE_API(ovr_, f, fastpath_); \
167         } \
168         else \
169         { \
170                 AST(ovr_##f != NULL); \
171                 COREGL_OVERRIDE_API(ovr_, f, _orig_fastpath_); \
172                 _orig_fastpath_##f = NULL; \
173         }
174
175 void
176 fastpath_apply_overrides_egl(int enable)
177 {
178         // Fast-Path Core Functions
179         OVERRIDE(eglGetProcAddress);
180
181         OVERRIDE(eglBindAPI);
182         OVERRIDE(eglQueryAPI);
183
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);
193
194 }
195
196 void
197 fastpath_apply_overrides_gl(int enable)
198 {
199         // Fast-Path Functions
200         if (debug_nofp != 1)
201         {
202                 OVERRIDE(glGetError);
203
204                 OVERRIDE(glGetIntegerv);
205                 OVERRIDE(glGetFloatv);
206                 OVERRIDE(glGetBooleanv);
207
208                 OVERRIDE(glActiveTexture);
209                 OVERRIDE(glGenTextures);
210                 OVERRIDE(glBindTexture);
211                 OVERRIDE(glIsTexture);
212                 OVERRIDE(glDeleteTextures);
213                 OVERRIDE(glFramebufferTexture2D);
214                 OVERRIDE(glFramebufferTexture2DMultisampleEXT);
215
216                 OVERRIDE(glGenBuffers);
217                 OVERRIDE(glBindBuffer);
218                 OVERRIDE(glIsBuffer);
219                 OVERRIDE(glDeleteBuffers);
220
221                 OVERRIDE(glGenFramebuffers);
222                 OVERRIDE(glBindFramebuffer);
223                 OVERRIDE(glIsFramebuffer);
224                 OVERRIDE(glDeleteFramebuffers);
225
226                 OVERRIDE(glGenRenderbuffers);
227                 OVERRIDE(glBindRenderbuffer);
228                 OVERRIDE(glFramebufferRenderbuffer);
229                 OVERRIDE(glIsRenderbuffer);
230                 OVERRIDE(glDeleteRenderbuffers);
231
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);
262
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);
276                 OVERRIDE(glDisable);
277                 OVERRIDE(glDisableVertexAttribArray);
278                 OVERRIDE(glDrawArrays);
279                 OVERRIDE(glDrawElements);
280                 OVERRIDE(glEnable);
281                 OVERRIDE(glEnableVertexAttribArray);
282                 OVERRIDE(glFrontFace);
283                 OVERRIDE(glGetVertexAttribfv);
284                 OVERRIDE(glGetVertexAttribiv);
285                 OVERRIDE(glGetVertexAttribPointerv);
286                 OVERRIDE(glHint);
287                 OVERRIDE(glLineWidth);
288                 OVERRIDE(glPixelStorei);
289                 OVERRIDE(glPolygonOffset);
290                 OVERRIDE(glSampleCoverage);
291                 OVERRIDE(glScissor);
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);
308
309                 OVERRIDE(glEGLImageTargetTexture2DOES);
310
311         }
312         else
313         {
314                 LOG("\E[0;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
315         }
316 }
317
318 #undef OVERRIDE
319
320 static GL_Object **
321 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
322 {
323         switch (type)
324         {
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;
335                 default:
336                         return NULL;
337         }
338 }
339
340 int
341 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
342 {
343         int ret = 0;
344         int tid = 0;
345         GLContext_List *current = NULL;
346         GLContext_List *newitm = NULL;
347
348         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
349
350         AST(cstate != NULL);
351
352         tid = get_current_thread();
353
354         current = glctx_list;
355         while (current != NULL)
356         {
357                 if (current->option_len == option_len &&
358                     memcmp(current->option, option, option_len) == 0 &&
359                     current->thread_id == tid)
360                 {
361                         AST(current->cstate == cstate);
362                         goto finish;
363                 }
364                 current = current->next;
365         }
366
367         newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
368         if (newitm == NULL)
369         {
370                 ERR("Failed to create context list.\n");
371                 goto finish;
372         }
373
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);
379
380         if (glctx_list != NULL)
381                 newitm->next = glctx_list;
382
383         glctx_list = newitm;
384
385         ret = 1;
386         goto finish;
387
388 finish:
389         if (ret != 1)
390         {
391                 if (newitm != NULL)
392                 {
393                         free(newitm);
394                         newitm = NULL;
395                 }
396                 if (cstate != NULL)
397                 {
398                         free(cstate);
399                         cstate = NULL;
400                 }
401         }
402         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
403
404         return ret;
405 }
406
407 GLContextState *
408 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
409 {
410         GLContextState *ret = NULL;
411         GLContext_List *current = NULL;
412         int tid = 0;
413
414         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
415
416         tid = get_current_thread();
417
418         current = glctx_list;
419         while (current != NULL)
420         {
421                 if (current->option_len == option_len &&
422                     memcmp(current->option, option, option_len) == 0 &&
423                     current->thread_id == tid)
424                 {
425                         ret = current->cstate;
426                         goto finish;
427                 }
428                 current = current->next;
429         }
430         goto finish;
431
432 finish:
433         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
434         return ret;
435 }
436
437 int
438 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
439 {
440         int ret = 0;
441         int tid = 0;
442         GLContext_List *olditm = NULL;
443         GLContext_List *current = NULL;
444
445         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
446
447         AST(cstate != NULL);
448
449         tid = get_current_thread();
450         current = glctx_list;
451
452         while (current != NULL)
453         {
454                 if (current->cstate == cstate)
455                 {
456                         GLContext_List *nextitm = NULL;
457                         if (olditm != NULL)
458                         {
459                                 olditm->next = current->next;
460                                 nextitm = olditm->next;
461                         }
462                         else
463                         {
464                                 glctx_list = current->next;
465                                 nextitm = glctx_list;
466                         }
467                         free(current);
468                         ret = 1;
469                         current = nextitm;
470                         continue;
471                 }
472                 olditm = current;
473                 current = current->next;
474         }
475         goto finish;
476
477 finish:
478         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
479         return ret;
480 }
481
482 GLuint
483 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
484 {
485         GL_Object **object = NULL;
486         GLuint ret = _COREGL_INT_INIT_VALUE;
487         int i;
488
489         object = _get_shared_object(sostate, type);
490
491         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
492         {
493                 if (object[i] == NULL)
494                 {
495                         GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
496                         newobj->id = (int)type + i;
497                         newobj->real_id = real_name;
498                         object[i] = newobj;
499                         ret = newobj->id;
500                         goto finish;
501                 }
502         }
503         goto finish;
504
505 finish:
506         return ret;
507 }
508
509 GLuint
510 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
511 {
512         GL_Object **object = NULL;
513         GLuint ret = _COREGL_INT_INIT_VALUE;
514         int hash = _COREGL_INT_INIT_VALUE;
515
516         object = _get_shared_object(sostate, type);
517
518         hash = glue_name - (int)type;
519         if (hash < 0 ||
520             hash > MAX_GL_OBJECT_SIZE ||
521             object[hash] == NULL ||
522             object[hash]->id != glue_name)
523         {
524                 ret = 0;
525                 goto finish;
526         }
527
528         free(object[hash]);
529         object[hash] = NULL;
530         ret = 1;
531         goto finish;
532
533 finish:
534         return ret;
535 }
536
537 GLuint
538 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
539 {
540         GL_Object **object = NULL;
541         GLuint ret = _COREGL_INT_INIT_VALUE;
542         int hash = _COREGL_INT_INIT_VALUE;
543
544         object = _get_shared_object(sostate, type);
545
546         hash = glue_name - (int)type;
547         if (hash < 0 ||
548             hash > MAX_GL_OBJECT_SIZE ||
549             object[hash] == NULL ||
550             object[hash]->id != glue_name)
551         {
552                 ret = 0;
553                 goto finish;
554         }
555         ret = object[hash]->real_id;
556         goto finish;
557
558 finish:
559         return ret;
560 }
561
562 GLuint
563 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
564 {
565         GL_Object **object = NULL;
566         GLuint ret = _COREGL_INT_INIT_VALUE;
567         int i;
568
569         object = _get_shared_object(sostate, type);
570
571         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
572         {
573                 if (object[i] != NULL && object[i]->real_id == real_name)
574                 {
575                         ret = object[i]->id;
576                         goto finish;
577                 }
578         }
579         ret = 0;
580         goto finish;
581
582 finish:
583         return ret;
584 }
585
586 void
587 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
588 {
589         static struct timeval tv_last = { 0, 0 };
590
591         if (unlikely(trace_state_flag != 1)) return;
592
593         if (!force_output)
594         {
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)
598                 {
599                         goto finish;
600                 }
601                 tv_last = tv_now;
602         }
603
604         TRACE("\n");
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");
608
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"
615
616 #define PRINTF_CHAR_GLclampf "%10.6f"
617 #define PRINTF_CHAR_GLfloat "%10.6f"
618
619 #define PRINTF_CHAR_GLvoidptr "%10p"
620
621 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
622
623 #define INITIAL_CTX initial_ctx
624 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
625    { \
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++) \
631       { \
632          if (i > 0) { \
633             if (i % 4 == 0) \
634                TRACE("\n %-30.30s     ", "");\
635             else \
636                TRACE(", "); \
637          } \
638          TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
639          TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
640       } \
641       TRACE(" \E[0;37;1m)\E[0m\n"); \
642    }
643 # include "coregl_fastpath_state.h"
644 #undef GLUE_STATE
645 #undef INITIAL_CTX
646
647         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
648         TRACE("\n");
649
650         TRACE_END();
651
652 finish:
653         return;
654 }
655
656 int
657 fastpath_init_context_states(GLGlueContext *ctx)
658 {
659         int ret = 0;
660
661         AST(mutex_lock(&init_context_mutex) == 1);
662
663         if (ctx == NULL)
664         {
665                 ERR("Context NULL\n");
666                 ret = 0;
667                 goto finish;
668         }
669
670         AST(ctx->initialized == 0);
671         AST(ctx->sostate != NULL);
672
673         if (initial_ctx == NULL)
674         {
675                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
676                 AST(initial_ctx != NULL);
677
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)  \
682       { \
683          int i; \
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++) \
689          { \
690             if (*((char *)(&value[i])) == 0xcc) \
691             { \
692                memset(&value[i], 0xaa, sizeof(TYPE)); \
693                value = valuedata; DEFAULT_STMT; value = valuedata; \
694                if (*((char *)(&value[i])) == 0xaa) \
695                { \
696                   ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
697                   break; \
698                } \
699             } \
700             initial_ctx->NAME[i] = value[i]; \
701          } \
702       }
703 #  include "coregl_fastpath_state.h"
704 # undef GLUE_STATE
705 # undef INITIAL_CTX
706 #else
707 # define INITIAL_CTX initial_ctx
708 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
709       if (try_step == 1) \
710       { \
711          value = valuedata; DEFAULT_STMT; value = valuedata; \
712       } \
713       else \
714       { \
715          value = valuedata; FALLBACK_STMT; value = valuedata; \
716       }
717
718 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
719       { \
720          int i; \
721          int try_step = 0;\
722          TYPE valuedata[SIZE]; \
723          TYPE *value = NULL; \
724          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
725          do { \
726             try_step++; \
727             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
728             for (i = 0; i < SIZE; i++) \
729             { \
730                if (*((char *)(&value[i])) == 0xcc) \
731                { \
732                   memset(&value[i], 0xaa, sizeof(TYPE)); \
733                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
734                   if (*((char *)(&value[i])) == 0xaa) \
735                   { \
736                      try_step++; \
737                      if (try_step == 2) \
738                      { \
739                         ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
740                      } \
741                      break; \
742                   } \
743                } \
744                initial_ctx->NAME[i] = value[i]; \
745             } \
746             if (try_step != 2) \
747             { \
748                value = valuedata; DEFAULT_STMT; value = valuedata; \
749                for (i = 0; i < SIZE; i++) \
750                { \
751                   if (initial_ctx->NAME[i] != value[i]) \
752                   { \
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]); \
754                   } \
755                } \
756             } \
757          } \
758          while (try_step == 2); \
759       }
760 #  include "coregl_fastpath_state.h"
761 # undef SET_GLUE_VALUE
762 # undef GLUE_STATE
763 # undef INITIAL_CTX
764 #endif
765
766                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
767                 {
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]);
769                 }
770                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
771                 {
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]);
773                 }
774         }
775
776         {
777                 int i;
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++) \
781          { \
782             ctx->NAME[i] = initial_ctx->NAME[i]; \
783          }
784 # include "coregl_fastpath_state.h"
785 #undef GLUE_STATE
786 #undef INITIAL_CTX
787         }
788
789         ctx->initialized = 1;
790         ret = 1;
791         goto finish;
792
793 finish:
794         AST(mutex_unlock(&init_context_mutex) == 1);
795
796         return ret;
797 }
798
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);
802 #endif
803
804 void
805 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
806 {
807         unsigned char flag = 0;
808         int i = 0;
809
810         if (debug_nofp == 1) goto finish;
811
812         // Return if they're the same
813         if (oldctx == newctx) goto finish;
814
815 #define STATE_COMPARE(state) \
816    if ((oldctx->state) != (newctx->state))
817
818 #define STATES_COMPARE(state_ptr, bytes) \
819    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
820
821
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
826
827         _sym_glFlush();
828
829 #ifdef COREGL_USE_MODULE_TRACEPATH
830         tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
831 #endif // COREGL_USE_MODULE_TRACEPATH
832
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
837
838         //------------------//
839         // _bind_flag
840         flag = oldctx->_bind_flag | newctx->_bind_flag;
841         if (flag)
842         {
843                 STATE_COMPARE(gl_array_buffer_binding[0])
844                 {
845                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
846                 }
847                 STATE_COMPARE(gl_element_array_buffer_binding[0])
848                 {
849                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
850                 }
851                 STATE_COMPARE(gl_framebuffer_binding[0])
852                 {
853                         _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
854                 }
855                 STATE_COMPARE(gl_renderbuffer_binding[0])
856                 {
857                         _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
858                 }
859         }
860
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
864
865
866         //------------------//
867         // Enable States
868         // _enable_flag1
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
873
874         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
875         if (flag)
876         {
877                 STATE_COMPARE(gl_blend[0])
878                 {
879                         if (newctx->gl_blend[0])
880                                 _sym_glEnable(GL_BLEND);
881                         else
882                                 _sym_glDisable(GL_BLEND);
883                 }
884                 STATE_COMPARE(gl_cull_face[0])
885                 {
886                         if (newctx->gl_cull_face[0])
887                                 _sym_glEnable(GL_CULL_FACE);
888                         else
889                                 _sym_glDisable(GL_CULL_FACE);
890                 }
891                 STATE_COMPARE(gl_depth_test[0])
892                 {
893                         if (newctx->gl_depth_test[0])
894                                 _sym_glEnable(GL_DEPTH_TEST);
895                         else
896                                 _sym_glDisable(GL_DEPTH_TEST);
897                 }
898                 STATE_COMPARE(gl_dither[0])
899                 {
900                         if (newctx->gl_dither[0])
901                                 _sym_glEnable(GL_DITHER);
902                         else
903                                 _sym_glDisable(GL_DITHER);
904                 }
905         }
906
907         // _enable_flag2
908         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
909         if (flag)
910         {
911                 STATE_COMPARE(gl_polygon_offset_fill[0])
912                 {
913                         if (newctx->gl_polygon_offset_fill[0])
914                                 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
915                         else
916                                 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
917                 }
918                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
919                 {
920                         if (newctx->gl_sample_alpha_to_coverage[0])
921                                 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
922                         else
923                                 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
924                 }
925                 STATE_COMPARE(gl_sample_coverage[0])
926                 {
927                         if (newctx->gl_sample_coverage[0])
928                                 _sym_glEnable(GL_SAMPLE_COVERAGE);
929                         else
930                                 _sym_glDisable(GL_SAMPLE_COVERAGE);
931                 }
932                 STATE_COMPARE(gl_scissor_test[0])
933                 {
934                         if (newctx->gl_scissor_test[0])
935                                 _sym_glEnable(GL_SCISSOR_TEST);
936                         else
937                                 _sym_glDisable(GL_SCISSOR_TEST);
938                 }
939                 STATE_COMPARE(gl_stencil_test[0])
940                 {
941                         if (newctx->gl_stencil_test[0])
942                                 _sym_glEnable(GL_STENCIL_TEST);
943                         else
944                                 _sym_glDisable(GL_STENCIL_TEST);
945                 }
946         }
947
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
951
952         //------------------//
953         // _clear_flag1
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
958
959         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
960         if (flag)
961         {
962                 // Viewport.
963                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
964                 {
965                         _sym_glViewport(newctx->gl_viewport[0],
966                                         newctx->gl_viewport[1],
967                                         newctx->gl_viewport[2],
968                                         newctx->gl_viewport[3]);
969                 }
970
971                 STATE_COMPARE(gl_current_program[0])
972                 {
973                         _sym_glUseProgram(newctx->gl_current_program[0]);
974                 }
975                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
976                 {
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]);
981                 }
982         }
983
984
985         // _clear_flag2
986         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
987         if (flag)
988         {
989                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
990                 {
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]);
995                 }
996                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
997                 {
998                         _sym_glDepthRangef(newctx->gl_depth_range[0],
999                                            newctx->gl_depth_range[1]);
1000                 }
1001                 STATE_COMPARE(gl_depth_clear_value[0])
1002                 {
1003                         _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
1004                 }
1005                 STATE_COMPARE(gl_depth_func[0])
1006                 {
1007                         _sym_glDepthFunc(newctx->gl_depth_func[0]);
1008                 }
1009                 STATE_COMPARE(gl_depth_writemask[0])
1010                 {
1011                         _sym_glDepthMask(newctx->gl_depth_writemask[0]);
1012                 }
1013                 STATE_COMPARE(gl_cull_face_mode[0])
1014                 {
1015                         _sym_glCullFace(newctx->gl_cull_face_mode[0]);
1016                 }
1017
1018         }
1019
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
1023
1024         //------------------//
1025         // Texture here...
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
1030
1031         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1032         if (flag)
1033         {
1034
1035                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1036                 {
1037                         STATE_COMPARE(gl_tex_2d_state[i])
1038                         {
1039                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
1040                                 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
1041                         }
1042
1043                         STATE_COMPARE(gl_tex_cube_state[i])
1044                         {
1045                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
1046                                 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
1047                         }
1048                 }
1049
1050                 // Restore active texture
1051                 _sym_glActiveTexture(newctx->gl_active_texture[0]);
1052
1053                 STATE_COMPARE(gl_generate_mipmap_hint[0])
1054                 {
1055                         _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
1056                 }
1057         }
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
1061
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
1067
1068         flag = oldctx->_blend_flag | newctx->_blend_flag;
1069         if (flag)
1070         {
1071                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1072                 {
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]);
1077                 }
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]))
1082                 {
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]);
1087                 }
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]))
1090                 {
1091                         _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
1092                 }
1093
1094         }
1095
1096         //------------------//
1097         // _stencil_flag1
1098         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1099         if (flag)
1100         {
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]))
1104                 {
1105                         _sym_glStencilFuncSeparate(GL_FRONT,
1106                                                    newctx->gl_stencil_func[0],
1107                                                    newctx->gl_stencil_ref[0],
1108                                                    newctx->gl_stencil_value_mask[0]);
1109                 }
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]))
1113                 {
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]);
1118                 }
1119
1120                 STATE_COMPARE(gl_stencil_writemask[0])
1121                 {
1122                         _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
1123                 }
1124         }
1125
1126
1127         // _stencil_flag1
1128         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1129         if (flag)
1130         {
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]))
1134                 {
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]);
1139                 }
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]))
1143                 {
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]);
1148                 }
1149
1150                 STATE_COMPARE(gl_stencil_back_writemask[0])
1151                 {
1152                         _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
1153                 }
1154                 STATE_COMPARE(gl_stencil_clear_value[0])
1155                 {
1156                         _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
1157                 }
1158         }
1159
1160         //------------------//
1161         // _misc_flag1
1162         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1163         if (flag)
1164         {
1165                 STATE_COMPARE(gl_front_face[0])
1166                 {
1167                         _sym_glFrontFace(newctx->gl_front_face[0]);
1168                 }
1169                 STATE_COMPARE(gl_line_width[0])
1170                 {
1171                         _sym_glLineWidth(newctx->gl_line_width[0]);
1172                 }
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]))
1175                 {
1176                         _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1177                                              newctx->gl_polygon_offset_units[0]);
1178                 }
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]))
1181                 {
1182                         _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1183                                               newctx->gl_sample_coverage_invert[0]);
1184                 }
1185         }
1186
1187         // _misc_flag2
1188         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1189         if (flag)
1190         {
1191                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1192                 {
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]);
1197                 }
1198                 STATE_COMPARE(gl_pack_alignment[0])
1199                 {
1200                         _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
1201                 }
1202                 STATE_COMPARE(gl_unpack_alignment[0])
1203                 {
1204                         _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
1205                 }
1206         }
1207 #ifdef COREGL_USE_MODULE_TRACEPATH
1208         tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1209 #endif // COREGL_USE_MODULE_TRACEPATH
1210
1211         // _varray_flag
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
1216
1217         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1218         if (flag)
1219         {
1220                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1221                 {
1222                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1223                         {
1224                                 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
1225                         }
1226                         else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
1227
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]);
1234
1235                         STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1236                         {
1237                                 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
1238                         }
1239
1240                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1241                         {
1242                                 _sym_glEnableVertexAttribArray(i);
1243                         }
1244                         else
1245                         {
1246                                 _sym_glDisableVertexAttribArray(i);
1247                         }
1248                 }
1249
1250                 STATE_COMPARE(gl_array_buffer_binding[0])
1251                 {
1252                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
1253                 }
1254                 STATE_COMPARE(gl_element_array_buffer_binding[0])
1255                 {
1256                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
1257                 }
1258
1259         }
1260
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
1264
1265         goto finish;
1266
1267 finish:
1268
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
1273         return;
1274 #undef STATE_COMPARE
1275 #undef STATES_COMPARE
1276 }
1277