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