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