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