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