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