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