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