[Title] Avoid prevent issues
[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         _orig_fastpath_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                 _orig_fastpath_glActiveTexture(GL_TEXTURE0 + i);
42                 _orig_fastpath_glGetIntegerv(pname, &(((GLint *)params)[i]));
43         }
44         _orig_fastpath_glActiveTexture(cur_active_tex);
45 }
46
47 void
48 init_modules_fastpath()
49 {
50         int fastpath_opt = 0;
51         int fastpath_force_off_opt = 0;
52
53         COREGL_LOG("[CoreGL] <Fastpath> : ");
54
55         fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
56         fastpath_force_off_opt = atoi(get_env_setting("COREGL_FASTPATH_FORCE_OFF"));
57
58         if (fastpath_force_off_opt == 1)
59         {
60                 COREGL_LOG("\E[40;31;1m(DISABLED by force option)\E[0m ");
61                 fastpath_opt = 0;
62         }
63
64         switch (fastpath_opt)
65         {
66                 case 1:
67                         COREGL_LOG("(%d) Fastpath enabled...\n", fastpath_opt);
68                         fp_opt = FP_FAST_PATH;
69                         break;
70                 default:
71                         COREGL_LOG("(%d) Default API path enabled...\n", fastpath_opt);
72                         fp_opt = FP_NORMAL_PATH;
73                         break;
74         }
75
76         debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
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                                 COREGL_WRN("\E[40;31;1mContext attached to [dpy=%p|rctx=%p] has not been completely destroyed.(leak)\E[0m\n", current->cstate->rdpy, current->cstate->rctx);
99
100                                 _orig_fastpath_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
101                                 _orig_fastpath_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                         COREGL_ERR("Invalide GL Override Option!!!\n");
155                         break;
156         }
157 }
158
159
160 void
161 fastpath_apply_overrides_egl(int enable)
162 {
163 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST)     COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
164 # include "../../headers/sym_egl.h"
165 #undef _COREGL_SYMBOL
166
167         COREGL_OVERRIDE(fastpath_, eglGetProcAddress);
168
169         COREGL_OVERRIDE(fastpath_, eglBindAPI);
170         COREGL_OVERRIDE(fastpath_, eglQueryAPI);
171
172         COREGL_OVERRIDE(fastpath_, eglCreateContext);
173         COREGL_OVERRIDE(fastpath_, eglCreateImageKHR);
174         COREGL_OVERRIDE(fastpath_, eglMakeCurrent);
175         COREGL_OVERRIDE(fastpath_, eglDestroyContext);
176         COREGL_OVERRIDE(fastpath_, eglQueryContext);
177         COREGL_OVERRIDE(fastpath_, eglGetCurrentContext);
178         COREGL_OVERRIDE(fastpath_, eglReleaseThread);
179         COREGL_OVERRIDE(fastpath_, eglGetCurrentSurface);
180         COREGL_OVERRIDE(fastpath_, eglTerminate);
181
182 }
183
184 void
185 fastpath_apply_overrides_gl(int enable)
186 {
187 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST)     COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
188 # include "../../headers/sym_gl.h"
189 #undef _COREGL_SYMBOL
190
191         if (debug_nofp != 1)
192         {
193                 COREGL_OVERRIDE(fastpath_, glGetError);
194                 COREGL_OVERRIDE(fastpath_, glGetString);
195
196                 COREGL_OVERRIDE(fastpath_, glGetIntegerv);
197                 COREGL_OVERRIDE(fastpath_, glGetFloatv);
198                 COREGL_OVERRIDE(fastpath_, glGetBooleanv);
199
200                 COREGL_OVERRIDE(fastpath_, glActiveTexture);
201                 COREGL_OVERRIDE(fastpath_, glGenTextures);
202                 COREGL_OVERRIDE(fastpath_, glBindTexture);
203                 COREGL_OVERRIDE(fastpath_, glIsTexture);
204                 COREGL_OVERRIDE(fastpath_, glDeleteTextures);
205                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2D);
206
207                 COREGL_OVERRIDE(fastpath_, glGenBuffers);
208                 COREGL_OVERRIDE(fastpath_, glBindBuffer);
209                 COREGL_OVERRIDE(fastpath_, glIsBuffer);
210                 COREGL_OVERRIDE(fastpath_, glDeleteBuffers);
211
212                 COREGL_OVERRIDE(fastpath_, glGenFramebuffers);
213                 COREGL_OVERRIDE(fastpath_, glBindFramebuffer);
214                 COREGL_OVERRIDE(fastpath_, glIsFramebuffer);
215                 COREGL_OVERRIDE(fastpath_, glDeleteFramebuffers);
216                 COREGL_OVERRIDE(fastpath_, glGetFramebufferAttachmentParameteriv);
217
218                 COREGL_OVERRIDE(fastpath_, glGenRenderbuffers);
219                 COREGL_OVERRIDE(fastpath_, glBindRenderbuffer);
220                 COREGL_OVERRIDE(fastpath_, glFramebufferRenderbuffer);
221                 COREGL_OVERRIDE(fastpath_, glIsRenderbuffer);
222                 COREGL_OVERRIDE(fastpath_, glDeleteRenderbuffers);
223
224                 COREGL_OVERRIDE(fastpath_, glCreateShader);
225                 COREGL_OVERRIDE(fastpath_, glCreateProgram);
226                 COREGL_OVERRIDE(fastpath_, glAttachShader);
227                 COREGL_OVERRIDE(fastpath_, glCompileShader);
228                 COREGL_OVERRIDE(fastpath_, glShaderBinary);
229                 COREGL_OVERRIDE(fastpath_, glDeleteShader);
230                 COREGL_OVERRIDE(fastpath_, glDetachShader);
231                 COREGL_OVERRIDE(fastpath_, glGetShaderiv);
232                 COREGL_OVERRIDE(fastpath_, glGetShaderInfoLog);
233                 COREGL_OVERRIDE(fastpath_, glGetShaderSource);
234                 COREGL_OVERRIDE(fastpath_, glIsShader);
235                 COREGL_OVERRIDE(fastpath_, glShaderSource);
236                 COREGL_OVERRIDE(fastpath_, glBindAttribLocation);
237                 COREGL_OVERRIDE(fastpath_, glDeleteProgram);
238                 COREGL_OVERRIDE(fastpath_, glGetActiveAttrib);
239                 COREGL_OVERRIDE(fastpath_, glGetActiveUniform);
240                 COREGL_OVERRIDE(fastpath_, glGetAttachedShaders);
241                 COREGL_OVERRIDE(fastpath_, glGetAttribLocation);
242                 COREGL_OVERRIDE(fastpath_, glGetProgramiv);
243                 COREGL_OVERRIDE(fastpath_, glGetProgramInfoLog);
244                 COREGL_OVERRIDE(fastpath_, glGetUniformfv);
245                 COREGL_OVERRIDE(fastpath_, glGetUniformiv);
246                 COREGL_OVERRIDE(fastpath_, glGetUniformLocation);
247                 COREGL_OVERRIDE(fastpath_, glIsProgram);
248                 COREGL_OVERRIDE(fastpath_, glLinkProgram);
249                 COREGL_OVERRIDE(fastpath_, glUseProgram);
250                 COREGL_OVERRIDE(fastpath_, glValidateProgram);
251
252                 COREGL_OVERRIDE(fastpath_, glBlendColor);
253                 COREGL_OVERRIDE(fastpath_, glBlendEquation);
254                 COREGL_OVERRIDE(fastpath_, glBlendEquationSeparate);
255                 COREGL_OVERRIDE(fastpath_, glBlendFunc);
256                 COREGL_OVERRIDE(fastpath_, glBlendFuncSeparate);
257                 COREGL_OVERRIDE(fastpath_, glClearColor);
258                 COREGL_OVERRIDE(fastpath_, glClearDepthf);
259                 COREGL_OVERRIDE(fastpath_, glClearStencil);
260                 COREGL_OVERRIDE(fastpath_, glColorMask);
261                 COREGL_OVERRIDE(fastpath_, glCullFace);
262                 COREGL_OVERRIDE(fastpath_, glDepthFunc);
263                 COREGL_OVERRIDE(fastpath_, glDepthMask);
264                 COREGL_OVERRIDE(fastpath_, glDepthRangef);
265                 COREGL_OVERRIDE(fastpath_, glDisable);
266                 COREGL_OVERRIDE(fastpath_, glDisableVertexAttribArray);
267                 COREGL_OVERRIDE(fastpath_, glEnable);
268                 COREGL_OVERRIDE(fastpath_, glEnableVertexAttribArray);
269                 COREGL_OVERRIDE(fastpath_, glFrontFace);
270                 COREGL_OVERRIDE(fastpath_, glHint);
271                 COREGL_OVERRIDE(fastpath_, glLineWidth);
272                 COREGL_OVERRIDE(fastpath_, glPixelStorei);
273                 COREGL_OVERRIDE(fastpath_, glPolygonOffset);
274                 COREGL_OVERRIDE(fastpath_, glSampleCoverage);
275                 COREGL_OVERRIDE(fastpath_, glScissor);
276                 COREGL_OVERRIDE(fastpath_, glStencilFunc);
277                 COREGL_OVERRIDE(fastpath_, glStencilFuncSeparate);
278                 COREGL_OVERRIDE(fastpath_, glStencilMask);
279                 COREGL_OVERRIDE(fastpath_, glStencilMaskSeparate);
280                 COREGL_OVERRIDE(fastpath_, glStencilOp);
281                 COREGL_OVERRIDE(fastpath_, glStencilOpSeparate);
282                 COREGL_OVERRIDE(fastpath_, glVertexAttrib1f);
283                 COREGL_OVERRIDE(fastpath_, glVertexAttrib1fv);
284                 COREGL_OVERRIDE(fastpath_, glVertexAttrib2f);
285                 COREGL_OVERRIDE(fastpath_, glVertexAttrib2fv);
286                 COREGL_OVERRIDE(fastpath_, glVertexAttrib3f);
287                 COREGL_OVERRIDE(fastpath_, glVertexAttrib3fv);
288                 COREGL_OVERRIDE(fastpath_, glVertexAttrib4f);
289                 COREGL_OVERRIDE(fastpath_, glVertexAttrib4fv);
290                 COREGL_OVERRIDE(fastpath_, glVertexAttribPointer);
291                 COREGL_OVERRIDE(fastpath_, glViewport);
292
293                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2DMultisampleEXT);
294                 COREGL_OVERRIDE(fastpath_, glProgramParameteriEXT);
295                 COREGL_OVERRIDE(fastpath_, glEGLImageTargetTexture2DOES);
296                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture3DOES);
297
298                 /* ES 3.0 BLOCK */
299                 COREGL_OVERRIDE(fastpath_, glReadBuffer);
300                 COREGL_OVERRIDE(fastpath_, glDrawRangeElements);
301                 COREGL_OVERRIDE(fastpath_, glTexImage3D);
302                 COREGL_OVERRIDE(fastpath_, glTexSubImage3D);
303                 COREGL_OVERRIDE(fastpath_, glCopyTexSubImage3D);
304                 COREGL_OVERRIDE(fastpath_, glCompressedTexImage3D);
305                 COREGL_OVERRIDE(fastpath_, glCompressedTexSubImage3D);
306                 COREGL_OVERRIDE(fastpath_, glGenQueries);
307                 COREGL_OVERRIDE(fastpath_, glDeleteQueries);
308                 COREGL_OVERRIDE(fastpath_, glIsQuery);
309                 COREGL_OVERRIDE(fastpath_, glBeginQuery);
310                 COREGL_OVERRIDE(fastpath_, glEndQuery);
311                 COREGL_OVERRIDE(fastpath_, glGetQueryiv);
312                 COREGL_OVERRIDE(fastpath_, glGetQueryObjectuiv);
313                 COREGL_OVERRIDE(fastpath_, glUnmapBuffer);
314                 COREGL_OVERRIDE(fastpath_, glGetBufferPointerv);
315                 COREGL_OVERRIDE(fastpath_, glDrawBuffers);
316                 COREGL_OVERRIDE(fastpath_, glUniformMatrix2x3fv);
317                 COREGL_OVERRIDE(fastpath_, glUniformMatrix3x2fv);
318                 COREGL_OVERRIDE(fastpath_, glUniformMatrix2x4fv);
319                 COREGL_OVERRIDE(fastpath_, glUniformMatrix4x2fv);
320                 COREGL_OVERRIDE(fastpath_, glUniformMatrix3x4fv);
321                 COREGL_OVERRIDE(fastpath_, glUniformMatrix4x3fv);
322                 COREGL_OVERRIDE(fastpath_, glBlitFramebuffer);
323                 COREGL_OVERRIDE(fastpath_, glRenderbufferStorageMultisample);
324                 COREGL_OVERRIDE(fastpath_, glFramebufferTextureLayer);
325                 COREGL_OVERRIDE(fastpath_, glMapBufferRange);
326                 COREGL_OVERRIDE(fastpath_, glFlushMappedBufferRange);
327                 COREGL_OVERRIDE(fastpath_, glBindVertexArray);
328                 COREGL_OVERRIDE(fastpath_, glDeleteVertexArrays);
329                 COREGL_OVERRIDE(fastpath_, glGenVertexArrays);
330                 COREGL_OVERRIDE(fastpath_, glIsVertexArray);
331                 COREGL_OVERRIDE(fastpath_, glGetIntegeri_v);
332                 COREGL_OVERRIDE(fastpath_, glBeginTransformFeedback);
333                 COREGL_OVERRIDE(fastpath_, glEndTransformFeedback);
334                 COREGL_OVERRIDE(fastpath_, glBindBufferRange);
335                 COREGL_OVERRIDE(fastpath_, glBindBufferBase);
336                 COREGL_OVERRIDE(fastpath_, glTransformFeedbackVaryings);
337                 COREGL_OVERRIDE(fastpath_, glGetTransformFeedbackVarying);
338                 COREGL_OVERRIDE(fastpath_, glVertexAttribIPointer);
339                 COREGL_OVERRIDE(fastpath_, glGetVertexAttribIiv);
340                 COREGL_OVERRIDE(fastpath_, glGetVertexAttribIuiv);
341                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4i);
342                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4ui);
343                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4iv);
344                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4uiv);
345                 COREGL_OVERRIDE(fastpath_, glGetUniformuiv);
346                 COREGL_OVERRIDE(fastpath_, glGetFragDataLocation);
347                 COREGL_OVERRIDE(fastpath_, glUniform1ui);
348                 COREGL_OVERRIDE(fastpath_, glUniform2ui);
349                 COREGL_OVERRIDE(fastpath_, glUniform3ui);
350                 COREGL_OVERRIDE(fastpath_, glUniform4ui);
351                 COREGL_OVERRIDE(fastpath_, glUniform1uiv);
352                 COREGL_OVERRIDE(fastpath_, glUniform2uiv);
353                 COREGL_OVERRIDE(fastpath_, glUniform3uiv);
354                 COREGL_OVERRIDE(fastpath_, glUniform4uiv);
355                 COREGL_OVERRIDE(fastpath_, glClearBufferiv);
356                 COREGL_OVERRIDE(fastpath_, glClearBufferuiv);
357                 COREGL_OVERRIDE(fastpath_, glClearBufferfv);
358                 COREGL_OVERRIDE(fastpath_, glClearBufferfi);
359                 COREGL_OVERRIDE(fastpath_, glGetStringi);
360                 COREGL_OVERRIDE(fastpath_, glCopyBufferSubData);
361                 COREGL_OVERRIDE(fastpath_, glGetUniformIndices);
362                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformsiv);
363                 COREGL_OVERRIDE(fastpath_, glGetUniformBlockIndex);
364                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockiv);
365                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockName);
366                 COREGL_OVERRIDE(fastpath_, glUniformBlockBinding);
367                 COREGL_OVERRIDE(fastpath_, glDrawArraysInstanced);
368                 COREGL_OVERRIDE(fastpath_, glDrawElementsInstanced);
369                 COREGL_OVERRIDE(fastpath_, glFenceSync);
370                 COREGL_OVERRIDE(fastpath_, glIsSync);
371                 COREGL_OVERRIDE(fastpath_, glDeleteSync);
372                 COREGL_OVERRIDE(fastpath_, glClientWaitSync);
373                 COREGL_OVERRIDE(fastpath_, glWaitSync);
374                 COREGL_OVERRIDE(fastpath_, glGetInteger64v);
375                 COREGL_OVERRIDE(fastpath_, glGetSynciv);
376                 COREGL_OVERRIDE(fastpath_, glGetInteger64i_v);
377                 COREGL_OVERRIDE(fastpath_, glGetBufferParameteri64v);
378                 COREGL_OVERRIDE(fastpath_, glGenSamplers);
379                 COREGL_OVERRIDE(fastpath_, glDeleteSamplers);
380                 COREGL_OVERRIDE(fastpath_, glIsSampler);
381                 COREGL_OVERRIDE(fastpath_, glBindSampler);
382                 COREGL_OVERRIDE(fastpath_, glSamplerParameteri);
383                 COREGL_OVERRIDE(fastpath_, glSamplerParameteriv);
384                 COREGL_OVERRIDE(fastpath_, glSamplerParameterf);
385                 COREGL_OVERRIDE(fastpath_, glSamplerParameterfv);
386                 COREGL_OVERRIDE(fastpath_, glGetSamplerParameteriv);
387                 COREGL_OVERRIDE(fastpath_, glGetSamplerParameterfv);
388                 COREGL_OVERRIDE(fastpath_, glVertexAttribDivisor);
389                 COREGL_OVERRIDE(fastpath_, glBindTransformFeedback);
390                 COREGL_OVERRIDE(fastpath_, glDeleteTransformFeedbacks);
391                 COREGL_OVERRIDE(fastpath_, glGenTransformFeedbacks);
392                 COREGL_OVERRIDE(fastpath_, glIsTransformFeedback);
393                 COREGL_OVERRIDE(fastpath_, glPauseTransformFeedback);
394                 COREGL_OVERRIDE(fastpath_, glResumeTransformFeedback);
395                 COREGL_OVERRIDE(fastpath_, glGetProgramBinary); // OPEN
396                 COREGL_OVERRIDE(fastpath_, glProgramBinary); // OPEN
397                 COREGL_OVERRIDE(fastpath_, glProgramParameteri);
398                 COREGL_OVERRIDE(fastpath_, glInvalidateFramebuffer);
399                 COREGL_OVERRIDE(fastpath_, glInvalidateSubFramebuffer);
400                 COREGL_OVERRIDE(fastpath_, glTexStorage2D);
401                 COREGL_OVERRIDE(fastpath_, glTexStorage3D);
402                 COREGL_OVERRIDE(fastpath_, glGetInternalformativ);
403
404         }
405         else
406         {
407                 COREGL_LOG("\E[40;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
408         }
409 }
410
411 #undef OVERRIDE
412
413 static inline GL_Object_Hash_Base *
414 _get_shared_object_hash(GL_Shared_Object_State *sostate, GL_Object_Type type)
415 {
416         switch (type)
417         {
418                 case GL_OBJECT_TYPE_TEXTURE:
419                         return &sostate->texture;
420                 case GL_OBJECT_TYPE_BUFFER:
421                         return &sostate->buffer;
422                 case GL_OBJECT_TYPE_FRAMEBUFFER:
423                         return &sostate->framebuffer;
424                 case GL_OBJECT_TYPE_RENDERBUFFER:
425                         return &sostate->renderbuffer;
426                 case GL_OBJECT_TYPE_PROGRAM:
427                         return &sostate->program;
428                 default:
429                         return NULL;
430         }
431 }
432
433 static inline GL_Object_Hash_Base *
434 _get_shared_object_hash_real(GL_Shared_Object_State *sostate, GL_Object_Type type)
435 {
436         switch (type)
437         {
438                 case GL_OBJECT_TYPE_TEXTURE:
439                         return &sostate->texture_real;
440                 case GL_OBJECT_TYPE_BUFFER:
441                         return &sostate->buffer_real;
442                 case GL_OBJECT_TYPE_FRAMEBUFFER:
443                         return &sostate->framebuffer_real;
444                 case GL_OBJECT_TYPE_RENDERBUFFER:
445                         return &sostate->renderbuffer_real;
446                 case GL_OBJECT_TYPE_PROGRAM:
447                         return &sostate->program_real;
448                 default:
449                         return NULL;
450         }
451 }
452
453 int
454 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
455 {
456         int ret = 0;
457         int tid = 0;
458         GLContext_List *current = NULL;
459         GLContext_List *newitm = NULL;
460
461         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
462
463         AST(cstate != NULL);
464
465         tid = get_current_thread();
466
467         current = glctx_list;
468         while (current != NULL)
469         {
470                 if (current->option_len == option_len &&
471                     memcmp(current->option, option, option_len) == 0 &&
472                     current->thread_id == tid)
473                 {
474                         AST(current->cstate == cstate);
475                         goto finish;
476                 }
477                 current = current->next;
478         }
479
480         newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
481         if (newitm == NULL)
482         {
483                 COREGL_ERR("Failed to create context list.\n");
484                 goto finish;
485         }
486
487         newitm->cstate = cstate;
488         newitm->thread_id = tid;
489         newitm->option_len = option_len;
490         newitm->option = (void *)malloc(option_len);
491         memcpy(newitm->option, option, option_len);
492
493         if (glctx_list != NULL)
494                 newitm->next = glctx_list;
495
496         glctx_list = newitm;
497
498         ret = 1;
499         goto finish;
500
501 finish:
502         if (ret != 1)
503         {
504                 if (newitm != NULL)
505                 {
506                         free(newitm);
507                         newitm = NULL;
508                 }
509                 if (cstate != NULL)
510                 {
511                         free(cstate);
512                         cstate = NULL;
513                 }
514         }
515         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
516
517         return ret;
518 }
519
520 GLContextState *
521 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
522 {
523         GLContextState *ret = NULL;
524         GLContext_List *current = NULL;
525         int tid = 0;
526
527         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
528
529         tid = get_current_thread();
530
531         current = glctx_list;
532         while (current != NULL)
533         {
534                 if (current->option_len == option_len &&
535                     memcmp(current->option, option, option_len) == 0 &&
536                     current->thread_id == tid)
537                 {
538                         ret = current->cstate;
539                         goto finish;
540                 }
541                 current = current->next;
542         }
543         goto finish;
544
545 finish:
546         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
547         return ret;
548 }
549
550 int
551 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
552 {
553         int ret = 0;
554         int tid = 0;
555         GLContext_List *olditm = NULL;
556         GLContext_List *current = NULL;
557
558         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
559
560         AST(cstate != NULL);
561
562         tid = get_current_thread();
563         current = glctx_list;
564
565         while (current != NULL)
566         {
567                 if (current->cstate == cstate)
568                 {
569                         GLContext_List *nextitm = NULL;
570                         if (olditm != NULL)
571                         {
572                                 olditm->next = current->next;
573                                 nextitm = olditm->next;
574                         }
575                         else
576                         {
577                                 glctx_list = current->next;
578                                 nextitm = glctx_list;
579                         }
580                         if (current->option != NULL)
581                         {
582                                 AST(current->option_len > 0);
583                                 free(current->option);
584                                 current->option = NULL;
585                                 current->option_len = 0;
586                         }
587                         free(current);
588                         ret = 1;
589                         current = nextitm;
590                         continue;
591                 }
592                 olditm = current;
593                 current = current->next;
594         }
595         goto finish;
596
597 finish:
598         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
599         return ret;
600 }
601
602 void
603 fastpath_sostate_init(GL_Shared_Object_State *sostate)
604 {
605 #define HASH_INIT(hash_base) \
606         hash_base.hash_field = (GL_Object_Hash **)calloc(1, sizeof(GL_Object_Hash *) * GL_OBJECT_HASH_BASE); \
607         hash_base.hash_size = GL_OBJECT_HASH_BASE;
608
609         HASH_INIT(sostate->texture);
610         HASH_INIT(sostate->buffer);
611         HASH_INIT(sostate->framebuffer);
612         HASH_INIT(sostate->renderbuffer);
613         HASH_INIT(sostate->program);
614
615         HASH_INIT(sostate->texture_real);
616         HASH_INIT(sostate->buffer_real);
617         HASH_INIT(sostate->framebuffer_real);
618         HASH_INIT(sostate->renderbuffer_real);
619         HASH_INIT(sostate->program_real);
620
621 #undef HASH_INIT
622 }
623
624 static void
625 _add_hash(GL_Object_Hash_Base *hash_base, GL_Object_Hash *data)
626 {
627         int array_idx = data->hash_key & (hash_base->hash_size - 1);
628         if (hash_base->hash_field[array_idx] == NULL)
629         {
630                 hash_base->hash_field[array_idx] = data;
631         }
632         else
633         {
634                 GL_Object_Hash *current = hash_base->hash_field[array_idx];
635                 while(current->next)
636                 {
637                         AST(current->hash_key != data->hash_key);
638                         current = current->next;
639                 }
640                 current->next = data;
641         }
642         data->next = NULL;
643         hash_base->item_size++;
644 }
645
646 static int
647 _remove_hash(GL_Object_Hash_Base *hash_base, GLuint hash)
648 {
649         int ret = 0;
650         int array_idx = hash & (hash_base->hash_size - 1);
651
652         GL_Object_Hash *current = hash_base->hash_field[array_idx];
653         GL_Object_Hash *prev = NULL;
654
655         while(current)
656         {
657                 if (current->hash_key == hash)
658                 {
659                         if (prev != NULL)
660                                 prev->next = current->next;
661                         else
662                                 hash_base->hash_field[array_idx] = current->next;
663                         hash_base->item_size--;
664                         ret = 1;
665                         break;
666                 }
667                 prev = current;
668                 current = current->next;
669         }
670
671         return ret;
672 }
673
674 static void
675 _free_hash_list(GL_Object_Hash_Base *hash_base, int free_data)
676 {
677         if (hash_base->item_size == 0) return;
678
679         for (int i = 0; i < hash_base->hash_size; i++)
680         {
681                 if (hash_base->hash_field[i] != NULL)
682                 {
683                         GL_Object_Hash *current = hash_base->hash_field[i];
684
685                         while (current != NULL)
686                         {
687                                 GL_Object_Hash *current_next = current->next;
688
689                                 if (free_data == 1 && current->item != NULL)
690                                 {
691                                         free(current->item);
692                                 }
693
694                                 free(current);
695                                 hash_base->item_size--;
696                                 current = current_next;
697                         }
698                 }
699         }
700 }
701
702 void
703 fastpath_sostate_deinit(GL_Shared_Object_State *sostate)
704 {
705 #define HASH_DEINIT(hash_base, free_data) \
706         _free_hash_list(&hash_base, free_data); \
707         free(hash_base.hash_field); \
708         hash_base.hash_size = 0;
709
710         HASH_DEINIT(sostate->texture, 1);
711         HASH_DEINIT(sostate->buffer, 1);
712         HASH_DEINIT(sostate->framebuffer, 1);
713         HASH_DEINIT(sostate->renderbuffer, 1);
714         HASH_DEINIT(sostate->program, 1);
715
716         HASH_DEINIT(sostate->texture_real, 0);
717         HASH_DEINIT(sostate->buffer_real, 0);
718         HASH_DEINIT(sostate->framebuffer_real, 0);
719         HASH_DEINIT(sostate->renderbuffer_real, 0);
720         HASH_DEINIT(sostate->program_real, 0);
721
722 #undef HASH_DEINIT
723 }
724
725 #define FIND_HASH(hash_base, key, ret) \
726 { \
727         GL_Object_Hash *fh_current = hash_base->hash_field[(key) & (hash_base->hash_size - 1)]; \
728         while(fh_current) \
729         { \
730                 if (fh_current->hash_key == (key)) \
731                 { \
732                         ret = fh_current; \
733                         break; \
734                 } \
735                 fh_current = fh_current->next; \
736         } \
737 }
738
739 void
740 _sostate_hash_check(GL_Object_Hash_Base *hash_base)
741 {
742         if (hash_base->item_size + 1 < hash_base->hash_size)
743                 return;
744
745         int oldsize = hash_base->hash_size;
746         GL_Object_Hash **oldfield = hash_base->hash_field;
747
748         hash_base->hash_size = oldsize << 1;
749         hash_base->hash_field = (GL_Object_Hash **)calloc(1, sizeof(GL_Object_Hash *) * hash_base->hash_size);
750         AST(hash_base->hash_field != NULL);
751
752         for (int i = 0; i < oldsize; i++)
753         {
754                 if (oldfield[i] != NULL)
755                 {
756                         GL_Object_Hash *current = oldfield[i];
757
758                         while (current != NULL)
759                         {
760                                 GL_Object_Hash *current_next = current->next;
761                                 _add_hash(hash_base, current);
762                                 hash_base->item_size--;
763                                 current = current_next;
764                         }
765                 }
766         }
767         free(oldfield);
768
769 }
770
771 GLuint
772 fastpath_sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
773 {
774         GLuint ret = _COREGL_INT_INIT_VALUE;
775
776         GL_Object_Hash_Base *hash_base = NULL;
777         GL_Object_Hash_Base *hash_base_real = NULL;
778         int newid = _COREGL_INT_INIT_VALUE;
779
780         hash_base = _get_shared_object_hash(sostate, type);
781         hash_base_real = _get_shared_object_hash_real(sostate, type);
782
783         newid = hash_base->last_id + 1;
784         if (newid >= hash_base->hash_size)
785         {
786                 hash_base->is_looped = 1;
787                 newid = 1;
788                 hash_base->last_id = 1;
789         }
790
791         if (hash_base->is_looped != 0)
792         {
793                 int i;
794                 int findingid = newid;
795                 newid = -1;
796                 for (i = 0; i < hash_base->hash_size; i++)
797                 {
798                         GL_Object_Hash *exist_hash = NULL;
799                         FIND_HASH(hash_base, findingid, exist_hash);
800                         if (exist_hash == NULL)
801                         {
802                                 newid = findingid;
803                                 break;
804                         }
805                         findingid++;
806                         if (findingid >= hash_base->hash_size) findingid = 1;
807                 }
808                 AST(newid != -1);
809         }
810         hash_base->last_id = newid;
811
812         {
813                 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
814                 AST(newobj != NULL);
815                 newobj->id = (int)type + newid;
816                 newobj->real_id = real_name;
817                 newobj->ref_count = 1;
818                 ret = newobj->id;
819
820                 GL_Object_Hash *newobj_hash = (GL_Object_Hash *)calloc(1, sizeof(GL_Object_Hash));
821                 AST(newobj_hash != NULL);
822                 newobj_hash->item = newobj;
823                 newobj_hash->hash_key = newid;
824                 _add_hash(hash_base, newobj_hash);
825
826                 GL_Object_Hash *newobj_hash_real = (GL_Object_Hash *)calloc(1, sizeof(GL_Object_Hash));
827                 AST(newobj_hash_real != NULL);
828                 newobj_hash_real->item = newobj;
829                 newobj_hash_real->hash_key = real_name;
830                 _add_hash(hash_base_real, newobj_hash_real);
831         }
832
833         _sostate_hash_check(hash_base);
834         _sostate_hash_check(hash_base_real);
835
836         goto finish;
837
838 finish:
839         return ret;
840 }
841
842 #define FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object) \
843         if (((int)(hash)) < 0) { ret = 0; goto finish; } \
844         { \
845                 GL_Object_Hash *object_hash = NULL; \
846                 FIND_HASH((hash_base), (int)(hash), object_hash); \
847                 if (object_hash == NULL) { ret = 0; goto finish; } \
848                 (object) = object_hash->item; \
849                 if ((object) == NULL) { ret = 0; goto finish; } \
850         }
851
852 GLuint
853 fastpath_sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
854 {
855         GLuint ret = _COREGL_INT_INIT_VALUE;
856
857         GL_Object_Hash_Base *hash_base = NULL;
858         GL_Object_Hash_Base *hash_base_real = NULL;
859         GL_Object *object = NULL;
860
861         hash_base = _get_shared_object_hash(sostate, type);
862         hash_base_real = _get_shared_object_hash_real(sostate, type);
863
864         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
865
866         object->ref_count--;
867
868         if (object->ref_count <= 0)
869         {
870                 GL_Object_Hash *object_hash = NULL;
871
872                 FIND_HASH(hash_base, object->id - (int)type, object_hash);
873                 AST(object_hash != NULL);
874                 _remove_hash(hash_base, object->id - (int)type);
875                 free(object_hash);
876                 object_hash = NULL;
877
878                 FIND_HASH(hash_base_real, object->real_id, object_hash);
879                 AST(object_hash != NULL);
880                 _remove_hash(hash_base_real, object->real_id);
881                 free(object_hash);
882                 object_hash = NULL;
883
884                 free(object);
885                 object = NULL;
886         }
887
888         ret = 1;
889         goto finish;
890
891 finish:
892         return ret;
893 }
894
895 GLuint
896 fastpath_sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
897 {
898         GLuint ret = _COREGL_INT_INIT_VALUE;
899
900         GL_Object_Hash_Base *hash_base = NULL;
901         GL_Object *object = NULL;
902
903         hash_base = _get_shared_object_hash(sostate, type);
904
905         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
906
907         ret = object->real_id;
908         goto finish;
909
910 finish:
911         return ret;
912 }
913
914 GLint
915 fastpath_sostate_set_object_tag(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name, GLvoid *tag)
916 {
917         GLint ret = _COREGL_INT_INIT_VALUE;
918
919         GL_Object_Hash_Base *hash_base = NULL;
920         GL_Object *object = NULL;
921         int hash = _COREGL_INT_INIT_VALUE;
922
923         hash_base = _get_shared_object_hash(sostate, type);
924
925         hash = glue_name - (int)type;
926
927         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object);
928
929         AST(object->tag == NULL);
930         object->tag = tag;
931         ret = 1;
932         goto finish;
933
934 finish:
935         return ret;
936 }
937
938 GLvoid *
939 fastpath_sostate_get_object_tag(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
940 {
941         GLvoid *ret = NULL;
942
943         GL_Object_Hash_Base *hash_base = NULL;
944         GL_Object *object = NULL;
945
946         hash_base = _get_shared_object_hash(sostate, type);
947
948         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
949
950         ret = object->tag;
951         goto finish;
952
953 finish:
954         return ret;
955 }
956
957 GLuint
958 fastpath_sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
959 {
960         GLuint ret = _COREGL_INT_INIT_VALUE;
961
962         GL_Object_Hash_Base *hash_base_real = NULL;
963         GL_Object *object = NULL;
964
965         hash_base_real = _get_shared_object_hash_real(sostate, type);
966
967         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base_real, real_name, object);
968
969         ret = object->id;
970         goto finish;
971
972 finish:
973         return ret;
974 }
975
976 GLint
977 fastpath_sostate_use_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
978 {
979         GLint ret = _COREGL_INT_INIT_VALUE;
980
981         GL_Object_Hash_Base *hash_base = NULL;
982         GL_Object *object = NULL;
983
984         hash_base = _get_shared_object_hash(sostate, type);
985
986         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
987
988         object->ref_count++;
989         ret = 1;
990         goto finish;
991
992 finish:
993         return ret;
994 }
995
996 void
997 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
998 {
999         static struct timeval tv_last = { 0, 0 };
1000
1001         if (unlikely(trace_state_flag != 1)) return;
1002
1003         if (!force_output)
1004         {
1005                 struct timeval tv_now = { 0, 0 };
1006                 AST(gettimeofday(&tv_now, NULL) == 0);
1007                 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
1008                 {
1009                         goto finish;
1010                 }
1011                 tv_last = tv_now;
1012         }
1013
1014         TRACE("\n");
1015         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1016         TRACE("\E[40;32;1m  State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
1017         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1018
1019 #define PRINTF_CHAR_GLenum "%10d"
1020 #define PRINTF_CHAR_GLboolean "%10d"
1021 #define PRINTF_CHAR_GLint "%10d"
1022 #define PRINTF_CHAR_GLsizei "%10u"
1023 #define PRINTF_CHAR_GLuint "%10u"
1024 #define PRINTF_CHAR_GLuintmask "0x%8X"
1025
1026 #define PRINTF_CHAR_GLclampf "%10.6f"
1027 #define PRINTF_CHAR_GLfloat "%10.6f"
1028
1029 #define PRINTF_CHAR_GLvoidptr "%10p"
1030
1031 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
1032
1033 #define INITIAL_CTX initial_ctx
1034 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1035    { \
1036       TYPE valuedata[SIZE]; \
1037       TYPE *value = NULL; \
1038       value = valuedata; GET_STMT; value = valuedata; \
1039       TRACE("\E[40;37;1m %-30.30s : (\E[0m ", #NAME); \
1040       for (int i = 0; i < SIZE; i++) \
1041       { \
1042          if (i > 0) { \
1043             if (i % 4 == 0) \
1044                TRACE("\n %-30.30s     ", "");\
1045             else \
1046                TRACE(", "); \
1047          } \
1048          TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
1049          TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
1050       } \
1051       TRACE(" \E[40;37;1m)\E[0m\n"); \
1052    }
1053 # include "coregl_fastpath_state.h"
1054 #undef GLUE_STATE
1055 #undef INITIAL_CTX
1056
1057         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1058         TRACE("\n");
1059
1060         TRACE_END();
1061
1062 finish:
1063         return;
1064 }
1065
1066 int
1067 fastpath_init_context_states(GLGlueContext *ctx)
1068 {
1069         int ret = 0;
1070
1071         AST(mutex_lock(&init_context_mutex) == 1);
1072
1073         if (ctx == NULL)
1074         {
1075                 COREGL_ERR("Context NULL\n");
1076                 ret = 0;
1077                 goto finish;
1078         }
1079
1080         AST(ctx->initialized == 0);
1081         AST(ctx->sostate != NULL);
1082
1083         if (initial_ctx == NULL)
1084         {
1085                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
1086                 AST(initial_ctx != NULL);
1087
1088 //#define FORCE_DEFAULT_VALUE
1089 #ifdef FORCE_DEFAULT_VALUE
1090 # define INITIAL_CTX initial_ctx
1091 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1092       { \
1093          int i; \
1094          TYPE valuedata[SIZE]; \
1095          TYPE *value = NULL; \
1096          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1097          value = valuedata; DEFAULT_STMT; value = valuedata; \
1098          for (i = 0; i < SIZE; i++) \
1099          { \
1100             if (*((char *)(&value[i])) == 0xcc) \
1101             { \
1102                memset(&value[i], 0xaa, sizeof(TYPE)); \
1103                value = valuedata; DEFAULT_STMT; value = valuedata; \
1104                if (*((char *)(&value[i])) == 0xaa) \
1105                { \
1106                   COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1107                   break; \
1108                } \
1109             } \
1110             initial_ctx->NAME[i] = value[i]; \
1111          } \
1112       }
1113 #  include "coregl_fastpath_state.h"
1114 # undef GLUE_STATE
1115 # undef INITIAL_CTX
1116 #else
1117 # define INITIAL_CTX initial_ctx
1118 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
1119       if (try_step == 1) \
1120       { \
1121          value = valuedata; DEFAULT_STMT; value = valuedata; \
1122       } \
1123       else \
1124       { \
1125          value = valuedata; FALLBACK_STMT; value = valuedata; \
1126       }
1127
1128 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1129       { \
1130          int i; \
1131          int try_step = 0;\
1132          TYPE valuedata[SIZE]; \
1133          TYPE *value = NULL; \
1134          _sym_glGetError(); \
1135          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1136          do { \
1137             try_step++; \
1138             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1139             if (_sym_glGetError() == GL_INVALID_ENUM) \
1140             { \
1141                                         initial_ctx->NAME##_used = 0; \
1142                                         value = valuedata; DEFAULT_STMT; value = valuedata; \
1143                     break; \
1144             } \
1145                                 initial_ctx->NAME##_used = 1; \
1146             for (i = 0; i < SIZE; i++) \
1147             { \
1148                if (*((char *)(&value[i])) == 0xcc) \
1149                { \
1150                   memset(&value[i], 0xaa, sizeof(TYPE)); \
1151                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1152                   if (*((char *)(&value[i])) == 0xaa) \
1153                   { \
1154                      try_step++; \
1155                      if (try_step == 2) \
1156                      { \
1157                         COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1158                      } \
1159                      break; \
1160                   } \
1161                } \
1162                initial_ctx->NAME[i] = value[i]; \
1163             } \
1164             if (try_step != 2) \
1165             { \
1166                value = valuedata; DEFAULT_STMT; value = valuedata; \
1167                for (i = 0; i < SIZE; i++) \
1168                { \
1169                   if (initial_ctx->NAME[i] != value[i]) \
1170                   { \
1171                      COREGL_WRN("GL-state '"#NAME"'[%d] value ["PRINTF_CHAR(TYPE)"] is different from SPEC-DEFAULT ["PRINTF_CHAR(TYPE)"]\n", i, initial_ctx->NAME[i], value[i]); \
1172                   } \
1173                } \
1174             } \
1175          } \
1176          while (try_step == 2); \
1177       }
1178 #  include "coregl_fastpath_state.h"
1179 # undef SET_GLUE_VALUE
1180 # undef GLUE_STATE
1181 # undef INITIAL_CTX
1182 #endif
1183
1184                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
1185                 {
1186                         COREGL_WRN("\E[40;31;1mNumber of vertex attrib is too big! (%d-%d)\E[0m\n", MAX_VERTEX_ATTRIBS, initial_ctx->gl_num_vertex_attribs[0]);
1187                 }
1188                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
1189                 {
1190                         COREGL_WRN("\E[40;31;1mNumber of texture unit is too big! (%d-%d)\E[0m\n", MAX_TEXTURE_UNITS, initial_ctx->gl_num_tex_units[0]);
1191                 }
1192         }
1193
1194         {
1195                 int i;
1196 #define INITIAL_CTX initial_ctx
1197 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1198          for (i = 0; i < SIZE; i++) \
1199          { \
1200             ctx->NAME[i] = initial_ctx->NAME[i]; \
1201             ctx->NAME##_used = initial_ctx->NAME##_used; \
1202          }
1203 # include "coregl_fastpath_state.h"
1204 #undef GLUE_STATE
1205 #undef INITIAL_CTX
1206         }
1207
1208         ctx->initialized = 1;
1209         ret = 1;
1210         goto finish;
1211
1212 finish:
1213         AST(mutex_unlock(&init_context_mutex) == 1);
1214
1215         return ret;
1216 }
1217
1218 #ifdef COREGL_USE_MODULE_TRACEPATH
1219 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
1220 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
1221 #endif
1222
1223 #define CHECK_GL_ERROR(func) \
1224         { \
1225                 func; \
1226                 int err = _orig_fastpath_glGetError(); \
1227                 if (err != GL_NO_ERROR) \
1228                 { \
1229                         COREGL_ERR("\E[40;31;1m(GL %p) : %s returns GL error 0x%X\E[0m\n", oldctx->cstate, #func, err); \
1230                         goto finish; \
1231                 } \
1232         }
1233
1234 int
1235 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
1236 {
1237         int ret = 0;
1238         unsigned char flag = 0;
1239         int i = 0;
1240
1241         if (debug_nofp == 1)
1242         {
1243                 ret = 1;
1244                 goto finish;
1245         }
1246
1247         // Return if they're the same
1248         if (oldctx == newctx)
1249         {
1250                 ret = 1;
1251                 goto finish;
1252         }
1253
1254 #define STATE_COMPARE(state) \
1255    if ((oldctx->state) != (newctx->state))
1256
1257 #define STATES_COMPARE(state_ptr, bytes) \
1258    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
1259
1260
1261 #ifdef COREGL_USE_MODULE_TRACEPATH
1262         static void *trace_hint_glfinish = NULL;
1263         trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
1264 #endif // COREGL_USE_MODULE_TRACEPATH
1265
1266         {
1267                 int err = _orig_fastpath_glGetError();
1268                 if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR)
1269                         oldctx->gl_error = err;
1270         }
1271
1272         CHECK_GL_ERROR(_orig_fastpath_glFlush())
1273
1274 #ifdef COREGL_USE_MODULE_TRACEPATH
1275         tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
1276 #endif // COREGL_USE_MODULE_TRACEPATH
1277
1278 #ifdef COREGL_USE_MODULE_TRACEPATH
1279         static void *trace_hint_bindbuffers = NULL;
1280         trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
1281 #endif // COREGL_USE_MODULE_TRACEPATH
1282
1283
1284         //------------------//
1285         // _bind_flag
1286         flag = oldctx->_bind_flag | newctx->_bind_flag;
1287         if (flag)
1288         {
1289                 STATE_COMPARE(gl_array_buffer_binding[0])
1290                 {
1291                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]))
1292                 }
1293                 STATE_COMPARE(gl_element_array_buffer_binding[0])
1294                 {
1295                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]))
1296                 }
1297                 // ANGLE_framebuffer_blit BEGIN
1298                 if (newctx->gl_framebuffer_binding_read_used == 1)
1299                 {
1300                         STATE_COMPARE(gl_framebuffer_binding_read[0])
1301                         {
1302                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, newctx->gl_framebuffer_binding_read[0]))
1303                         }
1304                         STATE_COMPARE(gl_framebuffer_binding_draw[0])
1305                         {
1306                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, newctx->gl_framebuffer_binding_draw[0]))
1307                         }
1308                 }
1309                 else
1310                 // ANGLE_framebuffer_blit END
1311                 {
1312                         STATE_COMPARE(gl_framebuffer_binding[0])
1313                         {
1314                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]))
1315                         }
1316                 }
1317                 STATE_COMPARE(gl_renderbuffer_binding[0])
1318                 {
1319                         CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]))
1320                 }
1321         }
1322
1323 #ifdef COREGL_USE_MODULE_TRACEPATH
1324         tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
1325 #endif // COREGL_USE_MODULE_TRACEPATH
1326
1327
1328         //------------------//
1329         // Enable States
1330         // _enable_flag1
1331 #ifdef COREGL_USE_MODULE_TRACEPATH
1332         static void *trace_hint_enable_states = NULL;
1333         trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
1334 #endif // COREGL_USE_MODULE_TRACEPATH
1335
1336         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
1337         if (flag)
1338         {
1339                 STATE_COMPARE(gl_blend[0])
1340                 {
1341                         if (newctx->gl_blend[0])
1342                         {
1343                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
1344                         }
1345                         else
1346                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
1347                         }
1348                 STATE_COMPARE(gl_cull_face[0])
1349                 {
1350                         if (newctx->gl_cull_face[0])
1351                         {
1352                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
1353                         }
1354                         else
1355                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
1356                         }
1357                 STATE_COMPARE(gl_depth_test[0])
1358                 {
1359                         if (newctx->gl_depth_test[0])
1360                         {
1361                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
1362                         }
1363                         else
1364                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
1365                         }
1366                 STATE_COMPARE(gl_dither[0])
1367                 {
1368                         if (newctx->gl_dither[0])
1369                         {
1370                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
1371                         }
1372                         else
1373                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
1374                         }
1375         }
1376
1377         // _enable_flag2
1378         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
1379         if (flag)
1380         {
1381                 STATE_COMPARE(gl_polygon_offset_fill[0])
1382                 {
1383                         if (newctx->gl_polygon_offset_fill[0])
1384                         {
1385                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
1386                         }
1387                         else
1388                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
1389                         }
1390                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
1391                 {
1392                         if (newctx->gl_sample_alpha_to_coverage[0])
1393                         {
1394                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1395                         }
1396                         else
1397                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1398                         }
1399                 STATE_COMPARE(gl_sample_coverage[0])
1400                 {
1401                         if (newctx->gl_sample_coverage[0])
1402                         {
1403                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
1404                         }
1405                         else
1406                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
1407                         }
1408                 STATE_COMPARE(gl_scissor_test[0])
1409                 {
1410                         if (newctx->gl_scissor_test[0])
1411                         {
1412                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
1413                         }
1414                         else
1415                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
1416                         }
1417                 STATE_COMPARE(gl_stencil_test[0])
1418                 {
1419                         if (newctx->gl_stencil_test[0])
1420                         {
1421                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
1422                         }
1423                         else
1424                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
1425                         }
1426         }
1427
1428 #ifdef COREGL_USE_MODULE_TRACEPATH
1429         tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
1430 #endif // COREGL_USE_MODULE_TRACEPATH
1431
1432         //------------------//
1433         // _clear_flag1
1434 #ifdef COREGL_USE_MODULE_TRACEPATH
1435         static void *trace_hint_clear_viewport = NULL;
1436         trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1437 #endif // COREGL_USE_MODULE_TRACEPATH
1438
1439         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
1440         if (flag)
1441         {
1442                 // Viewport.
1443                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
1444                 {
1445                         CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
1446                                        newctx->gl_viewport[1],
1447                                        newctx->gl_viewport[2],
1448                                        newctx->gl_viewport[3]))
1449                 }
1450
1451                 STATE_COMPARE(gl_current_program[0])
1452                 {
1453                         CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
1454                 }
1455                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
1456                 {
1457                         CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
1458                                        newctx->gl_color_clear_value[1],
1459                                        newctx->gl_color_clear_value[2],
1460                                        newctx->gl_color_clear_value[3]))
1461                 }
1462         }
1463
1464
1465         // _clear_flag2
1466         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
1467         if (flag)
1468         {
1469                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
1470                 {
1471                         CHECK_GL_ERROR(_orig_fastpath_glColorMask(newctx->gl_color_writemask[0],
1472                                        newctx->gl_color_writemask[1],
1473                                        newctx->gl_color_writemask[2],
1474                                        newctx->gl_color_writemask[3]))
1475                 }
1476                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
1477                 {
1478                         CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
1479                                        newctx->gl_depth_range[1]))
1480                 }
1481                 STATE_COMPARE(gl_depth_clear_value[0])
1482                 {
1483                         CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
1484                 }
1485                 STATE_COMPARE(gl_depth_func[0])
1486                 {
1487                         CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
1488                 }
1489                 STATE_COMPARE(gl_depth_writemask[0])
1490                 {
1491                         CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
1492                 }
1493                 STATE_COMPARE(gl_cull_face_mode[0])
1494                 {
1495                         CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
1496                 }
1497
1498         }
1499
1500 #ifdef COREGL_USE_MODULE_TRACEPATH
1501         tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1502 #endif // COREGL_USE_MODULE_TRACEPATH
1503
1504         //------------------//
1505         // Texture here...
1506 #ifdef COREGL_USE_MODULE_TRACEPATH
1507         static void *trace_hint_bind_textures = NULL;
1508         trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1509 #endif // COREGL_USE_MODULE_TRACEPATH
1510
1511         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1512         if (flag)
1513         {
1514
1515                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1516                 {
1517                         STATE_COMPARE(gl_tex_2d_state[i])
1518                         {
1519                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1520                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]))
1521                         }
1522
1523                         STATE_COMPARE(gl_tex_cube_state[i])
1524                         {
1525                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1526                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]))
1527                         }
1528                 }
1529
1530                 // Restore active texture
1531                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
1532
1533                 STATE_COMPARE(gl_generate_mipmap_hint[0])
1534                 {
1535                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]))
1536                 }
1537         }
1538 #ifdef COREGL_USE_MODULE_TRACEPATH
1539         tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1540 #endif // COREGL_USE_MODULE_TRACEPATH
1541
1542         //------------------//
1543 #ifdef COREGL_USE_MODULE_TRACEPATH
1544         static void *trace_hint_etc = NULL;
1545         trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1546 #endif // COREGL_USE_MODULE_TRACEPATH
1547
1548         flag = oldctx->_blend_flag | newctx->_blend_flag;
1549         if (flag)
1550         {
1551                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1552                 {
1553                         CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
1554                                        newctx->gl_blend_color[1],
1555                                        newctx->gl_blend_color[2],
1556                                        newctx->gl_blend_color[3]))
1557                 }
1558                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1559                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1560                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1561                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1562                 {
1563                         CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1564                                        newctx->gl_blend_dst_rgb[0],
1565                                        newctx->gl_blend_src_alpha[0],
1566                                        newctx->gl_blend_dst_alpha[0]))
1567                 }
1568                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1569                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1570                 {
1571                         CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]))
1572                 }
1573
1574         }
1575
1576         //------------------//
1577         // _stencil_flag1
1578         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1579         if (flag)
1580         {
1581                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1582                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
1583                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1584                 {
1585                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
1586                                        newctx->gl_stencil_func[0],
1587                                        newctx->gl_stencil_ref[0],
1588                                        newctx->gl_stencil_value_mask[0]))
1589                 }
1590                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1591                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1592                     (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1593                 {
1594                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
1595                                        newctx->gl_stencil_fail[0],
1596                                        newctx->gl_stencil_pass_depth_fail[0],
1597                                        newctx->gl_stencil_pass_depth_pass[0]))
1598                 }
1599
1600                 STATE_COMPARE(gl_stencil_writemask[0])
1601                 {
1602                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]))
1603                 }
1604         }
1605
1606
1607         // _stencil_flag1
1608         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1609         if (flag)
1610         {
1611                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1612                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
1613                     (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1614                 {
1615                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
1616                                        newctx->gl_stencil_back_func[0],
1617                                        newctx->gl_stencil_back_ref[0],
1618                                        newctx->gl_stencil_back_value_mask[0]))
1619                 }
1620                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1621                     (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1622                     (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1623                 {
1624                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
1625                                        newctx->gl_stencil_back_fail[0],
1626                                        newctx->gl_stencil_back_pass_depth_fail[0],
1627                                        newctx->gl_stencil_back_pass_depth_pass[0]))
1628                 }
1629
1630                 STATE_COMPARE(gl_stencil_back_writemask[0])
1631                 {
1632                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]))
1633                 }
1634                 STATE_COMPARE(gl_stencil_clear_value[0])
1635                 {
1636                         CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
1637                 }
1638         }
1639
1640         //------------------//
1641         // _misc_flag1
1642         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1643         if (flag)
1644         {
1645                 STATE_COMPARE(gl_front_face[0])
1646                 {
1647                         CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
1648                 }
1649                 STATE_COMPARE(gl_line_width[0])
1650                 {
1651                         CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
1652                 }
1653                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1654                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0]))
1655                 {
1656                         CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1657                                        newctx->gl_polygon_offset_units[0]))
1658                 }
1659                 if ((oldctx->gl_sample_coverage_value[0]  != newctx->gl_sample_coverage_value[0]) ||
1660                     (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1661                 {
1662                         CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1663                                        newctx->gl_sample_coverage_invert[0]))
1664                 }
1665                 STATE_COMPARE(gl_fragment_shader_derivative_hint[0])
1666                 {
1667                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, newctx->gl_fragment_shader_derivative_hint[0]))
1668                 }
1669         }
1670
1671         // _misc_flag2
1672         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1673         if (flag)
1674         {
1675                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1676                 {
1677                         CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
1678                                                                 newctx->gl_scissor_box[1],
1679                                                                 newctx->gl_scissor_box[2],
1680                                                                 newctx->gl_scissor_box[3]))
1681                 }
1682                 STATE_COMPARE(gl_pack_alignment[0])
1683                 {
1684                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]))
1685                 }
1686                 STATE_COMPARE(gl_unpack_alignment[0])
1687                 {
1688                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]))
1689                 }
1690         }
1691 #ifdef COREGL_USE_MODULE_TRACEPATH
1692         tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1693 #endif // COREGL_USE_MODULE_TRACEPATH
1694
1695         // _varray_flag
1696 #ifdef COREGL_USE_MODULE_TRACEPATH
1697         static void *trace_hint_vertex_attrib = NULL;
1698         trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1699 #endif // COREGL_USE_MODULE_TRACEPATH
1700
1701         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1702         if (flag)
1703         {
1704                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1705                 {
1706                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1707                         {
1708                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]))
1709                         }
1710                         else
1711                         {
1712                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
1713                         }
1714
1715                         CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
1716                                        newctx->gl_vertex_array_size[i],
1717                                        newctx->gl_vertex_array_type[i],
1718                                        newctx->gl_vertex_array_normalized[i],
1719                                        newctx->gl_vertex_array_stride[i],
1720                                        newctx->gl_vertex_array_pointer[i]))
1721
1722                         STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
1723                         {
1724                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]))
1725                         }
1726
1727                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1728                         {
1729                                 CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
1730                         }
1731                         else
1732                         {
1733                                 CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
1734                         }
1735                 }
1736
1737                 STATE_COMPARE(gl_array_buffer_binding[0])
1738                 {
1739                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]))
1740                 }
1741                 STATE_COMPARE(gl_element_array_buffer_binding[0])
1742                 {
1743                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]))
1744                 }
1745
1746         }
1747
1748 #ifdef COREGL_USE_MODULE_TRACEPATH
1749         tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1750 #endif // COREGL_USE_MODULE_TRACEPATH
1751
1752         ret = 1;
1753         goto finish;
1754
1755 finish:
1756
1757 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1758         if (unlikely(trace_state_flag == 1))
1759                 fastpath_dump_context_states(newctx, 0);
1760 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1761         return ret;
1762 #undef STATE_COMPARE
1763 #undef STATES_COMPARE
1764 }
1765