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