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