Merge "Add coding style guide. Apply coding style." into tizen
[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(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 static int          api_gl_version = COREGL_GLAPI_2;
30
31 static void
32 _state_get_texture_states(GLenum pname, GLint *params)
33 {
34         GLuint cur_active_tex = 0;
35
36         AST(initial_ctx != NULL);
37
38         _orig_fastpath_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
39         int i;
40         for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++) {
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         AST(initial_ctx != NULL);
51
52         int i;
53         for (i = 0; i < initial_ctx->gl_num_draw_buffers[0]; i++) {
54                 _orig_fastpath_glGetIntegerv(GL_DRAW_BUFFER0 + i, (GLint *)&params[i]);
55         }
56 }
57
58 static void
59 _state_get_transform_feedback_buffer_bindings(GLuint *params)
60 {
61         AST(initial_ctx != NULL);
62
63         int i;
64         for (i = 0; i < initial_ctx->gl_num_transform_feedback_separate_attribs[0];
65              i++) {
66                 _orig_fastpath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i,
67                                                (GLint *)&params[i]);
68         }
69 }
70
71 static void
72 _state_get_transform_feedback_buffer_bindings_offset(GLintptr *params)
73 {
74         AST(initial_ctx != NULL);
75
76         int i;
77         for (i = 0; i < initial_ctx->gl_num_transform_feedback_separate_attribs[0];
78              i++) {
79                 _orig_fastpath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_START, i,
80                                                (GLint *)&params[i]);
81         }
82 }
83
84 static void
85 _state_get_transform_feedback_buffer_bindings_size(GLsizeiptr *params)
86 {
87         AST(initial_ctx != NULL);
88
89         int i;
90         for (i = 0; i < initial_ctx->gl_num_transform_feedback_separate_attribs[0];
91              i++) {
92                 _orig_fastpath_glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i,
93                                                (GLint *)&params[i]);
94         }
95 }
96
97 static void
98 _state_get_uniform_buffer_bindings(GLuint *params)
99 {
100         AST(initial_ctx != NULL);
101
102         int i;
103         for (i = 0; i < initial_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
104 /////////////////////////////////////////////////////////////////////////////////
105 // XXXX : AVOID SEGFAULT in ADRENO
106                 ((GLint *)params)[i] = 0;
107 //              _orig_fastpath_glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint *)&params[i]);
108 /////////////////////////////////////////////////////////////////////////////////
109         }
110 }
111
112 static void
113 _state_get_uniform_buffer_bindings_offset(GLintptr *params)
114 {
115         AST(initial_ctx != NULL);
116
117         int i;
118         for (i = 0; i < initial_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
119                 _orig_fastpath_glGetIntegeri_v(GL_UNIFORM_BUFFER_START, i, (GLint *)&params[i]);
120         }
121 }
122
123 static void
124 _state_get_uniform_buffer_bindings_size(GLsizeiptr *params)
125 {
126         AST(initial_ctx != NULL);
127
128         int i;
129         for (i = 0; i < initial_ctx->gl_num_uniform_buffer_bindings[0]; i++) {
130                 _orig_fastpath_glGetIntegeri_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint *)&params[i]);
131         }
132 }
133
134 void
135 fastpath_state_get_draw_buffers(GLenum *params)
136 {
137         _state_get_draw_buffers(params);
138 }
139
140 void
141 init_modules_fastpath()
142 {
143         int fastpath_opt = 0;
144         int fastpath_force_off_opt = 0;
145
146         COREGL_LOG("[CoreGL] <Fastpath> : ");
147
148         fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
149         fastpath_force_off_opt = atoi(get_env_setting("COREGL_FASTPATH_FORCE_OFF"));
150
151         if (fastpath_force_off_opt == 1) {
152                 COREGL_LOG("\E[40;31;1m(DISABLED by force option)\E[0m ");
153                 fastpath_opt = 0;
154         }
155
156         switch (fastpath_opt) {
157         case 1:
158                 COREGL_LOG("(%d) Fastpath enabled...\n", fastpath_opt);
159                 fp_opt = FP_FAST_PATH;
160                 break;
161         default:
162                 COREGL_LOG("(%d) Default API path enabled...\n", fastpath_opt);
163                 fp_opt = FP_NORMAL_PATH;
164                 break;
165         }
166
167         debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
168
169 }
170
171 void
172 deinit_modules_fastpath()
173 {
174         GLContext_List *current = NULL;
175
176         AST(mutex_lock(&ctx_list_access_mutex) == 1);
177
178         // Destroy remained context & Detect leaks
179         int retry_destroy = 0;
180
181         while (1) {
182                 retry_destroy = 0;
183                 current = glctx_list;
184                 while (current) {
185                         if (current->cstate != NULL) {
186                                 COREGL_WRN("\E[40;31;1mContext attached to [dpy=%p|rctx=%p] has not been completely destroyed.(leak)\E[0m\n",
187                                            current->cstate->rdpy, current->cstate->rctx);
188
189                                 _orig_fastpath_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE,
190                                                               EGL_NO_SURFACE, EGL_NO_CONTEXT);
191                                 _orig_fastpath_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
192
193                                 fastpath_remove_context_states_from_list(current->cstate, NULL);
194                                 retry_destroy = 1;
195                                 break;
196                         }
197
198                         glctx_list = current->next;
199                         free(current);
200                         current = glctx_list;
201                 }
202                 if (retry_destroy == 0) break;
203         }
204         goto finish;
205
206 finish:
207         AST(mutex_unlock(&ctx_list_access_mutex) == 1);
208 }
209
210 void
211 init_modules_tstate_fastpath(GLThreadState *tstate)
212 {
213         MY_MODULE_TSTATE *tstate_mt = NULL;
214
215         tstate_mt = (MY_MODULE_TSTATE *)calloc(1, sizeof(MY_MODULE_TSTATE));
216
217         tstate_mt->binded_api = EGL_OPENGL_ES_API;
218
219         tstate->module_data[MY_MODULE_ID] = tstate_mt;
220 }
221
222 void
223 deinit_modules_tstate_fastpath(GLThreadState *tstate)
224 {
225         if (tstate->module_data[MY_MODULE_ID] != NULL) {
226                 free(tstate->module_data[MY_MODULE_ID]);
227                 tstate->module_data[MY_MODULE_ID] = NULL;
228         }
229 }
230
231 void
232 fastpath_apply_overrides()
233 {
234         switch (fp_opt) {
235         case FP_FAST_PATH:
236                 fastpath_apply_overrides_egl(1);
237                 fastpath_apply_overrides_gl(1);
238                 break;
239         case FP_NORMAL_PATH:
240                 break;
241         default:
242                 COREGL_ERR("Invalide GL Override Option!!!\n");
243                 break;
244         }
245 }
246
247
248 void
249 fastpath_apply_overrides_egl(int enable)
250 {
251 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST)     COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
252 # include "../../headers/sym_egl.h"
253 #undef _COREGL_SYMBOL
254
255         COREGL_OVERRIDE(fastpath_, eglGetProcAddress);
256
257         COREGL_OVERRIDE(fastpath_, eglBindAPI);
258         COREGL_OVERRIDE(fastpath_, eglQueryAPI);
259
260         COREGL_OVERRIDE(fastpath_, eglCreateContext);
261         COREGL_OVERRIDE(fastpath_, eglCreateImageKHR);
262         COREGL_OVERRIDE(fastpath_, eglMakeCurrent);
263         COREGL_OVERRIDE(fastpath_, eglDestroyContext);
264         COREGL_OVERRIDE(fastpath_, eglQueryContext);
265         COREGL_OVERRIDE(fastpath_, eglGetCurrentContext);
266         COREGL_OVERRIDE(fastpath_, eglReleaseThread);
267         COREGL_OVERRIDE(fastpath_, eglGetCurrentSurface);
268         COREGL_OVERRIDE(fastpath_, eglTerminate);
269         COREGL_OVERRIDE(fastpath_, eglGetCurrentDisplay);
270
271 }
272
273 void
274 fastpath_apply_overrides_gl(int enable)
275 {
276 #define _COREGL_START_API(version) api_gl_version = version;
277 #define _COREGL_END_API(version) api_gl_version = COREGL_GLAPI_2;
278 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST)     \
279    if(api_gl_version <= driver_gl_version) COREGL_INIT_ORIGINAL(_orig_fastpath_, FUNC_NAME);
280
281 # include "../../headers/sym_gl.h"
282 #undef _COREGL_SYMBOL
283 #undef _COREGL_START_API
284 #undef _COREGL_END_API
285
286         if (debug_nofp != 1) {
287                 COREGL_OVERRIDE(fastpath_, glGetError);
288                 COREGL_OVERRIDE(fastpath_, glGetString);
289
290                 COREGL_OVERRIDE(fastpath_, glGetIntegerv);
291                 COREGL_OVERRIDE(fastpath_, glGetFloatv);
292                 COREGL_OVERRIDE(fastpath_, glGetBooleanv);
293
294                 COREGL_OVERRIDE(fastpath_, glActiveTexture);
295                 COREGL_OVERRIDE(fastpath_, glGenTextures);
296                 COREGL_OVERRIDE(fastpath_, glBindTexture);
297                 COREGL_OVERRIDE(fastpath_, glIsTexture);
298                 COREGL_OVERRIDE(fastpath_, glDeleteTextures);
299                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2D);
300
301                 COREGL_OVERRIDE(fastpath_, glGenBuffers);
302                 COREGL_OVERRIDE(fastpath_, glBindBuffer);
303                 COREGL_OVERRIDE(fastpath_, glIsBuffer);
304                 COREGL_OVERRIDE(fastpath_, glDeleteBuffers);
305
306                 COREGL_OVERRIDE(fastpath_, glGenFramebuffers);
307                 COREGL_OVERRIDE(fastpath_, glBindFramebuffer);
308                 COREGL_OVERRIDE(fastpath_, glIsFramebuffer);
309                 COREGL_OVERRIDE(fastpath_, glDeleteFramebuffers);
310                 COREGL_OVERRIDE(fastpath_, glGetFramebufferAttachmentParameteriv);
311
312                 COREGL_OVERRIDE(fastpath_, glGenRenderbuffers);
313                 COREGL_OVERRIDE(fastpath_, glBindRenderbuffer);
314                 COREGL_OVERRIDE(fastpath_, glFramebufferRenderbuffer);
315                 COREGL_OVERRIDE(fastpath_, glIsRenderbuffer);
316                 COREGL_OVERRIDE(fastpath_, glDeleteRenderbuffers);
317
318                 COREGL_OVERRIDE(fastpath_, glCreateShader);
319                 COREGL_OVERRIDE(fastpath_, glCreateProgram);
320                 COREGL_OVERRIDE(fastpath_, glAttachShader);
321                 COREGL_OVERRIDE(fastpath_, glCompileShader);
322                 COREGL_OVERRIDE(fastpath_, glShaderBinary);
323                 COREGL_OVERRIDE(fastpath_, glDeleteShader);
324                 COREGL_OVERRIDE(fastpath_, glDetachShader);
325                 COREGL_OVERRIDE(fastpath_, glGetShaderiv);
326                 COREGL_OVERRIDE(fastpath_, glGetShaderInfoLog);
327                 COREGL_OVERRIDE(fastpath_, glGetShaderSource);
328                 COREGL_OVERRIDE(fastpath_, glIsShader);
329                 COREGL_OVERRIDE(fastpath_, glShaderSource);
330                 COREGL_OVERRIDE(fastpath_, glBindAttribLocation);
331                 COREGL_OVERRIDE(fastpath_, glDeleteProgram);
332                 COREGL_OVERRIDE(fastpath_, glGetActiveAttrib);
333                 COREGL_OVERRIDE(fastpath_, glGetActiveUniform);
334                 COREGL_OVERRIDE(fastpath_, glGetAttachedShaders);
335                 COREGL_OVERRIDE(fastpath_, glGetAttribLocation);
336                 COREGL_OVERRIDE(fastpath_, glGetProgramiv);
337                 COREGL_OVERRIDE(fastpath_, glGetProgramInfoLog);
338                 COREGL_OVERRIDE(fastpath_, glGetUniformfv);
339                 COREGL_OVERRIDE(fastpath_, glGetUniformiv);
340                 COREGL_OVERRIDE(fastpath_, glGetUniformLocation);
341                 COREGL_OVERRIDE(fastpath_, glIsProgram);
342                 COREGL_OVERRIDE(fastpath_, glLinkProgram);
343                 COREGL_OVERRIDE(fastpath_, glUseProgram);
344                 COREGL_OVERRIDE(fastpath_, glValidateProgram);
345
346                 COREGL_OVERRIDE(fastpath_, glBlendColor);
347                 COREGL_OVERRIDE(fastpath_, glBlendEquation);
348                 COREGL_OVERRIDE(fastpath_, glBlendEquationSeparate);
349                 COREGL_OVERRIDE(fastpath_, glBlendFunc);
350                 COREGL_OVERRIDE(fastpath_, glBlendFuncSeparate);
351                 COREGL_OVERRIDE(fastpath_, glClearColor);
352                 COREGL_OVERRIDE(fastpath_, glClearDepthf);
353                 COREGL_OVERRIDE(fastpath_, glClearStencil);
354                 COREGL_OVERRIDE(fastpath_, glColorMask);
355                 COREGL_OVERRIDE(fastpath_, glCullFace);
356                 COREGL_OVERRIDE(fastpath_, glDepthFunc);
357                 COREGL_OVERRIDE(fastpath_, glDepthMask);
358                 COREGL_OVERRIDE(fastpath_, glDepthRangef);
359                 COREGL_OVERRIDE(fastpath_, glDisable);
360                 COREGL_OVERRIDE(fastpath_, glDisableVertexAttribArray);
361                 COREGL_OVERRIDE(fastpath_, glEnable);
362                 COREGL_OVERRIDE(fastpath_, glEnableVertexAttribArray);
363                 COREGL_OVERRIDE(fastpath_, glFrontFace);
364                 COREGL_OVERRIDE(fastpath_, glHint);
365                 COREGL_OVERRIDE(fastpath_, glLineWidth);
366                 COREGL_OVERRIDE(fastpath_, glPixelStorei);
367                 COREGL_OVERRIDE(fastpath_, glPolygonOffset);
368                 COREGL_OVERRIDE(fastpath_, glSampleCoverage);
369                 COREGL_OVERRIDE(fastpath_, glScissor);
370                 COREGL_OVERRIDE(fastpath_, glStencilFunc);
371                 COREGL_OVERRIDE(fastpath_, glStencilFuncSeparate);
372                 COREGL_OVERRIDE(fastpath_, glStencilMask);
373                 COREGL_OVERRIDE(fastpath_, glStencilMaskSeparate);
374                 COREGL_OVERRIDE(fastpath_, glStencilOp);
375                 COREGL_OVERRIDE(fastpath_, glStencilOpSeparate);
376                 COREGL_OVERRIDE(fastpath_, glVertexAttrib1f);
377                 COREGL_OVERRIDE(fastpath_, glVertexAttrib1fv);
378                 COREGL_OVERRIDE(fastpath_, glVertexAttrib2f);
379                 COREGL_OVERRIDE(fastpath_, glVertexAttrib2fv);
380                 COREGL_OVERRIDE(fastpath_, glVertexAttrib3f);
381                 COREGL_OVERRIDE(fastpath_, glVertexAttrib3fv);
382                 COREGL_OVERRIDE(fastpath_, glVertexAttrib4f);
383                 COREGL_OVERRIDE(fastpath_, glVertexAttrib4fv);
384                 COREGL_OVERRIDE(fastpath_, glVertexAttribPointer);
385                 COREGL_OVERRIDE(fastpath_, glViewport);
386
387                 COREGL_OVERRIDE(fastpath_, glGetProgramBinaryOES);
388                 COREGL_OVERRIDE(fastpath_, glProgramBinaryOES);
389
390                 COREGL_OVERRIDE(fastpath_, glUseProgramStagesEXT);
391                 COREGL_OVERRIDE(fastpath_, glActiveShaderProgramEXT);
392                 COREGL_OVERRIDE(fastpath_, glProgramParameteriEXT);
393                 COREGL_OVERRIDE(fastpath_, glProgramUniform1iEXT);
394                 COREGL_OVERRIDE(fastpath_, glProgramUniform2iEXT);
395                 COREGL_OVERRIDE(fastpath_, glProgramUniform3iEXT);
396                 COREGL_OVERRIDE(fastpath_, glProgramUniform4iEXT);
397                 COREGL_OVERRIDE(fastpath_, glProgramUniform1fEXT);
398                 COREGL_OVERRIDE(fastpath_, glProgramUniform2fEXT);
399                 COREGL_OVERRIDE(fastpath_, glProgramUniform3fEXT);
400                 COREGL_OVERRIDE(fastpath_, glProgramUniform4fEXT);
401                 COREGL_OVERRIDE(fastpath_, glProgramUniform1ivEXT);
402                 COREGL_OVERRIDE(fastpath_, glProgramUniform2ivEXT);
403                 COREGL_OVERRIDE(fastpath_, glProgramUniform3ivEXT);
404                 COREGL_OVERRIDE(fastpath_, glProgramUniform4ivEXT);
405                 COREGL_OVERRIDE(fastpath_, glProgramUniform1fvEXT);
406                 COREGL_OVERRIDE(fastpath_, glProgramUniform2fvEXT);
407                 COREGL_OVERRIDE(fastpath_, glProgramUniform3fvEXT);
408                 COREGL_OVERRIDE(fastpath_, glProgramUniform4fvEXT);
409                 COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix2fvEXT);
410                 COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix3fvEXT);
411                 COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix4fvEXT);
412
413                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2DMultisampleEXT);
414                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture3DOES);
415
416                 COREGL_OVERRIDE(fastpath_, glBindFramebufferOES);
417                 COREGL_OVERRIDE(fastpath_, glBindRenderbufferOES);
418                 COREGL_OVERRIDE(fastpath_, glClearBufferfi);
419                 COREGL_OVERRIDE(fastpath_, glClearBufferfv);
420                 COREGL_OVERRIDE(fastpath_, glClearBufferiv);
421                 COREGL_OVERRIDE(fastpath_, glClearBufferuiv);
422                 COREGL_OVERRIDE(fastpath_, glDeleteFramebuffersOES);
423                 COREGL_OVERRIDE(fastpath_, glDeleteRenderbuffersOES);
424                 COREGL_OVERRIDE(fastpath_, glDepthRangefOES);
425                 COREGL_OVERRIDE(fastpath_, glDepthRangexOES);
426                 COREGL_OVERRIDE(fastpath_, glFramebufferParameteri);
427                 COREGL_OVERRIDE(fastpath_, glGetFramebufferParameteriv);
428                 COREGL_OVERRIDE(fastpath_, glFramebufferRenderbufferOES);
429                 COREGL_OVERRIDE(fastpath_, glFramebufferTexture2DOES);
430                 COREGL_OVERRIDE(fastpath_, glGenFramebuffersOES);
431                 COREGL_OVERRIDE(fastpath_, glGenRenderbuffersOES);
432                 COREGL_OVERRIDE(fastpath_, glGetFramebufferAttachmentParameterivOES);
433                 COREGL_OVERRIDE(fastpath_, glGetQueryObjecti64vEXT);
434                 COREGL_OVERRIDE(fastpath_, glGetQueryObjectivEXT);
435                 COREGL_OVERRIDE(fastpath_, glGetQueryObjectui64vEXT);
436                 COREGL_OVERRIDE(fastpath_, glGetQueryObjectuivEXT);
437                 COREGL_OVERRIDE(fastpath_, glGetQueryivEXT);
438                 COREGL_OVERRIDE(fastpath_, glBeginQueryEXT);
439                 COREGL_OVERRIDE(fastpath_, glDeleteQueriesEXT);
440                 COREGL_OVERRIDE(fastpath_, glGenQueriesEXT);
441                 COREGL_OVERRIDE(fastpath_, glIsFramebufferOES);
442                 COREGL_OVERRIDE(fastpath_, glIsQueryEXT);
443                 COREGL_OVERRIDE(fastpath_, glIsRenderbufferOES);
444                 COREGL_OVERRIDE(fastpath_, glBlendEquationOES);
445                 COREGL_OVERRIDE(fastpath_, glBlendEquationSeparateOES);
446                 COREGL_OVERRIDE(fastpath_, glBlendFuncSeparateOES);
447                 COREGL_OVERRIDE(fastpath_, glPolygonOffsetxOES);
448                 COREGL_OVERRIDE(fastpath_, glLineWidthxOES);
449                 COREGL_OVERRIDE(fastpath_, glSampleCoveragexOES);
450                 COREGL_OVERRIDE(fastpath_, glQueryCounterEXT);
451                 COREGL_OVERRIDE(fastpath_, glBindVertexArrayOES);
452                 COREGL_OVERRIDE(fastpath_, glDeleteVertexArraysOES);
453                 COREGL_OVERRIDE(fastpath_, glGenVertexArraysOES);
454                 COREGL_OVERRIDE(fastpath_, glIsVertexArrayOES);
455                 COREGL_OVERRIDE(fastpath_, glClearDepthfOES );
456                 COREGL_OVERRIDE(fastpath_, glClearDepthxOES );
457                 /* Start overriding GLES 3.0 */
458                 if (driver_gl_version >= COREGL_GLAPI_3) {
459                         COREGL_OVERRIDE(fastpath_, glReadBuffer);
460
461                         COREGL_OVERRIDE(fastpath_, glGenQueries);
462                         COREGL_OVERRIDE(fastpath_, glDeleteQueries);
463                         COREGL_OVERRIDE(fastpath_, glIsQuery);
464                         COREGL_OVERRIDE(fastpath_, glBeginQuery);
465                         COREGL_OVERRIDE(fastpath_, glGetQueryiv);
466                         COREGL_OVERRIDE(fastpath_, glGetQueryObjectuiv);
467                         COREGL_OVERRIDE(fastpath_, glDrawBuffers);
468                         COREGL_OVERRIDE(fastpath_, glFramebufferTextureLayer);
469
470                         COREGL_OVERRIDE(fastpath_, glBindVertexArray);
471                         COREGL_OVERRIDE(fastpath_, glDeleteVertexArrays);
472                         COREGL_OVERRIDE(fastpath_, glGenVertexArrays);
473                         COREGL_OVERRIDE(fastpath_, glIsVertexArray);
474
475                         COREGL_OVERRIDE(fastpath_, glGetIntegeri_v);
476
477                         COREGL_OVERRIDE(fastpath_, glBindTransformFeedback);
478                         COREGL_OVERRIDE(fastpath_, glDeleteTransformFeedbacks);
479                         COREGL_OVERRIDE(fastpath_, glGenTransformFeedbacks);
480                         COREGL_OVERRIDE(fastpath_, glIsTransformFeedback);
481
482                         COREGL_OVERRIDE(fastpath_, glBindBufferRange);
483                         COREGL_OVERRIDE(fastpath_, glBindBufferBase);
484                         COREGL_OVERRIDE(fastpath_, glTransformFeedbackVaryings);
485                         COREGL_OVERRIDE(fastpath_, glGetTransformFeedbackVarying);
486                         COREGL_OVERRIDE(fastpath_, glVertexAttribIPointer);
487                         COREGL_OVERRIDE(fastpath_, glVertexAttribI4i);
488                         COREGL_OVERRIDE(fastpath_, glVertexAttribI4ui);
489                         COREGL_OVERRIDE(fastpath_, glVertexAttribI4iv);
490                         COREGL_OVERRIDE(fastpath_, glVertexAttribI4uiv);
491                         COREGL_OVERRIDE(fastpath_, glGetUniformuiv);
492                         COREGL_OVERRIDE(fastpath_, glGetFragDataLocation);
493                         COREGL_OVERRIDE(fastpath_, glGetStringi);
494                         COREGL_OVERRIDE(fastpath_, glGetUniformIndices);
495                         COREGL_OVERRIDE(fastpath_, glGetActiveUniformsiv);
496                         COREGL_OVERRIDE(fastpath_, glGetUniformBlockIndex);
497                         COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockiv);
498                         COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockName);
499                         COREGL_OVERRIDE(fastpath_, glUniformBlockBinding);
500                         COREGL_OVERRIDE(fastpath_, glGetInteger64v);
501                         COREGL_OVERRIDE(fastpath_, glGetInteger64i_v);
502                         COREGL_OVERRIDE(fastpath_, glGenSamplers);
503                         COREGL_OVERRIDE(fastpath_, glDeleteSamplers);
504                         COREGL_OVERRIDE(fastpath_, glIsSampler);
505                         COREGL_OVERRIDE(fastpath_, glBindSampler);
506                         COREGL_OVERRIDE(fastpath_, glSamplerParameteri);
507                         COREGL_OVERRIDE(fastpath_, glSamplerParameteriv);
508                         COREGL_OVERRIDE(fastpath_, glSamplerParameterf);
509                         COREGL_OVERRIDE(fastpath_, glSamplerParameterfv);
510                         COREGL_OVERRIDE(fastpath_, glGetSamplerParameteriv);
511                         COREGL_OVERRIDE(fastpath_, glGetSamplerParameterfv);
512                         COREGL_OVERRIDE(fastpath_, glVertexAttribDivisor);
513                         COREGL_OVERRIDE(fastpath_, glGetProgramBinary);
514                         COREGL_OVERRIDE(fastpath_, glProgramBinary);
515                         COREGL_OVERRIDE(fastpath_, glProgramParameteri);
516                 } // End of GLES 3.0
517
518                 if (driver_gl_version >= COREGL_GLAPI_31) {
519                         COREGL_OVERRIDE(fastpath_, glCreateShaderProgramv);
520                         COREGL_OVERRIDE(fastpath_, glGenProgramPipelines);
521                         COREGL_OVERRIDE(fastpath_, glGetProgramPipelineiv);
522                         COREGL_OVERRIDE(fastpath_, glBindProgramPipeline);
523                         COREGL_OVERRIDE(fastpath_, glDeleteProgramPipelines);
524                         COREGL_OVERRIDE(fastpath_, glIsProgramPipeline);
525                         COREGL_OVERRIDE(fastpath_, glValidateProgramPipeline);
526                         COREGL_OVERRIDE(fastpath_, glGetProgramPipelineInfoLog);
527                         COREGL_OVERRIDE(fastpath_, glDispatchCompute);
528                         COREGL_OVERRIDE(fastpath_, glDispatchComputeIndirect);
529                         COREGL_OVERRIDE(fastpath_, glGetProgramInterfaceiv);
530                         COREGL_OVERRIDE(fastpath_, glGetProgramResourceIndex);
531                         COREGL_OVERRIDE(fastpath_, glGetProgramResourceName);
532                         COREGL_OVERRIDE(fastpath_, glGetProgramResourceiv);
533                         COREGL_OVERRIDE(fastpath_, glGetProgramResourceLocation);
534                         COREGL_OVERRIDE(fastpath_, glUseProgramStages);
535                         COREGL_OVERRIDE(fastpath_, glActiveShaderProgram);
536                         COREGL_OVERRIDE(fastpath_, glProgramUniform1iv);
537                         COREGL_OVERRIDE(fastpath_, glProgramUniform2iv);
538                         COREGL_OVERRIDE(fastpath_, glProgramUniform3iv);
539                         COREGL_OVERRIDE(fastpath_, glProgramUniform4iv);
540                         COREGL_OVERRIDE(fastpath_, glProgramUniform1fv);
541                         COREGL_OVERRIDE(fastpath_, glProgramUniform2fv);
542                         COREGL_OVERRIDE(fastpath_, glProgramUniform3fv);
543                         COREGL_OVERRIDE(fastpath_, glProgramUniform4fv);
544                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix2fv);
545                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix3fv);
546                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix4fv);
547                         COREGL_OVERRIDE(fastpath_, glProgramUniform1i);
548                         COREGL_OVERRIDE(fastpath_, glProgramUniform2i);
549                         COREGL_OVERRIDE(fastpath_, glProgramUniform3i);
550                         COREGL_OVERRIDE(fastpath_, glProgramUniform4i);
551                         COREGL_OVERRIDE(fastpath_, glProgramUniform1f);
552                         COREGL_OVERRIDE(fastpath_, glProgramUniform2f);
553                         COREGL_OVERRIDE(fastpath_, glProgramUniform3f);
554                         COREGL_OVERRIDE(fastpath_, glProgramUniform4f);
555                         COREGL_OVERRIDE(fastpath_, glProgramUniform1uiv);
556                         COREGL_OVERRIDE(fastpath_, glProgramUniform2uiv);
557                         COREGL_OVERRIDE(fastpath_, glProgramUniform3uiv);
558                         COREGL_OVERRIDE(fastpath_, glProgramUniform4uiv);
559                         COREGL_OVERRIDE(fastpath_, glProgramUniform1ui);
560                         COREGL_OVERRIDE(fastpath_, glProgramUniform2ui);
561                         COREGL_OVERRIDE(fastpath_, glProgramUniform3ui);
562                         COREGL_OVERRIDE(fastpath_, glProgramUniform4ui);
563                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix2x3fv);
564                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix3x2fv);
565                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix4x2fv);
566                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix2x4fv);
567                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix3x4fv);
568                         COREGL_OVERRIDE(fastpath_, glProgramUniformMatrix4x3fv);
569                         COREGL_OVERRIDE(fastpath_, glBindImageTexture);
570                         COREGL_OVERRIDE(fastpath_, glGetBooleani_v);
571                         COREGL_OVERRIDE(fastpath_, glMemoryBarrier);
572                         COREGL_OVERRIDE(fastpath_, glMemoryBarrierByRegion);
573                         COREGL_OVERRIDE(fastpath_, glTexStorage2DMultisample);
574                         COREGL_OVERRIDE(fastpath_, glGetMultisamplefv);
575                         COREGL_OVERRIDE(fastpath_, glSampleMaski);
576                         COREGL_OVERRIDE(fastpath_, glGetTexLevelParameteriv);
577                         COREGL_OVERRIDE(fastpath_, glGetTexLevelParameterfv);
578                         COREGL_OVERRIDE(fastpath_, glBindVertexBuffer);
579                         COREGL_OVERRIDE(fastpath_, glVertexAttribFormat);
580                         COREGL_OVERRIDE(fastpath_, glVertexAttribIFormat);
581                         COREGL_OVERRIDE(fastpath_, glVertexAttribBinding);
582                         COREGL_OVERRIDE(fastpath_, glVertexBindingDivisor);
583                 }
584         } else {
585                 COREGL_LOG("\E[40;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
586         }
587 }
588
589 #undef OVERRIDE
590
591 static inline GL_Object_Hash_Base *
592 _lock_gl_object_hash(GL_Object_State *ostate, GL_Object_Type type)
593 {
594         switch (type) {
595         case GL_OBJECT_TYPE_QUERY:
596                 return &ostate->query;
597         case GL_OBJECT_TYPE_TEXTURE:
598                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
599                 return &ostate->shared->texture;
600         case GL_OBJECT_TYPE_BUFFER:
601                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
602                 return &ostate->shared->buffer;
603         case GL_OBJECT_TYPE_FRAMEBUFFER:
604                 return &ostate->framebuffer;
605         case GL_OBJECT_TYPE_RENDERBUFFER:
606                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
607                 return &ostate->shared->renderbuffer;
608         case GL_OBJECT_TYPE_PROGRAM:
609                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
610                 return &ostate->shared->program;
611         case GL_OBJECT_TYPE_VERTEXARRAY:
612                 return &ostate->vertexarray;
613         case GL_OBJECT_TYPE_SAMPLER:
614                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
615                 return &ostate->shared->sampler;
616         case GL_OBJECT_TYPE_TRANSFORMFEEDBACK:
617                 return &ostate->transformfeedback;
618         case GL_OBJECT_TYPE_PROGRAMPIPELINE:
619                 AST(mutex_lock(&ostate->shared->access_mutex) == 1);
620                 return &ostate->shared->programpipeline;
621         default:
622                 return NULL;
623         }
624 }
625
626 static inline void
627 _unlock_gl_object_hash(GL_Object_State *ostate, GL_Object_Type type)
628 {
629         switch (type) {
630         case GL_OBJECT_TYPE_TEXTURE:
631         case GL_OBJECT_TYPE_BUFFER:
632         case GL_OBJECT_TYPE_RENDERBUFFER:
633         case GL_OBJECT_TYPE_PROGRAM:
634         case GL_OBJECT_TYPE_SAMPLER:
635         case GL_OBJECT_TYPE_PROGRAMPIPELINE:
636                 AST(mutex_unlock(&ostate->shared->access_mutex) == 1);
637         default:
638                 break;
639         }
640 }
641
642 static inline GL_Object_Hash_Base *
643 _lock_gl_object_hash_real(GL_Object_State *ostate, GL_Object_Type type)
644 {
645         switch (type) {
646         case GL_OBJECT_TYPE_QUERY:
647                 return &ostate->query_real;
648         case GL_OBJECT_TYPE_TEXTURE:
649                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
650                 return &ostate->shared->texture_real;
651         case GL_OBJECT_TYPE_BUFFER:
652                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
653                 return &ostate->shared->buffer_real;
654         case GL_OBJECT_TYPE_FRAMEBUFFER:
655                 return &ostate->framebuffer_real;
656         case GL_OBJECT_TYPE_RENDERBUFFER:
657                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
658                 return &ostate->shared->renderbuffer_real;
659         case GL_OBJECT_TYPE_PROGRAM:
660                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
661                 return &ostate->shared->program_real;
662         case GL_OBJECT_TYPE_VERTEXARRAY:
663                 return &ostate->vertexarray_real;
664         case GL_OBJECT_TYPE_SAMPLER:
665                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
666                 return &ostate->shared->sampler_real;
667         case GL_OBJECT_TYPE_TRANSFORMFEEDBACK:
668                 return &ostate->transformfeedback_real;
669         case GL_OBJECT_TYPE_PROGRAMPIPELINE:
670                 AST(mutex_lock(&ostate->shared->real_access_mutex) == 1);
671                 return &ostate->shared->programpipeline_real;
672         default:
673                 return NULL;
674         }
675 }
676
677 static inline void
678 _unlock_gl_object_hash_real(GL_Object_State *ostate, GL_Object_Type type)
679 {
680         switch (type) {
681         case GL_OBJECT_TYPE_TEXTURE:
682         case GL_OBJECT_TYPE_BUFFER:
683         case GL_OBJECT_TYPE_RENDERBUFFER:
684         case GL_OBJECT_TYPE_PROGRAM:
685         case GL_OBJECT_TYPE_SAMPLER:
686         case GL_OBJECT_TYPE_PROGRAMPIPELINE:
687                 AST(mutex_unlock(&ostate->shared->real_access_mutex) == 1);
688                 break;
689         default:
690                 break;
691         }
692 }
693
694 int
695 fastpath_add_context_state_to_list(const void *option, const int option_len,
696                                    GLContextState *cstate, Mutex *mtx)
697 {
698         int ret = 0;
699         int tid = 0;
700         GLContext_List *current = NULL;
701         GLContext_List *newitm = NULL;
702
703         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
704
705         AST(cstate != NULL);
706
707         tid = get_current_thread();
708
709         current = glctx_list;
710         while (current != NULL) {
711                 if (current->option_len == option_len &&
712                     memcmp(current->option, option, option_len) == 0 &&
713                     current->thread_id == tid) {
714                         AST(current->cstate == cstate);
715                         goto finish;
716                 }
717                 current = current->next;
718         }
719
720         newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
721         if (newitm == NULL) {
722                 COREGL_ERR("Failed to create context list.\n");
723                 goto finish;
724         }
725
726         newitm->cstate = cstate;
727         newitm->thread_id = tid;
728         newitm->option_len = option_len;
729         newitm->option = (void *)malloc(option_len);
730         memcpy(newitm->option, option, option_len);
731
732         if (glctx_list != NULL)
733                 newitm->next = glctx_list;
734
735         glctx_list = newitm;
736
737         ret = 1;
738         goto finish;
739
740 finish:
741         if (ret != 1) {
742                 if (newitm != NULL) {
743                         free(newitm);
744                         newitm = NULL;
745                 }
746                 if (cstate != NULL) {
747                         free(cstate);
748                         cstate = NULL;
749                 }
750         }
751         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
752
753         return ret;
754 }
755
756 GLContextState *
757 fastpath_get_context_state_from_list(const void *option, const int option_len,
758                                      Mutex *mtx)
759 {
760         GLContextState *ret = NULL;
761         GLContext_List *current = NULL;
762         int tid = 0;
763
764         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
765
766         tid = get_current_thread();
767
768         current = glctx_list;
769         while (current != NULL) {
770                 if (current->option_len == option_len &&
771                     memcmp(current->option, option, option_len) == 0 &&
772                     current->thread_id == tid) {
773                         ret = current->cstate;
774                         goto finish;
775                 }
776                 current = current->next;
777         }
778         goto finish;
779
780 finish:
781         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
782         return ret;
783 }
784
785 int
786 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
787 {
788         int ret = 0;
789         GLContext_List *olditm = NULL;
790         GLContext_List *current = NULL;
791
792         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
793
794         AST(cstate != NULL);
795
796         current = glctx_list;
797
798         while (current != NULL) {
799                 if (current->cstate == cstate) {
800                         GLContext_List *nextitm = NULL;
801                         if (olditm != NULL) {
802                                 olditm->next = current->next;
803                                 nextitm = olditm->next;
804                         } else {
805                                 glctx_list = current->next;
806                                 nextitm = glctx_list;
807                         }
808                         if (current->option != NULL) {
809                                 AST(current->option_len > 0);
810                                 free(current->option);
811                                 current->option = NULL;
812                                 current->option_len = 0;
813                         }
814                         free(current);
815                         ret = 1;
816                         current = nextitm;
817                         continue;
818                 }
819                 olditm = current;
820                 current = current->next;
821         }
822         goto finish;
823
824 finish:
825         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
826         return ret;
827 }
828
829
830
831 #define HASH_INIT(hash_base) \
832         hash_base.hash_field = (GL_Object_Hash **)calloc(1, sizeof(GL_Object_Hash *) * GL_OBJECT_HASH_BASE); \
833         hash_base.hash_size = GL_OBJECT_HASH_BASE;
834
835 void
836 fastpath_ostate_init(GL_Object_State *ostate)
837 {
838         HASH_INIT(ostate->query);
839         HASH_INIT(ostate->framebuffer);
840         HASH_INIT(ostate->vertexarray);
841         HASH_INIT(ostate->transformfeedback);
842
843         HASH_INIT(ostate->query_real);
844         HASH_INIT(ostate->framebuffer_real);
845         HASH_INIT(ostate->vertexarray_real);
846         HASH_INIT(ostate->transformfeedback_real);
847 }
848
849 void
850 fastpath_sostate_init(GL_Shared_Object_State *sostate)
851 {
852         mutex_init(&sostate->access_mutex);
853
854         HASH_INIT(sostate->texture);
855         HASH_INIT(sostate->buffer);
856         HASH_INIT(sostate->renderbuffer);
857         HASH_INIT(sostate->program);
858         HASH_INIT(sostate->sampler);
859         HASH_INIT(sostate->programpipeline);
860
861         HASH_INIT(sostate->texture_real);
862         HASH_INIT(sostate->buffer_real);
863         HASH_INIT(sostate->renderbuffer_real);
864         HASH_INIT(sostate->program_real);
865         HASH_INIT(sostate->sampler_real);
866         HASH_INIT(sostate->programpipeline_real);
867 }
868
869 #undef HASH_INIT
870
871
872 static void
873 _add_hash(GL_Object_Hash_Base *hash_base, GL_Object_Hash *data)
874 {
875         int array_idx = data->hash_key & (hash_base->hash_size - 1);
876         if (hash_base->hash_field[array_idx] == NULL) {
877                 hash_base->hash_field[array_idx] = data;
878         } else {
879                 GL_Object_Hash *current = hash_base->hash_field[array_idx];
880                 while (current->next) {
881                         AST(current->hash_key != data->hash_key);
882                         current = current->next;
883                 }
884                 current->next = data;
885         }
886         data->next = NULL;
887         hash_base->item_size++;
888 }
889
890 static int
891 _remove_hash(GL_Object_Hash_Base *hash_base, GLuint hash)
892 {
893         int ret = 0;
894         int array_idx = hash & (hash_base->hash_size - 1);
895
896         GL_Object_Hash *current = hash_base->hash_field[array_idx];
897         GL_Object_Hash *prev = NULL;
898
899         while (current) {
900                 if (current->hash_key == hash) {
901                         if (prev != NULL)
902                                 prev->next = current->next;
903                         else
904                                 hash_base->hash_field[array_idx] = current->next;
905                         hash_base->item_size--;
906                         ret = 1;
907                         break;
908                 }
909                 prev = current;
910                 current = current->next;
911         }
912
913         return ret;
914 }
915
916 static void
917 _free_hash_list(GL_Object_Hash_Base *hash_base, int free_data)
918 {
919         if (hash_base->item_size == 0) return;
920
921         for (int i = 0; i < hash_base->hash_size; i++) {
922                 if (hash_base->hash_field[i] != NULL) {
923                         GL_Object_Hash *current = hash_base->hash_field[i];
924
925                         while (current != NULL) {
926                                 GL_Object_Hash *current_next = current->next;
927
928                                 if (free_data == 1 && current->item != NULL) {
929                                         free(current->item);
930                                 }
931
932                                 free(current);
933                                 hash_base->item_size--;
934                                 current = current_next;
935                         }
936                 }
937         }
938 }
939
940
941
942 #define HASH_DEINIT(hash_base, free_data) \
943         _free_hash_list(&hash_base, free_data); \
944         free(hash_base.hash_field); \
945         hash_base.hash_size = 0;
946
947 void
948 fastpath_ostate_deinit(GL_Object_State *ostate)
949 {
950         HASH_DEINIT(ostate->query, 1);
951         HASH_DEINIT(ostate->framebuffer, 1);
952         HASH_DEINIT(ostate->vertexarray, 1);
953         HASH_DEINIT(ostate->transformfeedback, 1);
954
955         HASH_DEINIT(ostate->query_real, 0);
956         HASH_DEINIT(ostate->framebuffer_real, 0);
957         HASH_DEINIT(ostate->vertexarray_real, 0);
958         HASH_DEINIT(ostate->transformfeedback_real, 0);
959 }
960
961 void
962 fastpath_sostate_deinit(GL_Shared_Object_State *sostate)
963 {
964         HASH_DEINIT(sostate->texture, 1);
965         HASH_DEINIT(sostate->buffer, 1);
966         HASH_DEINIT(sostate->renderbuffer, 1);
967         HASH_DEINIT(sostate->program, 1);
968         HASH_DEINIT(sostate->sampler, 1);
969         HASH_DEINIT(sostate->programpipeline, 1);
970
971         HASH_DEINIT(sostate->texture_real, 0);
972         HASH_DEINIT(sostate->buffer_real, 0);
973         HASH_DEINIT(sostate->renderbuffer_real, 0);
974         HASH_DEINIT(sostate->program_real, 0);
975         HASH_DEINIT(sostate->sampler_real, 0);
976
977         HASH_DEINIT(sostate->programpipeline_real, 0);
978 }
979
980 #undef HASH_DEINIT
981
982
983
984 #define FIND_HASH(hash_base, key, ret) \
985 { \
986         GL_Object_Hash *fh_current = hash_base->hash_field[(key) & (hash_base->hash_size - 1)]; \
987         while(fh_current) \
988         { \
989                 if (fh_current->hash_key == (key)) \
990                 { \
991                         ret = fh_current; \
992                         break; \
993                 } \
994                 fh_current = fh_current->next; \
995         } \
996 }
997
998 void
999 _ostate_hash_check(GL_Object_Hash_Base *hash_base)
1000 {
1001         if (hash_base->item_size + 1 < hash_base->hash_size)
1002                 return;
1003
1004         int oldsize = hash_base->hash_size;
1005         GL_Object_Hash **oldfield = hash_base->hash_field;
1006
1007         hash_base->hash_size = oldsize << 1;
1008         hash_base->hash_field = (GL_Object_Hash **)calloc(1,
1009                                 sizeof(GL_Object_Hash *) * hash_base->hash_size);
1010         AST(hash_base->hash_field != NULL);
1011
1012         for (int i = 0; i < oldsize; i++) {
1013                 if (oldfield[i] != NULL) {
1014                         GL_Object_Hash *current = oldfield[i];
1015
1016                         while (current != NULL) {
1017                                 GL_Object_Hash *current_next = current->next;
1018                                 _add_hash(hash_base, current);
1019                                 hash_base->item_size--;
1020                                 current = current_next;
1021                         }
1022                 }
1023         }
1024         free(oldfield);
1025
1026 }
1027
1028 GLuint
1029 fastpath_ostate_create_object(GL_Object_State *ostate, GL_Object_Type type,
1030                               GLuint real_name)
1031 {
1032         GLuint ret = _COREGL_INT_INIT_VALUE;
1033
1034         GL_Object_Hash_Base *hash_base = NULL;
1035         GL_Object_Hash_Base *hash_base_real = NULL;
1036         int newid = _COREGL_INT_INIT_VALUE;
1037
1038         hash_base = _lock_gl_object_hash(ostate, type);
1039         hash_base_real = _lock_gl_object_hash_real(ostate, type);
1040
1041         newid = hash_base->last_id + 1;
1042         if (newid >= hash_base->hash_size) {
1043                 hash_base->is_looped = 1;
1044                 newid = 1;
1045                 hash_base->last_id = 1;
1046         }
1047
1048         if (hash_base->is_looped != 0) {
1049                 int i;
1050                 int findingid = newid;
1051                 newid = -1;
1052                 for (i = 0; i < hash_base->hash_size; i++) {
1053                         GL_Object_Hash *exist_hash = NULL;
1054                         FIND_HASH(hash_base, findingid, exist_hash);
1055                         if (exist_hash == NULL) {
1056                                 newid = findingid;
1057                                 break;
1058                         }
1059                         findingid++;
1060                         if (findingid >= hash_base->hash_size) findingid = 1;
1061                 }
1062                 AST(newid != -1);
1063         }
1064         hash_base->last_id = newid;
1065
1066         {
1067                 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
1068                 if (newobj == NULL)
1069                         goto finish;
1070                 newobj->id = (int)type + newid;
1071                 newobj->real_id = real_name;
1072                 newobj->ref_count = 1;
1073
1074
1075                 GL_Object_Hash *newobj_hash = (GL_Object_Hash *)calloc(1,
1076                                               sizeof(GL_Object_Hash));
1077                 if (newobj_hash == NULL) {
1078                         free(newobj);
1079                         goto finish;
1080                 }
1081                 newobj_hash->item = newobj;
1082                 newobj_hash->hash_key = newid;
1083                 _add_hash(hash_base, newobj_hash);
1084
1085                 GL_Object_Hash *newobj_hash_real = (GL_Object_Hash *)calloc(1,
1086                                                    sizeof(GL_Object_Hash));
1087                 if (newobj_hash_real == NULL) {
1088                         free(newobj);
1089                         free(newobj_hash);
1090                         goto finish;
1091                 }
1092                 newobj_hash_real->item = newobj;
1093                 newobj_hash_real->hash_key = real_name;
1094                 _add_hash(hash_base_real, newobj_hash_real);
1095
1096                 ret = newobj->id;
1097         }
1098
1099         _ostate_hash_check(hash_base);
1100         _ostate_hash_check(hash_base_real);
1101
1102         goto finish;
1103
1104 finish:
1105         _unlock_gl_object_hash(ostate, type);
1106         _unlock_gl_object_hash_real(ostate, type);
1107         return ret;
1108 }
1109
1110 #define FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object) \
1111         if (((int)(hash)) < 0) { ret = 0; goto finish; } \
1112         { \
1113                 GL_Object_Hash *object_hash = NULL; \
1114                 FIND_HASH((hash_base), (int)(hash), object_hash); \
1115                 if (object_hash == NULL) { ret = 0; goto finish; } \
1116                 (object) = object_hash->item; \
1117                 if ((object) == NULL) { ret = 0; goto finish; } \
1118         }
1119
1120 GLuint
1121 fastpath_ostate_remove_object(GL_Object_State *ostate, GL_Object_Type type,
1122                               GLuint glue_name)
1123 {
1124         GLuint ret = _COREGL_INT_INIT_VALUE;
1125
1126         GL_Object_Hash_Base *hash_base = NULL;
1127         GL_Object_Hash_Base *hash_base_real = NULL;
1128         GL_Object *object = NULL;
1129
1130         hash_base = _lock_gl_object_hash(ostate, type);
1131         hash_base_real = _lock_gl_object_hash_real(ostate, type);
1132
1133         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1134
1135         object->ref_count--;
1136
1137         if (object->ref_count <= 0) {
1138                 GL_Object_Hash *object_hash = NULL;
1139
1140                 FIND_HASH(hash_base, object->id - (int)type, object_hash);
1141                 AST(object_hash != NULL);
1142                 _remove_hash(hash_base, object->id - (int)type);
1143                 free(object_hash);
1144                 object_hash = NULL;
1145
1146                 FIND_HASH(hash_base_real, object->real_id, object_hash);
1147                 AST(object_hash != NULL);
1148                 _remove_hash(hash_base_real, object->real_id);
1149                 free(object_hash);
1150                 object_hash = NULL;
1151
1152                 free(object);
1153                 object = NULL;
1154         }
1155
1156         ret = 1;
1157         goto finish;
1158
1159 finish:
1160         _unlock_gl_object_hash(ostate, type);
1161         _unlock_gl_object_hash_real(ostate, type);
1162         return ret;
1163 }
1164
1165 GLuint
1166 fastpath_ostate_get_object(GL_Object_State *ostate, GL_Object_Type type,
1167                            GLuint glue_name)
1168 {
1169         GLuint ret = _COREGL_INT_INIT_VALUE;
1170
1171         GL_Object_Hash_Base *hash_base = NULL;
1172         GL_Object *object = NULL;
1173
1174         hash_base = _lock_gl_object_hash(ostate, type);
1175
1176         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1177
1178         ret = object->real_id;
1179         goto finish;
1180
1181 finish:
1182         _unlock_gl_object_hash(ostate, type);
1183         return ret;
1184 }
1185
1186 /* Check if the context's state contains object of a given type */
1187 GLuint
1188 fastpath_ostate_has_object_type(GL_Object_State *ostate, GL_Object_Type type)
1189 {
1190         GLuint ret = _COREGL_INT_INIT_VALUE;
1191
1192         GL_Object_Hash_Base *hash_base = NULL;
1193         GL_Object *object = NULL;
1194         hash_base = _lock_gl_object_hash(ostate, type);
1195
1196         if (hash_base->hash_field == 0) {
1197                 ret = 0;
1198                 goto finish;
1199         }
1200
1201         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, 1, object);
1202
1203         ret = object->real_id;
1204         goto finish;
1205
1206 finish:
1207         _unlock_gl_object_hash(ostate, type);
1208         return ret;
1209 }
1210
1211
1212 GLint
1213 fastpath_ostate_set_object_tag(GL_Object_State *ostate, GL_Object_Type type,
1214                                GLuint glue_name, GLvoid *tag)
1215 {
1216         GLint ret = _COREGL_INT_INIT_VALUE;
1217
1218         GL_Object_Hash_Base *hash_base = NULL;
1219         GL_Object *object = NULL;
1220         int hash = _COREGL_INT_INIT_VALUE;
1221
1222         hash_base = _lock_gl_object_hash(ostate, type);
1223
1224         hash = glue_name - (int)type;
1225
1226         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object);
1227
1228         AST(object->tag == NULL);
1229         object->tag = tag;
1230         ret = 1;
1231         goto finish;
1232
1233 finish:
1234         _unlock_gl_object_hash(ostate, type);
1235         return ret;
1236 }
1237
1238 GLvoid *
1239 fastpath_ostate_get_object_tag(GL_Object_State *ostate, GL_Object_Type type,
1240                                GLuint glue_name)
1241 {
1242         GLvoid *ret = NULL;
1243
1244         GL_Object_Hash_Base *hash_base = NULL;
1245         GL_Object *object = NULL;
1246
1247         hash_base = _lock_gl_object_hash(ostate, type);
1248
1249         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1250
1251         ret = object->tag;
1252         goto finish;
1253
1254 finish:
1255         _unlock_gl_object_hash(ostate, type);
1256         return ret;
1257 }
1258
1259 GLuint
1260 fastpath_ostate_find_object(GL_Object_State *ostate, GL_Object_Type type,
1261                             GLuint real_name)
1262 {
1263         GLuint ret = _COREGL_INT_INIT_VALUE;
1264
1265         GL_Object_Hash_Base *hash_base_real = NULL;
1266         GL_Object *object = NULL;
1267
1268         hash_base_real = _lock_gl_object_hash_real(ostate, type);
1269
1270         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base_real, real_name, object);
1271
1272         ret = object->id;
1273         goto finish;
1274
1275 finish:
1276         _unlock_gl_object_hash_real(ostate, type);
1277         return ret;
1278 }
1279
1280 GLint
1281 fastpath_ostate_use_object(GL_Object_State *ostate, GL_Object_Type type,
1282                            GLuint glue_name)
1283 {
1284         GLint ret = _COREGL_INT_INIT_VALUE;
1285
1286         GL_Object_Hash_Base *hash_base = NULL;
1287         GL_Object *object = NULL;
1288
1289         hash_base = _lock_gl_object_hash(ostate, type);
1290
1291         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1292
1293         object->ref_count++;
1294         ret = 1;
1295         goto finish;
1296
1297 finish:
1298         _unlock_gl_object_hash(ostate, type);
1299         return ret;
1300 }
1301
1302 void
1303 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
1304 {
1305         static struct timeval tv_last = { 0, 0 };
1306
1307         if (unlikely(trace_state_flag != 1)) return;
1308
1309         if (!force_output) {
1310                 struct timeval tv_now = { 0, 0 };
1311                 AST(gettimeofday(&tv_now, NULL) == 0);
1312                 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC) {
1313                         goto finish;
1314                 }
1315                 tv_last = tv_now;
1316         }
1317
1318         TRACE("\n");
1319         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1320         TRACE("\E[40;32;1m  State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n",
1321               getpid(), ctx);
1322         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1323
1324 #define PRINTF_CHAR_GLenum "0x%8X"
1325 #define PRINTF_CHAR_GLboolean "%10d"
1326 #define PRINTF_CHAR_GLint "%10d"
1327 #define PRINTF_CHAR_GLsizei "%10u"
1328 #define PRINTF_CHAR_GLuint "%10u"
1329 #define PRINTF_CHAR_GLuintmask "0x%8X"
1330 #define PRINTF_CHAR_GLintptr "%10ld"
1331 #define PRINTF_CHAR_GLsizeiptr "%10ld"
1332
1333 #define PRINTF_CHAR_GLclampf "%10.6f"
1334 #define PRINTF_CHAR_GLfloat "%10.6f"
1335
1336 #define PRINTF_CHAR_GLvoidptr "%10p"
1337
1338 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
1339
1340 #define _COREGL_START_API(version) api_gl_version = version;
1341 #define _COREGL_END_API(version) api_gl_version = COREGL_GLAPI_2;
1342 #define INITIAL_CTX initial_ctx
1343 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1344    { \
1345       TYPE valuedata[SIZE]; \
1346       TYPE *value = NULL; \
1347       if(api_gl_version <= driver_gl_version) { \
1348          value = valuedata; GET_STMT; value = valuedata; \
1349          TRACE("\E[40;37;1m %-30.30s : (\E[0m ", #NAME); \
1350          for (int i = 0; i < SIZE; i++) \
1351          { \
1352             if (i > 0) { \
1353                if (i % 4 == 0) \
1354                   TRACE("\n %-30.30s     ", "");\
1355                else \
1356                   TRACE(", "); \
1357             } \
1358             if (ctx->NAME[i] != value[i]) { TRACE("\E[40;31;1m"); } \
1359                TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
1360                TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
1361             if (ctx->NAME[i] != value[i]) { TRACE("\E[0m"); } \
1362          } \
1363          TRACE(" \E[40;37;1m)\E[0m\n"); \
1364       } \
1365    }
1366 # include "coregl_fastpath_state.h"
1367 #undef GLUE_STATE
1368 #undef INITIAL_CTX
1369 #undef _COREGL_START_API
1370 #undef _COREGL_END_API
1371
1372         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1373         TRACE("\n");
1374
1375         TRACE_END();
1376
1377 finish:
1378         return;
1379 }
1380
1381 int
1382 fastpath_init_context_states(GLGlueContext *ctx)
1383 {
1384         int ret = 0;
1385
1386         AST(mutex_lock(&init_context_mutex) == 1);
1387
1388         if (ctx == NULL) {
1389                 COREGL_ERR("Context NULL\n");
1390                 ret = 0;
1391                 goto finish;
1392         }
1393
1394         AST(ctx->initialized == 0);
1395         AST(ctx->ostate.shared != NULL);
1396
1397         if (initial_ctx == NULL) {
1398                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
1399                 AST(initial_ctx != NULL);
1400
1401 //#define FORCE_DEFAULT_VALUE
1402 #define _COREGL_START_API(version) api_gl_version = version;
1403 #define _COREGL_END_API(version) api_gl_version = COREGL_GLAPI_2;
1404 #ifdef FORCE_DEFAULT_VALUE
1405 # define INITIAL_CTX initial_ctx
1406 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1407       { \
1408          int i; \
1409          TYPE valuedata[SIZE]; \
1410          TYPE *value = NULL; \
1411          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1412          if(api_gl_version <= driver_gl_version) { \
1413             value = valuedata; DEFAULT_STMT; value = valuedata; \
1414             for (i = 0; i < SIZE; i++) \
1415             { \
1416                if (*((char *)(&value[i])) == 0xcc) \
1417                { \
1418                   memset(&value[i], 0xaa, sizeof(TYPE)); \
1419                   value = valuedata; DEFAULT_STMT; value = valuedata; \
1420                   if (*((char *)(&value[i])) == 0xaa) \
1421                   { \
1422                      COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1423                      break; \
1424                   } \
1425                } \
1426                initial_ctx->NAME[i] = value[i]; \
1427             } \
1428         }\
1429       }
1430 #  include "coregl_fastpath_state.h"
1431 # undef GLUE_STATE
1432 # undef INITIAL_CTX
1433 #else
1434 # define INITIAL_CTX initial_ctx
1435 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
1436       if (try_step == 1) \
1437       { \
1438          value = valuedata; DEFAULT_STMT; value = valuedata; \
1439       } \
1440       else \
1441       { \
1442          value = valuedata; FALLBACK_STMT; value = valuedata; \
1443       }
1444
1445 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1446       { \
1447          int i; \
1448          int try_step = 0;\
1449          TYPE valuedata[SIZE]; \
1450          TYPE *value = NULL; \
1451          _sym_glGetError(); \
1452          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1453          if(api_gl_version <= driver_gl_version) { \
1454             do { \
1455                try_step++; \
1456                SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1457                if (_sym_glGetError() == GL_INVALID_ENUM) \
1458                { \
1459                   initial_ctx->NAME##_used = 0; \
1460                   value = valuedata; DEFAULT_STMT; value = valuedata; \
1461                   break; \
1462                } \
1463                initial_ctx->NAME##_used = 1; \
1464                for (i = 0; i < SIZE; i++) \
1465                { \
1466                   if (*((char *)(&value[i])) == 0xcc) \
1467                   { \
1468                      memset(&value[i], 0xaa, sizeof(TYPE)); \
1469                      SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1470                      if (*((char *)(&value[i])) == 0xaa) \
1471                      { \
1472                         try_step++; \
1473                         if (try_step == 2) \
1474                         { \
1475                            COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1476                         } \
1477                         break; \
1478                      } \
1479                   } \
1480                   initial_ctx->NAME[i] = value[i]; \
1481                } \
1482                if (try_step != 2) \
1483                { \
1484                   value = valuedata; DEFAULT_STMT; value = valuedata; \
1485                   for (i = 0; i < SIZE; i++) \
1486                   { \
1487                      if (initial_ctx->NAME[i] != value[i]) \
1488                      { \
1489                         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]); \
1490                      } \
1491                   } \
1492                } \
1493             } \
1494             while (try_step == 2); \
1495          }\
1496       }
1497 #  include "coregl_fastpath_state.h"
1498 # undef SET_GLUE_VALUE
1499 # undef GLUE_STATE
1500 # undef INITIAL_CTX
1501 #endif
1502 # undef _COREGL_END_API
1503 # undef _COREGL_START_API
1504
1505                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS) {
1506                         COREGL_WRN("\E[40;31;1mNumber of vertex attrib is too big! (%d-%d)\E[0m\n",
1507                                    MAX_VERTEX_ATTRIBS, initial_ctx->gl_num_vertex_attribs[0]);
1508                 }
1509                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS) {
1510                         COREGL_WRN("\E[40;31;1mNumber of texture unit is too big! (%d-%d)\E[0m\n",
1511                                    MAX_TEXTURE_UNITS, initial_ctx->gl_num_tex_units[0]);
1512                 }
1513                 if (initial_ctx->gl_num_transform_feedback_separate_attribs[0] >
1514                     MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) {
1515                         COREGL_WRN("\E[40;31;1mNumber of transform feedback separate attrib is too big! (%d-%d)\E[0m\n",
1516                                    MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
1517                                    initial_ctx->gl_num_transform_feedback_separate_attribs[0]);
1518                 }
1519                 if (initial_ctx->gl_num_uniform_buffer_bindings[0] >
1520                     MAX_UNIFORM_BUFFER_BINDINGS) {
1521                         COREGL_WRN("\E[40;31;1mNumber of uniform buffer binding is too big! (%d-%d)\E[0m\n",
1522                                    MAX_UNIFORM_BUFFER_BINDINGS, initial_ctx->gl_num_uniform_buffer_bindings[0]);
1523                 }
1524         }
1525
1526         {
1527                 int i;
1528 #define _COREGL_START_API(version) api_gl_version = version;
1529 #define _COREGL_END_API(version) api_gl_version = COREGL_GLAPI_2;
1530 #define INITIAL_CTX initial_ctx
1531 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1532       if(api_gl_version <= driver_gl_version) { \
1533          for (i = 0; i < SIZE; i++) \
1534          { \
1535             ctx->NAME[i] = initial_ctx->NAME[i]; \
1536             ctx->NAME##_used = initial_ctx->NAME##_used; \
1537          }\
1538       }
1539 # include "coregl_fastpath_state.h"
1540 #undef GLUE_STATE
1541 #undef INITIAL_CTX
1542 #undef _COREGL_START_API
1543 #undef _COREGL_END_API
1544         }
1545
1546         ctx->initialized = 1;
1547         ret = 1;
1548         goto finish;
1549
1550 finish:
1551         AST(mutex_unlock(&init_context_mutex) == 1);
1552
1553         return ret;
1554 }
1555
1556 #ifdef COREGL_USE_MODULE_TRACEPATH
1557 extern void *tracepath_api_trace_begin(const char *name, void *hint,
1558                                        int trace_total_time);
1559 extern void *tracepath_api_trace_end(const char *name, void *hint,
1560                                      int trace_total_time);
1561 #endif
1562
1563 #define CHECK_GL_ERROR(func) \
1564         { \
1565                 func; \
1566                 int err = _orig_fastpath_glGetError(); \
1567                 if (err != GL_NO_ERROR) \
1568                 { \
1569                         COREGL_ERR("\E[40;31;1m(GL %p) : %s returns GL error 0x%X\E[0m\n", oldctx->cstate, #func, err); \
1570                         goto finish; \
1571                 } \
1572         }
1573
1574 int
1575 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
1576 {
1577         int ret = 0;
1578         unsigned char flag = 0;
1579         int i = 0;
1580
1581         if (debug_nofp == 1) {
1582                 ret = 1;
1583                 goto finish;
1584         }
1585
1586         // Return if they're the same
1587         if (oldctx == newctx) {
1588                 ret = 1;
1589                 goto finish;
1590         }
1591
1592 #define STATE_COMPARE(state) \
1593    if ((oldctx->state) != (newctx->state))
1594
1595 #define STATES_COMPARE(state_ptr, bytes) \
1596    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
1597
1598
1599 #ifdef COREGL_USE_MODULE_TRACEPATH
1600         static void *trace_hint_glfinish = NULL;
1601         trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)",
1602                               trace_hint_glfinish, 0);
1603 #endif // COREGL_USE_MODULE_TRACEPATH
1604
1605         {
1606                 int err = _orig_fastpath_glGetError();
1607                 if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR)
1608                         oldctx->gl_error = err;
1609         }
1610
1611         CHECK_GL_ERROR(_orig_fastpath_glFlush())
1612
1613 #ifdef COREGL_USE_MODULE_TRACEPATH
1614         tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
1615 #endif // COREGL_USE_MODULE_TRACEPATH
1616
1617         // _varray_flag
1618 #ifdef COREGL_USE_MODULE_TRACEPATH
1619         static void *trace_hint_vertex_attrib = NULL;
1620         trace_hint_vertex_attrib =
1621                 tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)",
1622                                           trace_hint_vertex_attrib, 0);
1623 #endif // COREGL_USE_MODULE_TRACEPATH
1624
1625         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1626         if (flag) {
1627                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++) {
1628                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i]) {
1629                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
1630                                                 newctx->gl_vertex_array_buf_id[i]))
1631                         } else {
1632                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
1633                         }
1634
1635                         STATE_COMPARE(gl_vertex_array_divisor[i]) {
1636                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribDivisor(i,
1637                                                 newctx->gl_vertex_array_divisor[i]))
1638                         }
1639
1640                         if (newctx->gl_vertex_array_size[i] != 0) {
1641                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
1642                                                 newctx->gl_vertex_array_size[i],
1643                                                 newctx->gl_vertex_array_type[i],
1644                                                 newctx->gl_vertex_array_normalized[i],
1645                                                 newctx->gl_vertex_array_stride[i],
1646                                                 newctx->gl_vertex_array_pointer[i]))
1647                         } else {
1648                                 if (newctx->gl_vertex_array_integer[0] == GL_TRUE) {
1649                                         if (newctx->gl_vertex_array_type[0] == GL_UNSIGNED_INT) {
1650                                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4uiv(i,
1651                                                                 &newctx->gl_vertex_attrib_value_unsigned_integer[4 * i]))
1652                                         } else {
1653                                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4iv(i,
1654                                                                 &newctx->gl_vertex_attrib_value_integer[4 * i]))
1655                                         }
1656                                 } else {
1657                                         CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i,
1658                                                         &newctx->gl_vertex_attrib_value[4 * i]))
1659                                 }
1660                         }
1661
1662                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE) {
1663                                 CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
1664                         } else {
1665                                 CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
1666                         }
1667                 }
1668
1669         }
1670
1671 #ifdef COREGL_USE_MODULE_TRACEPATH
1672         tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)",
1673                                 trace_hint_vertex_attrib, 0);
1674 #endif // COREGL_USE_MODULE_TRACEPATH
1675
1676
1677 #ifdef COREGL_USE_MODULE_TRACEPATH
1678         static void *trace_hint_bindbuffers = NULL;
1679         trace_hint_bindbuffers =
1680                 tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)",
1681                                           trace_hint_bindbuffers, 0);
1682 #endif // COREGL_USE_MODULE_TRACEPATH
1683
1684         //------------------//
1685         // _bind_flag1
1686         flag = oldctx->_bind_flag1 | newctx->_bind_flag1;
1687         if (flag) {
1688                 STATE_COMPARE(gl_array_buffer_binding[0]) {
1689                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
1690                                         newctx->gl_array_buffer_binding[0]))
1691                 }
1692                 STATE_COMPARE(gl_element_array_buffer_binding[0]) {
1693                         STATE_COMPARE(gl_vertex_array_binding[0]) {
1694                                 CHECK_GL_ERROR(_orig_fastpath_glBindVertexArray(
1695                                                        newctx->gl_vertex_array_binding[0]))
1696                         }
1697                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
1698                                         newctx->gl_element_array_buffer_binding[0]))
1699                 }
1700
1701                 if (newctx->gl_framebuffer_binding_read_used == 1) {
1702                         STATE_COMPARE(gl_framebuffer_binding_read[0]) {
1703                                 if (driver_gl_version >= 2)
1704                                         CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_READ_FRAMEBUFFER,
1705                                                         newctx->gl_framebuffer_binding_read[0]))
1706                                         else
1707                                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_READ_FRAMEBUFFER,
1708                                                                 newctx->gl_framebuffer_binding_read[0]))
1709                                         }
1710                         STATE_COMPARE(gl_framebuffer_binding_draw[0]) {
1711                                 if (driver_gl_version >= 2)
1712                                         CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
1713                                                         newctx->gl_framebuffer_binding_draw[0]))
1714                                         else
1715                                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_DRAW_FRAMEBUFFER,
1716                                                                 newctx->gl_framebuffer_binding_draw[0]))
1717                                         }
1718                 } else {
1719                         STATE_COMPARE(gl_framebuffer_binding[0]) {
1720                                 if (driver_gl_version >= 2)
1721                                         CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER,
1722                                                         newctx->gl_framebuffer_binding[0]))
1723                                         else
1724                                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_FRAMEBUFFER,
1725                                                                 newctx->gl_framebuffer_binding[0]))
1726                                         }
1727                 }
1728                 STATE_COMPARE(gl_renderbuffer_binding[0]) {
1729                         CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER,
1730                                         newctx->gl_renderbuffer_binding[0]))
1731                 }
1732         }
1733
1734         //------------------//
1735         // _bind_flag2
1736         flag = oldctx->_bind_flag2 | newctx->_bind_flag2;
1737         if (flag) {
1738                 STATE_COMPARE(gl_copy_read_buffer_binding[0]) {
1739                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_READ_BUFFER,
1740                                         newctx->gl_copy_read_buffer_binding[0]))
1741                 }
1742                 STATE_COMPARE(gl_copy_write_buffer_binding[0]) {
1743                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_WRITE_BUFFER,
1744                                         newctx->gl_copy_write_buffer_binding[0]))
1745                 }
1746                 STATE_COMPARE(gl_pixel_pack_buffer_binding[0]) {
1747                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_PACK_BUFFER,
1748                                         newctx->gl_pixel_pack_buffer_binding[0]))
1749                 }
1750                 STATE_COMPARE(gl_pixel_unpack_buffer_binding[0]) {
1751                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
1752                                         newctx->gl_pixel_unpack_buffer_binding[0]))
1753                 }
1754                 STATE_COMPARE(gl_transform_feedback_buffer_binding[0]) {
1755                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
1756                                         newctx->gl_transform_feedback_buffer_binding[0]))
1757                 }
1758                 STATE_COMPARE(gl_uniform_buffer_binding[0]) {
1759                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_UNIFORM_BUFFER,
1760                                         newctx->gl_uniform_buffer_binding[0]))
1761                 }
1762         }
1763 #ifdef COREGL_USE_MODULE_TRACEPATH
1764         tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)",
1765                                 trace_hint_bindbuffers, 0);
1766 #endif // COREGL_USE_MODULE_TRACEPATH
1767
1768
1769         //------------------//
1770         // Enable States
1771         // _enable_flag1
1772 #ifdef COREGL_USE_MODULE_TRACEPATH
1773         static void *trace_hint_enable_states = NULL;
1774         trace_hint_enable_states =
1775                 tracepath_api_trace_begin("eglMakeCurrent(FP enable states)",
1776                                           trace_hint_enable_states, 0);
1777 #endif // COREGL_USE_MODULE_TRACEPATH
1778
1779         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
1780         if (flag) {
1781                 STATE_COMPARE(gl_blend[0]) {
1782                         if (newctx->gl_blend[0]) {
1783                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
1784                         } else
1785                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
1786                         }
1787                 STATE_COMPARE(gl_cull_face[0]) {
1788                         if (newctx->gl_cull_face[0]) {
1789                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
1790                         } else
1791                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
1792                         }
1793                 STATE_COMPARE(gl_depth_test[0]) {
1794                         if (newctx->gl_depth_test[0]) {
1795                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
1796                         } else
1797                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
1798                         }
1799                 STATE_COMPARE(gl_dither[0]) {
1800                         if (newctx->gl_dither[0]) {
1801                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
1802                         } else
1803                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
1804                         }
1805         }
1806
1807         // _enable_flag2
1808         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
1809         if (flag) {
1810                 STATE_COMPARE(gl_polygon_offset_fill[0]) {
1811                         if (newctx->gl_polygon_offset_fill[0]) {
1812                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
1813                         } else
1814                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
1815                         }
1816                 STATE_COMPARE(gl_sample_alpha_to_coverage[0]) {
1817                         if (newctx->gl_sample_alpha_to_coverage[0]) {
1818                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1819                         } else
1820                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1821                         }
1822                 STATE_COMPARE(gl_sample_coverage[0]) {
1823                         if (newctx->gl_sample_coverage[0]) {
1824                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
1825                         } else
1826                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
1827                         }
1828                 STATE_COMPARE(gl_scissor_test[0]) {
1829                         if (newctx->gl_scissor_test[0]) {
1830                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
1831                         } else
1832                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
1833                         }
1834                 STATE_COMPARE(gl_stencil_test[0]) {
1835                         if (newctx->gl_stencil_test[0]) {
1836                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
1837                         } else
1838                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
1839                         }
1840         }
1841
1842         // _enable_flag3
1843         flag = oldctx->_enable_flag3 | newctx->_enable_flag3;
1844         if (flag) {
1845                 STATE_COMPARE(gl_primitive_restart_fixed_index[0]) {
1846                         if (newctx->gl_primitive_restart_fixed_index[0]) {
1847                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
1848                         } else
1849                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
1850                         }
1851                 STATE_COMPARE(gl_rasterizer_discard[0]) {
1852                         if (newctx->gl_rasterizer_discard[0]) {
1853                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_RASTERIZER_DISCARD))
1854                         } else
1855                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_RASTERIZER_DISCARD))
1856                         }
1857         }
1858
1859 #ifdef COREGL_USE_MODULE_TRACEPATH
1860         tracepath_api_trace_end("eglMakeCurrent(FP enable states)",
1861                                 trace_hint_enable_states, 0);
1862 #endif // COREGL_USE_MODULE_TRACEPATH
1863
1864         //------------------//
1865         // _clear_flag1
1866 #ifdef COREGL_USE_MODULE_TRACEPATH
1867         static void *trace_hint_clear_viewport = NULL;
1868         trace_hint_clear_viewport =
1869                 tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)",
1870                                           trace_hint_clear_viewport, 0);
1871 #endif // COREGL_USE_MODULE_TRACEPATH
1872
1873         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
1874         if (flag) {
1875                 // Viewport.
1876                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint)) {
1877                         CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
1878                                         newctx->gl_viewport[1],
1879                                         newctx->gl_viewport[2],
1880                                         newctx->gl_viewport[3]))
1881                 }
1882
1883                 STATE_COMPARE(gl_current_program[0]) {
1884                         CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
1885                 }
1886                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf)) {
1887                         CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
1888                                         newctx->gl_color_clear_value[1],
1889                                         newctx->gl_color_clear_value[2],
1890                                         newctx->gl_color_clear_value[3]))
1891                 }
1892         }
1893
1894
1895         // _clear_flag2
1896         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
1897         if (flag) {
1898                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean)) {
1899                         CHECK_GL_ERROR(_orig_fastpath_glColorMask(newctx->gl_color_writemask[0],
1900                                         newctx->gl_color_writemask[1],
1901                                         newctx->gl_color_writemask[2],
1902                                         newctx->gl_color_writemask[3]))
1903                 }
1904                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf)) {
1905                         CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
1906                                         newctx->gl_depth_range[1]))
1907                 }
1908                 STATE_COMPARE(gl_depth_clear_value[0]) {
1909                         CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
1910                 }
1911                 STATE_COMPARE(gl_depth_func[0]) {
1912                         CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
1913                 }
1914                 STATE_COMPARE(gl_depth_writemask[0]) {
1915                         CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
1916                 }
1917                 STATE_COMPARE(gl_cull_face_mode[0]) {
1918                         CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
1919                 }
1920
1921         }
1922
1923 #ifdef COREGL_USE_MODULE_TRACEPATH
1924         tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)",
1925                                 trace_hint_clear_viewport, 0);
1926 #endif // COREGL_USE_MODULE_TRACEPATH
1927
1928         //------------------//
1929         // Texture here...
1930 #ifdef COREGL_USE_MODULE_TRACEPATH
1931         static void *trace_hint_bind_textures = NULL;
1932         trace_hint_bind_textures =
1933                 tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)",
1934                                           trace_hint_bind_textures, 0);
1935 #endif // COREGL_USE_MODULE_TRACEPATH
1936
1937         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1938         if (flag) {
1939
1940                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++) {
1941                         STATE_COMPARE(gl_tex_2d_state[i]) {
1942                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1943                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D,
1944                                                 newctx->gl_tex_2d_state[i]))
1945                         }
1946                         STATE_COMPARE(gl_tex_3d_state[i]) {
1947                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1948                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_3D,
1949                                                 newctx->gl_tex_3d_state[i]))
1950                         }
1951                         STATE_COMPARE(gl_tex_2d_array_state[i]) {
1952                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1953                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_ARRAY,
1954                                                 newctx->gl_tex_2d_array_state[i]))
1955                         }
1956                         STATE_COMPARE(gl_tex_cube_state[i]) {
1957                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1958                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP,
1959                                                 newctx->gl_tex_cube_state[i]))
1960                         }
1961                         STATE_COMPARE(gl_tex_external_oes_state[i]) {
1962                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1963                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_EXTERNAL_OES,
1964                                                 newctx->gl_tex_external_oes_state[i]))
1965                         }
1966                 }
1967
1968                 // Restore active texture
1969                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
1970
1971                 STATE_COMPARE(gl_generate_mipmap_hint[0]) {
1972                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT,
1973                                                              newctx->gl_generate_mipmap_hint[0]))
1974                 }
1975         }
1976 #ifdef COREGL_USE_MODULE_TRACEPATH
1977         tracepath_api_trace_end("eglMakeCurrent(FP bind textures)",
1978                                 trace_hint_bind_textures, 0);
1979 #endif // COREGL_USE_MODULE_TRACEPATH
1980
1981         //------------------//
1982 #ifdef COREGL_USE_MODULE_TRACEPATH
1983         static void *trace_hint_etc = NULL;
1984         trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)",
1985                          trace_hint_etc, 0);
1986 #endif // COREGL_USE_MODULE_TRACEPATH
1987
1988         flag = oldctx->_blend_flag | newctx->_blend_flag;
1989         if (flag) {
1990                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf)) {
1991                         CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
1992                                         newctx->gl_blend_color[1],
1993                                         newctx->gl_blend_color[2],
1994                                         newctx->gl_blend_color[3]))
1995                 }
1996                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1997                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1998                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1999                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0])) {
2000                         CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
2001                                         newctx->gl_blend_dst_rgb[0],
2002                                         newctx->gl_blend_src_alpha[0],
2003                                         newctx->gl_blend_dst_alpha[0]))
2004                 }
2005                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
2006                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0])) {
2007                         CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(
2008                                                newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]))
2009                 }
2010
2011         }
2012
2013         //------------------//
2014         // _stencil_flag1
2015         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
2016         if (flag) {
2017                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
2018                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
2019                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0])) {
2020                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
2021                                         newctx->gl_stencil_func[0],
2022                                         newctx->gl_stencil_ref[0],
2023                                         newctx->gl_stencil_value_mask[0]))
2024                 }
2025                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
2026                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0])
2027                     ||
2028                     (oldctx->gl_stencil_pass_depth_pass[0] !=
2029                      newctx->gl_stencil_pass_depth_pass[0])) {
2030                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
2031                                         newctx->gl_stencil_fail[0],
2032                                         newctx->gl_stencil_pass_depth_fail[0],
2033                                         newctx->gl_stencil_pass_depth_pass[0]))
2034                 }
2035
2036                 STATE_COMPARE(gl_stencil_writemask[0]) {
2037                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT,
2038                                         newctx->gl_stencil_writemask[0]))
2039                 }
2040         }
2041
2042
2043         // _stencil_flag1
2044         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
2045         if (flag) {
2046                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
2047                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
2048                     (oldctx->gl_stencil_back_value_mask[0] !=
2049                      newctx->gl_stencil_back_value_mask[0])) {
2050                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
2051                                         newctx->gl_stencil_back_func[0],
2052                                         newctx->gl_stencil_back_ref[0],
2053                                         newctx->gl_stencil_back_value_mask[0]))
2054                 }
2055                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
2056                     (oldctx->gl_stencil_back_pass_depth_fail[0] !=
2057                      newctx->gl_stencil_back_pass_depth_fail[0]) ||
2058                     (oldctx->gl_stencil_back_pass_depth_pass[0] !=
2059                      newctx->gl_stencil_back_pass_depth_pass[0])) {
2060                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
2061                                         newctx->gl_stencil_back_fail[0],
2062                                         newctx->gl_stencil_back_pass_depth_fail[0],
2063                                         newctx->gl_stencil_back_pass_depth_pass[0]))
2064                 }
2065
2066                 STATE_COMPARE(gl_stencil_back_writemask[0]) {
2067                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK,
2068                                         newctx->gl_stencil_back_writemask[0]))
2069                 }
2070                 STATE_COMPARE(gl_stencil_clear_value[0]) {
2071                         CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
2072                 }
2073         }
2074
2075         //------------------//
2076         // _pixel_flag1
2077         flag = oldctx->_pixel_flag1 | newctx->_pixel_flag1;
2078         if (flag) {
2079                 STATE_COMPARE(gl_pack_row_length[0]) {
2080                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ROW_LENGTH,
2081                                         newctx->gl_pack_row_length[0]))
2082                 }
2083                 STATE_COMPARE(gl_pack_skip_rows[0]) {
2084                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_ROWS,
2085                                         newctx->gl_pack_skip_rows[0]))
2086                 }
2087                 STATE_COMPARE(gl_pack_skip_pixels[0]) {
2088                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_PIXELS,
2089                                         newctx->gl_pack_skip_pixels[0]))
2090                 }
2091                 STATE_COMPARE(gl_pack_alignment[0]) {
2092                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT,
2093                                         newctx->gl_pack_alignment[0]))
2094                 }
2095         }
2096
2097         // _pixel_flag2
2098         flag = oldctx->_pixel_flag2 | newctx->_pixel_flag2;
2099         if (flag) {
2100                 STATE_COMPARE(gl_unpack_row_length[0]) {
2101                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ROW_LENGTH,
2102                                         newctx->gl_unpack_row_length[0]))
2103                 }
2104                 STATE_COMPARE(gl_unpack_skip_rows[0]) {
2105                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_ROWS,
2106                                         newctx->gl_unpack_skip_rows[0]))
2107                 }
2108                 STATE_COMPARE(gl_unpack_skip_pixels[0]) {
2109                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_PIXELS,
2110                                         newctx->gl_unpack_skip_pixels[0]))
2111                 }
2112                 STATE_COMPARE(gl_unpack_alignment[0]) {
2113                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT,
2114                                         newctx->gl_unpack_alignment[0]))
2115                 }
2116                 STATE_COMPARE(gl_unpack_image_height[0]) {
2117                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,
2118                                         newctx->gl_unpack_image_height[0]))
2119                 }
2120                 STATE_COMPARE(gl_unpack_skip_images[0]) {
2121                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_IMAGES,
2122                                         newctx->gl_unpack_skip_images[0]))
2123                 }
2124         }
2125
2126         //------------------//
2127         // _misc_flag1
2128         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
2129         if (flag) {
2130                 STATE_COMPARE(gl_front_face[0]) {
2131                         CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
2132                 }
2133                 STATE_COMPARE(gl_line_width[0]) {
2134                         CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
2135                 }
2136                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0])
2137                     ||
2138                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0])) {
2139                         CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(
2140                                                newctx->gl_polygon_offset_factor[0],
2141                                                newctx->gl_polygon_offset_units[0]))
2142                 }
2143                 if ((oldctx->gl_sample_coverage_value[0]  !=
2144                      newctx->gl_sample_coverage_value[0]) ||
2145                     (oldctx->gl_sample_coverage_invert[0] !=
2146                      newctx->gl_sample_coverage_invert[0])) {
2147                         CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(
2148                                                newctx->gl_sample_coverage_value[0],
2149                                                newctx->gl_sample_coverage_invert[0]))
2150                 }
2151                 STATE_COMPARE(gl_fragment_shader_derivative_hint[0]) {
2152                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES,
2153                                                              newctx->gl_fragment_shader_derivative_hint[0]))
2154                 }
2155         }
2156
2157         // _misc_flag2
2158         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
2159         if (flag) {
2160                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint)) {
2161                         CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
2162                                                                 newctx->gl_scissor_box[1],
2163                                                                 newctx->gl_scissor_box[2],
2164                                                                 newctx->gl_scissor_box[3]))
2165                 }
2166         }
2167
2168         // _misc_flag3
2169         flag = oldctx->_misc_flag3 | newctx->_misc_flag3;
2170         if (flag) {
2171                 STATE_COMPARE(gl_read_buffer[0]) {
2172                         CHECK_GL_ERROR(_orig_fastpath_glReadBuffer(newctx->gl_read_buffer[0]))
2173                 }
2174                 STATES_COMPARE(gl_draw_buffers, 16 * sizeof(GLenum)) {
2175                         int drawBuffSize = 16;
2176                         /* If the  context has only default framebuffer, then size of glDrawBuffers can only be 1 */
2177                         if (fastpath_ostate_has_object_type(&newctx->ostate,
2178                                                             GL_OBJECT_TYPE_FRAMEBUFFER) == 0) {
2179                                 drawBuffSize = 1;
2180                         }
2181
2182                         CHECK_GL_ERROR(_orig_fastpath_glDrawBuffers(drawBuffSize,
2183                                         newctx->gl_draw_buffers))
2184                 }
2185
2186                 if (oldctx->gl_transform_feedback_active[0] == GL_TRUE &&
2187                     oldctx->gl_transform_feedback_paused[0] == GL_FALSE) {
2188                         CHECK_GL_ERROR(_orig_fastpath_glPauseTransformFeedback())
2189                 }
2190                 STATE_COMPARE(gl_transform_feedback_binding[0]) {
2191                         CHECK_GL_ERROR(_orig_fastpath_glBindTransformFeedback(GL_TRANSFORM_FEEDBACK,
2192                                         newctx->gl_transform_feedback_binding[0]))
2193                 }
2194                 if (newctx->gl_transform_feedback_active[0] == GL_TRUE &&
2195                     newctx->gl_transform_feedback_paused[0] == GL_FALSE) {
2196                         CHECK_GL_ERROR(_orig_fastpath_glResumeTransformFeedback())
2197                 }
2198         }
2199
2200 #ifdef COREGL_USE_MODULE_TRACEPATH
2201         tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
2202 #endif // COREGL_USE_MODULE_TRACEPATH
2203
2204         ret = 1;
2205         goto finish;
2206
2207 finish:
2208
2209 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
2210         if (unlikely(trace_state_flag == 1))
2211                 fastpath_dump_context_states(newctx, 0);
2212 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
2213         return ret;
2214 #undef STATE_COMPARE
2215 #undef STATES_COMPARE
2216 }
2217