[INTERNAL] Added samper objects
[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_, glVertexAttribI4i);
428                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4ui);
429                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4iv);
430                 COREGL_OVERRIDE(fastpath_, glVertexAttribI4uiv);
431                 COREGL_OVERRIDE(fastpath_, glGetUniformuiv);
432                 COREGL_OVERRIDE(fastpath_, glGetFragDataLocation);
433                 COREGL_OVERRIDE(fastpath_, glGetStringi);
434                 COREGL_OVERRIDE(fastpath_, glGetUniformIndices);
435                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformsiv);
436                 COREGL_OVERRIDE(fastpath_, glGetUniformBlockIndex);
437                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockiv);
438                 COREGL_OVERRIDE(fastpath_, glGetActiveUniformBlockName);
439                 COREGL_OVERRIDE(fastpath_, glUniformBlockBinding);
440                 COREGL_OVERRIDE(fastpath_, glGetInteger64v);
441                 COREGL_OVERRIDE(fastpath_, glGetInteger64i_v);
442                 COREGL_OVERRIDE(fastpath_, glGenSamplers);
443                 COREGL_OVERRIDE(fastpath_, glDeleteSamplers);
444                 COREGL_OVERRIDE(fastpath_, glIsSampler);
445                 COREGL_OVERRIDE(fastpath_, glBindSampler);
446                 COREGL_OVERRIDE(fastpath_, glSamplerParameteri);
447                 COREGL_OVERRIDE(fastpath_, glSamplerParameteriv);
448                 COREGL_OVERRIDE(fastpath_, glSamplerParameterf);
449                 COREGL_OVERRIDE(fastpath_, glSamplerParameterfv);
450                 COREGL_OVERRIDE(fastpath_, glGetSamplerParameteriv);
451                 COREGL_OVERRIDE(fastpath_, glGetSamplerParameterfv);
452                 COREGL_OVERRIDE(fastpath_, glVertexAttribDivisor);
453                 COREGL_OVERRIDE(fastpath_, glGetProgramBinary);
454                 COREGL_OVERRIDE(fastpath_, glProgramBinary);
455                 COREGL_OVERRIDE(fastpath_, glProgramParameteri);
456
457         }
458         else
459         {
460                 COREGL_LOG("\E[40;35;1m[CoreGL] SKIP GL FASTPATH...\E[0m\n");
461         }
462 }
463
464 #undef OVERRIDE
465
466 static inline GL_Object_Hash_Base *
467 _get_shared_object_hash(GL_Object_State *ostate, GL_Object_Type type)
468 {
469         switch (type)
470         {
471                 case GL_OBJECT_TYPE_QUERY:
472                         return &ostate->query;
473                 case GL_OBJECT_TYPE_TEXTURE:
474                         return &ostate->shared->texture;
475                 case GL_OBJECT_TYPE_BUFFER:
476                         return &ostate->shared->buffer;
477                 case GL_OBJECT_TYPE_FRAMEBUFFER:
478                         return &ostate->framebuffer;
479                 case GL_OBJECT_TYPE_RENDERBUFFER:
480                         return &ostate->shared->renderbuffer;
481                 case GL_OBJECT_TYPE_PROGRAM:
482                         return &ostate->shared->program;
483                 case GL_OBJECT_TYPE_VERTEXARRAY:
484                         return &ostate->vertexarray;
485                 case GL_OBJECT_TYPE_SAMPLER:
486                         return &ostate->shared->sampler;
487                 case GL_OBJECT_TYPE_TRANSFORMFEEDBACK:
488                         return &ostate->transformfeedback;
489                 default:
490                         return NULL;
491         }
492 }
493
494 static inline GL_Object_Hash_Base *
495 _get_shared_object_hash_real(GL_Object_State *ostate, GL_Object_Type type)
496 {
497         switch (type)
498         {
499                 case GL_OBJECT_TYPE_QUERY:
500                         return &ostate->query_real;
501                 case GL_OBJECT_TYPE_TEXTURE:
502                         return &ostate->shared->texture_real;
503                 case GL_OBJECT_TYPE_BUFFER:
504                         return &ostate->shared->buffer_real;
505                 case GL_OBJECT_TYPE_FRAMEBUFFER:
506                         return &ostate->framebuffer_real;
507                 case GL_OBJECT_TYPE_RENDERBUFFER:
508                         return &ostate->shared->renderbuffer_real;
509                 case GL_OBJECT_TYPE_PROGRAM:
510                         return &ostate->shared->program_real;
511                 case GL_OBJECT_TYPE_VERTEXARRAY:
512                         return &ostate->vertexarray_real;
513                 case GL_OBJECT_TYPE_SAMPLER:
514                         return &ostate->shared->sampler_real;
515                 case GL_OBJECT_TYPE_TRANSFORMFEEDBACK:
516                         return &ostate->transformfeedback_real;
517                 default:
518                         return NULL;
519         }
520 }
521
522 int
523 fastpath_add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
524 {
525         int ret = 0;
526         int tid = 0;
527         GLContext_List *current = NULL;
528         GLContext_List *newitm = NULL;
529
530         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
531
532         AST(cstate != NULL);
533
534         tid = get_current_thread();
535
536         current = glctx_list;
537         while (current != NULL)
538         {
539                 if (current->option_len == option_len &&
540                     memcmp(current->option, option, option_len) == 0 &&
541                     current->thread_id == tid)
542                 {
543                         AST(current->cstate == cstate);
544                         goto finish;
545                 }
546                 current = current->next;
547         }
548
549         newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
550         if (newitm == NULL)
551         {
552                 COREGL_ERR("Failed to create context list.\n");
553                 goto finish;
554         }
555
556         newitm->cstate = cstate;
557         newitm->thread_id = tid;
558         newitm->option_len = option_len;
559         newitm->option = (void *)malloc(option_len);
560         memcpy(newitm->option, option, option_len);
561
562         if (glctx_list != NULL)
563                 newitm->next = glctx_list;
564
565         glctx_list = newitm;
566
567         ret = 1;
568         goto finish;
569
570 finish:
571         if (ret != 1)
572         {
573                 if (newitm != NULL)
574                 {
575                         free(newitm);
576                         newitm = NULL;
577                 }
578                 if (cstate != NULL)
579                 {
580                         free(cstate);
581                         cstate = NULL;
582                 }
583         }
584         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
585
586         return ret;
587 }
588
589 GLContextState *
590 fastpath_get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
591 {
592         GLContextState *ret = NULL;
593         GLContext_List *current = NULL;
594         int tid = 0;
595
596         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
597
598         tid = get_current_thread();
599
600         current = glctx_list;
601         while (current != NULL)
602         {
603                 if (current->option_len == option_len &&
604                     memcmp(current->option, option, option_len) == 0 &&
605                     current->thread_id == tid)
606                 {
607                         ret = current->cstate;
608                         goto finish;
609                 }
610                 current = current->next;
611         }
612         goto finish;
613
614 finish:
615         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
616         return ret;
617 }
618
619 int
620 fastpath_remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
621 {
622         int ret = 0;
623         int tid = 0;
624         GLContext_List *olditm = NULL;
625         GLContext_List *current = NULL;
626
627         if (mtx != NULL) AST(mutex_lock(mtx) == 1);
628
629         AST(cstate != NULL);
630
631         tid = get_current_thread();
632         current = glctx_list;
633
634         while (current != NULL)
635         {
636                 if (current->cstate == cstate)
637                 {
638                         GLContext_List *nextitm = NULL;
639                         if (olditm != NULL)
640                         {
641                                 olditm->next = current->next;
642                                 nextitm = olditm->next;
643                         }
644                         else
645                         {
646                                 glctx_list = current->next;
647                                 nextitm = glctx_list;
648                         }
649                         if (current->option != NULL)
650                         {
651                                 AST(current->option_len > 0);
652                                 free(current->option);
653                                 current->option = NULL;
654                                 current->option_len = 0;
655                         }
656                         free(current);
657                         ret = 1;
658                         current = nextitm;
659                         continue;
660                 }
661                 olditm = current;
662                 current = current->next;
663         }
664         goto finish;
665
666 finish:
667         if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
668         return ret;
669 }
670
671
672
673 #define HASH_INIT(hash_base) \
674         hash_base.hash_field = (GL_Object_Hash **)calloc(1, sizeof(GL_Object_Hash *) * GL_OBJECT_HASH_BASE); \
675         hash_base.hash_size = GL_OBJECT_HASH_BASE;
676
677 void
678 fastpath_ostate_init(GL_Object_State *ostate)
679 {
680         HASH_INIT(ostate->query);
681         HASH_INIT(ostate->framebuffer);
682         HASH_INIT(ostate->vertexarray);
683         HASH_INIT(ostate->transformfeedback);
684
685         HASH_INIT(ostate->query_real);
686         HASH_INIT(ostate->framebuffer_real);
687         HASH_INIT(ostate->vertexarray_real);
688         HASH_INIT(ostate->transformfeedback_real);
689 }
690
691 void
692 fastpath_sostate_init(GL_Shared_Object_State *sostate)
693 {
694         mutex_init(&sostate->access_mutex);
695
696         HASH_INIT(sostate->texture);
697         HASH_INIT(sostate->buffer);
698         HASH_INIT(sostate->renderbuffer);
699         HASH_INIT(sostate->program);
700         HASH_INIT(sostate->sampler);
701
702         HASH_INIT(sostate->texture_real);
703         HASH_INIT(sostate->buffer_real);
704         HASH_INIT(sostate->renderbuffer_real);
705         HASH_INIT(sostate->program_real);
706         HASH_INIT(sostate->sampler_real);
707 }
708
709 #undef HASH_INIT
710
711
712 static void
713 _add_hash(GL_Object_Hash_Base *hash_base, GL_Object_Hash *data)
714 {
715         int array_idx = data->hash_key & (hash_base->hash_size - 1);
716         if (hash_base->hash_field[array_idx] == NULL)
717         {
718                 hash_base->hash_field[array_idx] = data;
719         }
720         else
721         {
722                 GL_Object_Hash *current = hash_base->hash_field[array_idx];
723                 while(current->next)
724                 {
725                         AST(current->hash_key != data->hash_key);
726                         current = current->next;
727                 }
728                 current->next = data;
729         }
730         data->next = NULL;
731         hash_base->item_size++;
732 }
733
734 static int
735 _remove_hash(GL_Object_Hash_Base *hash_base, GLuint hash)
736 {
737         int ret = 0;
738         int array_idx = hash & (hash_base->hash_size - 1);
739
740         GL_Object_Hash *current = hash_base->hash_field[array_idx];
741         GL_Object_Hash *prev = NULL;
742
743         while(current)
744         {
745                 if (current->hash_key == hash)
746                 {
747                         if (prev != NULL)
748                                 prev->next = current->next;
749                         else
750                                 hash_base->hash_field[array_idx] = current->next;
751                         hash_base->item_size--;
752                         ret = 1;
753                         break;
754                 }
755                 prev = current;
756                 current = current->next;
757         }
758
759         return ret;
760 }
761
762 static void
763 _free_hash_list(GL_Object_Hash_Base *hash_base, int free_data)
764 {
765         if (hash_base->item_size == 0) return;
766
767         for (int i = 0; i < hash_base->hash_size; i++)
768         {
769                 if (hash_base->hash_field[i] != NULL)
770                 {
771                         GL_Object_Hash *current = hash_base->hash_field[i];
772
773                         while (current != NULL)
774                         {
775                                 GL_Object_Hash *current_next = current->next;
776
777                                 if (free_data == 1 && current->item != NULL)
778                                 {
779                                         free(current->item);
780                                 }
781
782                                 free(current);
783                                 hash_base->item_size--;
784                                 current = current_next;
785                         }
786                 }
787         }
788 }
789
790
791
792 #define HASH_DEINIT(hash_base, free_data) \
793         _free_hash_list(&hash_base, free_data); \
794         free(hash_base.hash_field); \
795         hash_base.hash_size = 0;
796
797 void
798 fastpath_ostate_deinit(GL_Object_State *ostate)
799 {
800         HASH_DEINIT(ostate->query, 1);
801         HASH_DEINIT(ostate->framebuffer, 1);
802         HASH_DEINIT(ostate->vertexarray, 1);
803         HASH_DEINIT(ostate->transformfeedback, 1);
804
805         HASH_DEINIT(ostate->query_real, 0);
806         HASH_DEINIT(ostate->framebuffer_real, 0);
807         HASH_DEINIT(ostate->vertexarray_real, 0);
808         HASH_DEINIT(ostate->transformfeedback_real, 0);
809 }
810
811 void
812 fastpath_sostate_deinit(GL_Shared_Object_State *sostate)
813 {
814         HASH_DEINIT(sostate->texture, 1);
815         HASH_DEINIT(sostate->buffer, 1);
816         HASH_DEINIT(sostate->renderbuffer, 1);
817         HASH_DEINIT(sostate->program, 1);
818         HASH_DEINIT(sostate->sampler, 1);
819
820         HASH_DEINIT(sostate->texture_real, 0);
821         HASH_DEINIT(sostate->buffer_real, 0);
822         HASH_DEINIT(sostate->renderbuffer_real, 0);
823         HASH_DEINIT(sostate->program_real, 0);
824         HASH_DEINIT(sostate->sampler_real, 0);
825 }
826
827 #undef HASH_DEINIT
828
829
830
831 #define FIND_HASH(hash_base, key, ret) \
832 { \
833         GL_Object_Hash *fh_current = hash_base->hash_field[(key) & (hash_base->hash_size - 1)]; \
834         while(fh_current) \
835         { \
836                 if (fh_current->hash_key == (key)) \
837                 { \
838                         ret = fh_current; \
839                         break; \
840                 } \
841                 fh_current = fh_current->next; \
842         } \
843 }
844
845 void
846 _ostate_hash_check(GL_Object_Hash_Base *hash_base)
847 {
848         if (hash_base->item_size + 1 < hash_base->hash_size)
849                 return;
850
851         int oldsize = hash_base->hash_size;
852         GL_Object_Hash **oldfield = hash_base->hash_field;
853
854         hash_base->hash_size = oldsize << 1;
855         hash_base->hash_field = (GL_Object_Hash **)calloc(1, sizeof(GL_Object_Hash *) * hash_base->hash_size);
856         AST(hash_base->hash_field != NULL);
857
858         for (int i = 0; i < oldsize; i++)
859         {
860                 if (oldfield[i] != NULL)
861                 {
862                         GL_Object_Hash *current = oldfield[i];
863
864                         while (current != NULL)
865                         {
866                                 GL_Object_Hash *current_next = current->next;
867                                 _add_hash(hash_base, current);
868                                 hash_base->item_size--;
869                                 current = current_next;
870                         }
871                 }
872         }
873         free(oldfield);
874
875 }
876
877 GLuint
878 fastpath_ostate_create_object(GL_Object_State *ostate, GL_Object_Type type, GLuint real_name)
879 {
880         GLuint ret = _COREGL_INT_INIT_VALUE;
881
882         GL_Object_Hash_Base *hash_base = NULL;
883         GL_Object_Hash_Base *hash_base_real = NULL;
884         int newid = _COREGL_INT_INIT_VALUE;
885
886         hash_base = _get_shared_object_hash(ostate, type);
887         hash_base_real = _get_shared_object_hash_real(ostate, type);
888
889         newid = hash_base->last_id + 1;
890         if (newid >= hash_base->hash_size)
891         {
892                 hash_base->is_looped = 1;
893                 newid = 1;
894                 hash_base->last_id = 1;
895         }
896
897         if (hash_base->is_looped != 0)
898         {
899                 int i;
900                 int findingid = newid;
901                 newid = -1;
902                 for (i = 0; i < hash_base->hash_size; i++)
903                 {
904                         GL_Object_Hash *exist_hash = NULL;
905                         FIND_HASH(hash_base, findingid, exist_hash);
906                         if (exist_hash == NULL)
907                         {
908                                 newid = findingid;
909                                 break;
910                         }
911                         findingid++;
912                         if (findingid >= hash_base->hash_size) findingid = 1;
913                 }
914                 AST(newid != -1);
915         }
916         hash_base->last_id = newid;
917
918         {
919                 GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
920                 AST(newobj != NULL);
921                 newobj->id = (int)type + newid;
922                 newobj->real_id = real_name;
923                 newobj->ref_count = 1;
924                 ret = newobj->id;
925
926                 GL_Object_Hash *newobj_hash = (GL_Object_Hash *)calloc(1, sizeof(GL_Object_Hash));
927                 AST(newobj_hash != NULL);
928                 newobj_hash->item = newobj;
929                 newobj_hash->hash_key = newid;
930                 _add_hash(hash_base, newobj_hash);
931
932                 GL_Object_Hash *newobj_hash_real = (GL_Object_Hash *)calloc(1, sizeof(GL_Object_Hash));
933                 AST(newobj_hash_real != NULL);
934                 newobj_hash_real->item = newobj;
935                 newobj_hash_real->hash_key = real_name;
936                 _add_hash(hash_base_real, newobj_hash_real);
937         }
938
939         _ostate_hash_check(hash_base);
940         _ostate_hash_check(hash_base_real);
941
942         goto finish;
943
944 finish:
945         return ret;
946 }
947
948 #define FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object) \
949         if (((int)(hash)) < 0) { ret = 0; goto finish; } \
950         { \
951                 GL_Object_Hash *object_hash = NULL; \
952                 FIND_HASH((hash_base), (int)(hash), object_hash); \
953                 if (object_hash == NULL) { ret = 0; goto finish; } \
954                 (object) = object_hash->item; \
955                 if ((object) == NULL) { ret = 0; goto finish; } \
956         }
957
958 GLuint
959 fastpath_ostate_remove_object(GL_Object_State *ostate, GL_Object_Type type, GLuint glue_name)
960 {
961         GLuint ret = _COREGL_INT_INIT_VALUE;
962
963         GL_Object_Hash_Base *hash_base = NULL;
964         GL_Object_Hash_Base *hash_base_real = NULL;
965         GL_Object *object = NULL;
966
967         hash_base = _get_shared_object_hash(ostate, type);
968         hash_base_real = _get_shared_object_hash_real(ostate, type);
969
970         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
971
972         object->ref_count--;
973
974         if (object->ref_count <= 0)
975         {
976                 GL_Object_Hash *object_hash = NULL;
977
978                 FIND_HASH(hash_base, object->id - (int)type, object_hash);
979                 AST(object_hash != NULL);
980                 _remove_hash(hash_base, object->id - (int)type);
981                 free(object_hash);
982                 object_hash = NULL;
983
984                 FIND_HASH(hash_base_real, object->real_id, object_hash);
985                 AST(object_hash != NULL);
986                 _remove_hash(hash_base_real, object->real_id);
987                 free(object_hash);
988                 object_hash = NULL;
989
990                 free(object);
991                 object = NULL;
992         }
993
994         ret = 1;
995         goto finish;
996
997 finish:
998         return ret;
999 }
1000
1001 GLuint
1002 fastpath_ostate_get_object(GL_Object_State *ostate, GL_Object_Type type, GLuint glue_name)
1003 {
1004         GLuint ret = _COREGL_INT_INIT_VALUE;
1005
1006         GL_Object_Hash_Base *hash_base = NULL;
1007         GL_Object *object = NULL;
1008
1009         hash_base = _get_shared_object_hash(ostate, type);
1010
1011         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1012
1013         ret = object->real_id;
1014         goto finish;
1015
1016 finish:
1017         return ret;
1018 }
1019
1020 GLint
1021 fastpath_ostate_set_object_tag(GL_Object_State *ostate, GL_Object_Type type, GLuint glue_name, GLvoid *tag)
1022 {
1023         GLint ret = _COREGL_INT_INIT_VALUE;
1024
1025         GL_Object_Hash_Base *hash_base = NULL;
1026         GL_Object *object = NULL;
1027         int hash = _COREGL_INT_INIT_VALUE;
1028
1029         hash_base = _get_shared_object_hash(ostate, type);
1030
1031         hash = glue_name - (int)type;
1032
1033         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, hash, object);
1034
1035         AST(object->tag == NULL);
1036         object->tag = tag;
1037         ret = 1;
1038         goto finish;
1039
1040 finish:
1041         return ret;
1042 }
1043
1044 GLvoid *
1045 fastpath_ostate_get_object_tag(GL_Object_State *ostate, GL_Object_Type type, GLuint glue_name)
1046 {
1047         GLvoid *ret = NULL;
1048
1049         GL_Object_Hash_Base *hash_base = NULL;
1050         GL_Object *object = NULL;
1051
1052         hash_base = _get_shared_object_hash(ostate, type);
1053
1054         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1055
1056         ret = object->tag;
1057         goto finish;
1058
1059 finish:
1060         return ret;
1061 }
1062
1063 GLuint
1064 fastpath_ostate_find_object(GL_Object_State *ostate, GL_Object_Type type, GLuint real_name)
1065 {
1066         GLuint ret = _COREGL_INT_INIT_VALUE;
1067
1068         GL_Object_Hash_Base *hash_base_real = NULL;
1069         GL_Object *object = NULL;
1070
1071         hash_base_real = _get_shared_object_hash_real(ostate, type);
1072
1073         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base_real, real_name, object);
1074
1075         ret = object->id;
1076         goto finish;
1077
1078 finish:
1079         return ret;
1080 }
1081
1082 GLint
1083 fastpath_ostate_use_object(GL_Object_State *ostate, GL_Object_Type type, GLuint glue_name)
1084 {
1085         GLint ret = _COREGL_INT_INIT_VALUE;
1086
1087         GL_Object_Hash_Base *hash_base = NULL;
1088         GL_Object *object = NULL;
1089
1090         hash_base = _get_shared_object_hash(ostate, type);
1091
1092         FIND_OBJ_FROM_HASH_WITH_VERIFY(hash_base, glue_name - (int)type, object);
1093
1094         object->ref_count++;
1095         ret = 1;
1096         goto finish;
1097
1098 finish:
1099         return ret;
1100 }
1101
1102 void
1103 fastpath_dump_context_states(GLGlueContext *ctx, int force_output)
1104 {
1105         static struct timeval tv_last = { 0, 0 };
1106
1107         if (unlikely(trace_state_flag != 1)) return;
1108
1109         if (!force_output)
1110         {
1111                 struct timeval tv_now = { 0, 0 };
1112                 AST(gettimeofday(&tv_now, NULL) == 0);
1113                 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
1114                 {
1115                         goto finish;
1116                 }
1117                 tv_last = tv_now;
1118         }
1119
1120         TRACE("\n");
1121         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1122         TRACE("\E[40;32;1m  State info \E[1;37;1m: <PID = %d> GlueCTX = %p\E[0m\n", getpid(), ctx);
1123         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1124
1125 #define PRINTF_CHAR_GLenum "%10d"
1126 #define PRINTF_CHAR_GLboolean "%10d"
1127 #define PRINTF_CHAR_GLint "%10d"
1128 #define PRINTF_CHAR_GLsizei "%10u"
1129 #define PRINTF_CHAR_GLuint "%10u"
1130 #define PRINTF_CHAR_GLuintmask "0x%8X"
1131 #define PRINTF_CHAR_GLintptr "0x%8X"
1132 #define PRINTF_CHAR_GLsizeiptr "%10d"
1133
1134 #define PRINTF_CHAR_GLclampf "%10.6f"
1135 #define PRINTF_CHAR_GLfloat "%10.6f"
1136
1137 #define PRINTF_CHAR_GLvoidptr "%10p"
1138
1139 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
1140
1141 #define INITIAL_CTX initial_ctx
1142 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1143    { \
1144       TYPE valuedata[SIZE]; \
1145       TYPE *value = NULL; \
1146       value = valuedata; GET_STMT; value = valuedata; \
1147       TRACE("\E[40;37;1m %-30.30s : (\E[0m ", #NAME); \
1148       for (int i = 0; i < SIZE; i++) \
1149       { \
1150          if (i > 0) { \
1151             if (i % 4 == 0) \
1152                TRACE("\n %-30.30s     ", "");\
1153             else \
1154                TRACE(", "); \
1155          } \
1156          TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
1157          TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
1158       } \
1159       TRACE(" \E[40;37;1m)\E[0m\n"); \
1160    }
1161 # include "coregl_fastpath_state.h"
1162 #undef GLUE_STATE
1163 #undef INITIAL_CTX
1164
1165         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
1166         TRACE("\n");
1167
1168         TRACE_END();
1169
1170 finish:
1171         return;
1172 }
1173
1174 int
1175 fastpath_init_context_states(GLGlueContext *ctx)
1176 {
1177         int ret = 0;
1178
1179         AST(mutex_lock(&init_context_mutex) == 1);
1180
1181         if (ctx == NULL)
1182         {
1183                 COREGL_ERR("Context NULL\n");
1184                 ret = 0;
1185                 goto finish;
1186         }
1187
1188         AST(ctx->initialized == 0);
1189         AST(ctx->ostate.shared != NULL);
1190
1191         if (initial_ctx == NULL)
1192         {
1193                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
1194                 AST(initial_ctx != NULL);
1195
1196 //#define FORCE_DEFAULT_VALUE
1197 #ifdef FORCE_DEFAULT_VALUE
1198 # define INITIAL_CTX initial_ctx
1199 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1200       { \
1201          int i; \
1202          TYPE valuedata[SIZE]; \
1203          TYPE *value = NULL; \
1204          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1205          value = valuedata; DEFAULT_STMT; value = valuedata; \
1206          for (i = 0; i < SIZE; i++) \
1207          { \
1208             if (*((char *)(&value[i])) == 0xcc) \
1209             { \
1210                memset(&value[i], 0xaa, sizeof(TYPE)); \
1211                value = valuedata; DEFAULT_STMT; value = valuedata; \
1212                if (*((char *)(&value[i])) == 0xaa) \
1213                { \
1214                   COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1215                   break; \
1216                } \
1217             } \
1218             initial_ctx->NAME[i] = value[i]; \
1219          } \
1220       }
1221 #  include "coregl_fastpath_state.h"
1222 # undef GLUE_STATE
1223 # undef INITIAL_CTX
1224 #else
1225 # define INITIAL_CTX initial_ctx
1226 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
1227       if (try_step == 1) \
1228       { \
1229          value = valuedata; DEFAULT_STMT; value = valuedata; \
1230       } \
1231       else \
1232       { \
1233          value = valuedata; FALLBACK_STMT; value = valuedata; \
1234       }
1235
1236 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1237       { \
1238          int i; \
1239          int try_step = 0;\
1240          TYPE valuedata[SIZE]; \
1241          TYPE *value = NULL; \
1242          _sym_glGetError(); \
1243          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
1244          do { \
1245             try_step++; \
1246             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1247             if (_sym_glGetError() == GL_INVALID_ENUM) \
1248             { \
1249                                         initial_ctx->NAME##_used = 0; \
1250                                         value = valuedata; DEFAULT_STMT; value = valuedata; \
1251                     break; \
1252             } \
1253                                 initial_ctx->NAME##_used = 1; \
1254             for (i = 0; i < SIZE; i++) \
1255             { \
1256                if (*((char *)(&value[i])) == 0xcc) \
1257                { \
1258                   memset(&value[i], 0xaa, sizeof(TYPE)); \
1259                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
1260                   if (*((char *)(&value[i])) == 0xaa) \
1261                   { \
1262                      try_step++; \
1263                      if (try_step == 2) \
1264                      { \
1265                         COREGL_WRN("\E[40;31;1mGL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
1266                      } \
1267                      break; \
1268                   } \
1269                } \
1270                initial_ctx->NAME[i] = value[i]; \
1271             } \
1272             if (try_step != 2) \
1273             { \
1274                value = valuedata; DEFAULT_STMT; value = valuedata; \
1275                for (i = 0; i < SIZE; i++) \
1276                { \
1277                   if (initial_ctx->NAME[i] != value[i]) \
1278                   { \
1279                      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]); \
1280                   } \
1281                } \
1282             } \
1283          } \
1284          while (try_step == 2); \
1285       }
1286 #  include "coregl_fastpath_state.h"
1287 # undef SET_GLUE_VALUE
1288 # undef GLUE_STATE
1289 # undef INITIAL_CTX
1290 #endif
1291
1292                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
1293                 {
1294                         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]);
1295                 }
1296                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
1297                 {
1298                         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]);
1299                 }
1300         }
1301
1302         {
1303                 int i;
1304 #define INITIAL_CTX initial_ctx
1305 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
1306          for (i = 0; i < SIZE; i++) \
1307          { \
1308             ctx->NAME[i] = initial_ctx->NAME[i]; \
1309             ctx->NAME##_used = initial_ctx->NAME##_used; \
1310          }
1311 # include "coregl_fastpath_state.h"
1312 #undef GLUE_STATE
1313 #undef INITIAL_CTX
1314         }
1315
1316         ctx->initialized = 1;
1317         ret = 1;
1318         goto finish;
1319
1320 finish:
1321         AST(mutex_unlock(&init_context_mutex) == 1);
1322
1323         return ret;
1324 }
1325
1326 #ifdef COREGL_USE_MODULE_TRACEPATH
1327 extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
1328 extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
1329 #endif
1330
1331 #define CHECK_GL_ERROR(func) \
1332         { \
1333                 func; \
1334                 int err = _orig_fastpath_glGetError(); \
1335                 if (err != GL_NO_ERROR) \
1336                 { \
1337                         COREGL_ERR("\E[40;31;1m(GL %p) : %s returns GL error 0x%X\E[0m\n", oldctx->cstate, #func, err); \
1338                         goto finish; \
1339                 } \
1340         }
1341
1342 int
1343 fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
1344 {
1345         int ret = 0;
1346         unsigned char flag = 0;
1347         int i = 0;
1348
1349         if (debug_nofp == 1)
1350         {
1351                 ret = 1;
1352                 goto finish;
1353         }
1354
1355         // Return if they're the same
1356         if (oldctx == newctx)
1357         {
1358                 ret = 1;
1359                 goto finish;
1360         }
1361
1362 #define STATE_COMPARE(state) \
1363    if ((oldctx->state) != (newctx->state))
1364
1365 #define STATES_COMPARE(state_ptr, bytes) \
1366    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
1367
1368
1369 #ifdef COREGL_USE_MODULE_TRACEPATH
1370         static void *trace_hint_glfinish = NULL;
1371         trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
1372 #endif // COREGL_USE_MODULE_TRACEPATH
1373
1374         {
1375                 int err = _orig_fastpath_glGetError();
1376                 if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR)
1377                         oldctx->gl_error = err;
1378         }
1379
1380         CHECK_GL_ERROR(_orig_fastpath_glFlush())
1381
1382 #ifdef COREGL_USE_MODULE_TRACEPATH
1383         tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
1384 #endif // COREGL_USE_MODULE_TRACEPATH
1385
1386         // _varray_flag
1387 #ifdef COREGL_USE_MODULE_TRACEPATH
1388         static void *trace_hint_vertex_attrib = NULL;
1389         trace_hint_vertex_attrib = tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1390 #endif // COREGL_USE_MODULE_TRACEPATH
1391
1392         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
1393         if (flag)
1394         {
1395                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
1396                 {
1397                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
1398                         {
1399                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]))
1400                         }
1401                         else
1402                         {
1403                                 CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
1404                         }
1405
1406                         STATE_COMPARE(gl_vertex_array_divisor[i])
1407                         {
1408                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribDivisor(i, newctx->gl_vertex_array_divisor[i]))
1409                         }
1410
1411                         if (newctx->gl_vertex_array_pointer[i] != NULL)
1412                         {
1413                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
1414                                                newctx->gl_vertex_array_size[i],
1415                                                newctx->gl_vertex_array_type[i],
1416                                                newctx->gl_vertex_array_normalized[i],
1417                                                newctx->gl_vertex_array_stride[i],
1418                                                newctx->gl_vertex_array_pointer[i]))
1419                         }
1420                         else
1421                         {
1422                                 if (newctx->gl_vertex_array_integer[0] == GL_TRUE)
1423                                 {
1424                                         if (newctx->gl_vertex_array_type[0] == GL_UNSIGNED_INT)
1425                                         {
1426                                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4uiv(i, &newctx->gl_vertex_attrib_value_unsigned_integer[4 * i]))
1427                                         }
1428                                         else
1429                                         {
1430                                                 CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4iv(i, &newctx->gl_vertex_attrib_value_integer[4 * i]))
1431                                         }
1432                                 }
1433                                 else
1434                                 {
1435                                         CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]))
1436                                 }
1437                         }
1438
1439                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
1440                         {
1441                                 CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
1442                         }
1443                         else
1444                         {
1445                                 CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
1446                         }
1447                 }
1448
1449         }
1450
1451 #ifdef COREGL_USE_MODULE_TRACEPATH
1452         tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
1453 #endif // COREGL_USE_MODULE_TRACEPATH
1454
1455
1456 #ifdef COREGL_USE_MODULE_TRACEPATH
1457         static void *trace_hint_bindbuffers = NULL;
1458         trace_hint_bindbuffers = tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
1459 #endif // COREGL_USE_MODULE_TRACEPATH
1460
1461         //------------------//
1462         // _bind_flag
1463         flag = oldctx->_bind_flag | newctx->_bind_flag;
1464         if (flag)
1465         {
1466                 STATE_COMPARE(gl_array_buffer_binding[0])
1467                 {
1468                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]))
1469                 }
1470                 STATE_COMPARE(gl_copy_read_buffer_binding[0])
1471                 {
1472                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_READ_BUFFER, newctx->gl_copy_read_buffer_binding[0]))
1473                 }
1474                 STATE_COMPARE(gl_copy_write_buffer_binding[0])
1475                 {
1476                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_WRITE_BUFFER, newctx->gl_copy_write_buffer_binding[0]))
1477                 }
1478                 STATE_COMPARE(gl_element_array_buffer_binding[0])
1479                 {
1480                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]))
1481                 }
1482                 STATE_COMPARE(gl_pixel_pack_buffer_binding[0])
1483                 {
1484                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_PACK_BUFFER, newctx->gl_pixel_pack_buffer_binding[0]))
1485                 }
1486                 STATE_COMPARE(gl_pixel_unpack_buffer_binding[0])
1487                 {
1488                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, newctx->gl_pixel_unpack_buffer_binding[0]))
1489                 }
1490                 STATE_COMPARE(gl_transform_feedback_buffer_binding[0])
1491                 {
1492                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, newctx->gl_transform_feedback_buffer_binding[0]))
1493                 }
1494                 STATE_COMPARE(gl_uniform_buffer_binding[0])
1495                 {
1496                         CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_UNIFORM_BUFFER, newctx->gl_uniform_buffer_binding[0]))
1497                 }
1498                 // ANGLE_framebuffer_blit BEGIN
1499                 if (newctx->gl_framebuffer_binding_read_used == 1)
1500                 {
1501                         STATE_COMPARE(gl_framebuffer_binding_read[0])
1502                         {
1503                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, newctx->gl_framebuffer_binding_read[0]))
1504                         }
1505                         STATE_COMPARE(gl_framebuffer_binding_draw[0])
1506                         {
1507                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, newctx->gl_framebuffer_binding_draw[0]))
1508                         }
1509                 }
1510                 else
1511                 // ANGLE_framebuffer_blit END
1512                 {
1513                         STATE_COMPARE(gl_framebuffer_binding[0])
1514                         {
1515                                 CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]))
1516                         }
1517                 }
1518                 STATE_COMPARE(gl_renderbuffer_binding[0])
1519                 {
1520                         CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]))
1521                 }
1522         }
1523
1524 #ifdef COREGL_USE_MODULE_TRACEPATH
1525         tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
1526 #endif // COREGL_USE_MODULE_TRACEPATH
1527
1528
1529         //------------------//
1530         // Enable States
1531         // _enable_flag1
1532 #ifdef COREGL_USE_MODULE_TRACEPATH
1533         static void *trace_hint_enable_states = NULL;
1534         trace_hint_enable_states = tracepath_api_trace_begin("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
1535 #endif // COREGL_USE_MODULE_TRACEPATH
1536
1537         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
1538         if (flag)
1539         {
1540                 STATE_COMPARE(gl_blend[0])
1541                 {
1542                         if (newctx->gl_blend[0])
1543                         {
1544                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
1545                         }
1546                         else
1547                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
1548                 }
1549                 STATE_COMPARE(gl_cull_face[0])
1550                 {
1551                         if (newctx->gl_cull_face[0])
1552                         {
1553                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
1554                         }
1555                         else
1556                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
1557                 }
1558                 STATE_COMPARE(gl_depth_test[0])
1559                 {
1560                         if (newctx->gl_depth_test[0])
1561                         {
1562                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
1563                         }
1564                         else
1565                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
1566                 }
1567                 STATE_COMPARE(gl_dither[0])
1568                 {
1569                         if (newctx->gl_dither[0])
1570                         {
1571                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
1572                         }
1573                         else
1574                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
1575                 }
1576         }
1577
1578         // _enable_flag2
1579         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
1580         if (flag)
1581         {
1582                 STATE_COMPARE(gl_polygon_offset_fill[0])
1583                 {
1584                         if (newctx->gl_polygon_offset_fill[0])
1585                         {
1586                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
1587                         }
1588                         else
1589                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
1590                 }
1591                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
1592                 {
1593                         if (newctx->gl_sample_alpha_to_coverage[0])
1594                         {
1595                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1596                         }
1597                         else
1598                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
1599                 }
1600                 STATE_COMPARE(gl_sample_coverage[0])
1601                 {
1602                         if (newctx->gl_sample_coverage[0])
1603                         {
1604                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
1605                         }
1606                         else
1607                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
1608                 }
1609                 STATE_COMPARE(gl_scissor_test[0])
1610                 {
1611                         if (newctx->gl_scissor_test[0])
1612                         {
1613                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
1614                         }
1615                         else
1616                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
1617                 }
1618                 STATE_COMPARE(gl_stencil_test[0])
1619                 {
1620                         if (newctx->gl_stencil_test[0])
1621                         {
1622                                 CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
1623                         }
1624                         else
1625                                 CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
1626                 }
1627         }
1628
1629 #ifdef COREGL_USE_MODULE_TRACEPATH
1630         tracepath_api_trace_end("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
1631 #endif // COREGL_USE_MODULE_TRACEPATH
1632
1633         //------------------//
1634         // _clear_flag1
1635 #ifdef COREGL_USE_MODULE_TRACEPATH
1636         static void *trace_hint_clear_viewport = NULL;
1637         trace_hint_clear_viewport = tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1638 #endif // COREGL_USE_MODULE_TRACEPATH
1639
1640         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
1641         if (flag)
1642         {
1643                 // Viewport.
1644                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
1645                 {
1646                         CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
1647                                        newctx->gl_viewport[1],
1648                                        newctx->gl_viewport[2],
1649                                        newctx->gl_viewport[3]))
1650                 }
1651
1652                 STATE_COMPARE(gl_current_program[0])
1653                 {
1654                         CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
1655                 }
1656                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
1657                 {
1658                         CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
1659                                        newctx->gl_color_clear_value[1],
1660                                        newctx->gl_color_clear_value[2],
1661                                        newctx->gl_color_clear_value[3]))
1662                 }
1663         }
1664
1665
1666         // _clear_flag2
1667         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
1668         if (flag)
1669         {
1670                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
1671                 {
1672                         CHECK_GL_ERROR(_orig_fastpath_glColorMask(newctx->gl_color_writemask[0],
1673                                        newctx->gl_color_writemask[1],
1674                                        newctx->gl_color_writemask[2],
1675                                        newctx->gl_color_writemask[3]))
1676                 }
1677                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
1678                 {
1679                         CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
1680                                        newctx->gl_depth_range[1]))
1681                 }
1682                 STATE_COMPARE(gl_depth_clear_value[0])
1683                 {
1684                         CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
1685                 }
1686                 STATE_COMPARE(gl_depth_func[0])
1687                 {
1688                         CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
1689                 }
1690                 STATE_COMPARE(gl_depth_writemask[0])
1691                 {
1692                         CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
1693                 }
1694                 STATE_COMPARE(gl_cull_face_mode[0])
1695                 {
1696                         CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
1697                 }
1698
1699         }
1700
1701 #ifdef COREGL_USE_MODULE_TRACEPATH
1702         tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
1703 #endif // COREGL_USE_MODULE_TRACEPATH
1704
1705         //------------------//
1706         // Texture here...
1707 #ifdef COREGL_USE_MODULE_TRACEPATH
1708         static void *trace_hint_bind_textures = NULL;
1709         trace_hint_bind_textures = tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1710 #endif // COREGL_USE_MODULE_TRACEPATH
1711
1712         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
1713         if (flag)
1714         {
1715
1716                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
1717                 {
1718                         STATE_COMPARE(gl_tex_2d_state[i])
1719                         {
1720                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1721                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]))
1722                         }
1723
1724                         STATE_COMPARE(gl_tex_cube_state[i])
1725                         {
1726                                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
1727                                 CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]))
1728                         }
1729                 }
1730
1731                 // Restore active texture
1732                 CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
1733
1734                 STATE_COMPARE(gl_generate_mipmap_hint[0])
1735                 {
1736                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]))
1737                 }
1738         }
1739 #ifdef COREGL_USE_MODULE_TRACEPATH
1740         tracepath_api_trace_end("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
1741 #endif // COREGL_USE_MODULE_TRACEPATH
1742
1743         //------------------//
1744 #ifdef COREGL_USE_MODULE_TRACEPATH
1745         static void *trace_hint_etc = NULL;
1746         trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1747 #endif // COREGL_USE_MODULE_TRACEPATH
1748
1749         flag = oldctx->_blend_flag | newctx->_blend_flag;
1750         if (flag)
1751         {
1752                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
1753                 {
1754                         CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
1755                                        newctx->gl_blend_color[1],
1756                                        newctx->gl_blend_color[2],
1757                                        newctx->gl_blend_color[3]))
1758                 }
1759                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
1760                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
1761                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
1762                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
1763                 {
1764                         CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
1765                                        newctx->gl_blend_dst_rgb[0],
1766                                        newctx->gl_blend_src_alpha[0],
1767                                        newctx->gl_blend_dst_alpha[0]))
1768                 }
1769                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
1770                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
1771                 {
1772                         CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]))
1773                 }
1774
1775         }
1776
1777         //------------------//
1778         // _stencil_flag1
1779         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
1780         if (flag)
1781         {
1782                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
1783                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
1784                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
1785                 {
1786                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
1787                                        newctx->gl_stencil_func[0],
1788                                        newctx->gl_stencil_ref[0],
1789                                        newctx->gl_stencil_value_mask[0]))
1790                 }
1791                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
1792                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
1793                     (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
1794                 {
1795                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
1796                                        newctx->gl_stencil_fail[0],
1797                                        newctx->gl_stencil_pass_depth_fail[0],
1798                                        newctx->gl_stencil_pass_depth_pass[0]))
1799                 }
1800
1801                 STATE_COMPARE(gl_stencil_writemask[0])
1802                 {
1803                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]))
1804                 }
1805         }
1806
1807
1808         // _stencil_flag1
1809         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
1810         if (flag)
1811         {
1812                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
1813                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
1814                     (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
1815                 {
1816                         CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
1817                                        newctx->gl_stencil_back_func[0],
1818                                        newctx->gl_stencil_back_ref[0],
1819                                        newctx->gl_stencil_back_value_mask[0]))
1820                 }
1821                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
1822                     (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
1823                     (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
1824                 {
1825                         CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
1826                                        newctx->gl_stencil_back_fail[0],
1827                                        newctx->gl_stencil_back_pass_depth_fail[0],
1828                                        newctx->gl_stencil_back_pass_depth_pass[0]))
1829                 }
1830
1831                 STATE_COMPARE(gl_stencil_back_writemask[0])
1832                 {
1833                         CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]))
1834                 }
1835                 STATE_COMPARE(gl_stencil_clear_value[0])
1836                 {
1837                         CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
1838                 }
1839         }
1840
1841         //------------------//
1842         // _misc_flag1
1843         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
1844         if (flag)
1845         {
1846                 STATE_COMPARE(gl_front_face[0])
1847                 {
1848                         CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
1849                 }
1850                 STATE_COMPARE(gl_line_width[0])
1851                 {
1852                         CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
1853                 }
1854                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
1855                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0]))
1856                 {
1857                         CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
1858                                        newctx->gl_polygon_offset_units[0]))
1859                 }
1860                 if ((oldctx->gl_sample_coverage_value[0]  != newctx->gl_sample_coverage_value[0]) ||
1861                     (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
1862                 {
1863                         CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(newctx->gl_sample_coverage_value[0],
1864                                        newctx->gl_sample_coverage_invert[0]))
1865                 }
1866                 STATE_COMPARE(gl_fragment_shader_derivative_hint[0])
1867                 {
1868                         CHECK_GL_ERROR(_orig_fastpath_glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, newctx->gl_fragment_shader_derivative_hint[0]))
1869                 }
1870         }
1871
1872         // _misc_flag2
1873         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
1874         if (flag)
1875         {
1876                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
1877                 {
1878                         CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
1879                                                                 newctx->gl_scissor_box[1],
1880                                                                 newctx->gl_scissor_box[2],
1881                                                                 newctx->gl_scissor_box[3]))
1882                 }
1883                 STATE_COMPARE(gl_pack_alignment[0])
1884                 {
1885                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]))
1886                 }
1887                 STATE_COMPARE(gl_unpack_alignment[0])
1888                 {
1889                         CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]))
1890                 }
1891         }
1892
1893         // _misc_flag3
1894         flag = oldctx->_misc_flag3 | newctx->_misc_flag3;
1895         if (flag)
1896         {
1897                 STATE_COMPARE(gl_read_buffer[0])
1898                 {
1899                         CHECK_GL_ERROR(_orig_fastpath_glReadBuffer(newctx->gl_read_buffer[0]))
1900                 }
1901                 STATES_COMPARE(gl_draw_buffers, 16 * sizeof(GLenum))
1902                 {
1903                         CHECK_GL_ERROR(_orig_fastpath_glDrawBuffers(16, newctx->gl_draw_buffers))
1904                 }
1905                 STATE_COMPARE(gl_vertex_array_binding[0])
1906                 {
1907                         CHECK_GL_ERROR(_orig_fastpath_glBindVertexArray(newctx->gl_vertex_array_binding[0]))
1908                 }
1909                 STATE_COMPARE(gl_transform_feedback_binding[0])
1910                 {
1911                         CHECK_GL_ERROR(_orig_fastpath_glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, newctx->gl_transform_feedback_binding[0]))
1912                 }
1913 //              STATE_COMPARE(gl_transform_feedback_state[0])
1914 //              {
1915                         //CHECK_GL_ERROR(_orig_fastpath_glBindVertexArray(newctx->gl_vertex_array_binding[0]))
1916 //              }
1917         }
1918
1919 #ifdef COREGL_USE_MODULE_TRACEPATH
1920         tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
1921 #endif // COREGL_USE_MODULE_TRACEPATH
1922
1923         ret = 1;
1924         goto finish;
1925
1926 finish:
1927
1928 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
1929         if (unlikely(trace_state_flag == 1))
1930                 fastpath_dump_context_states(newctx, 0);
1931 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
1932         return ret;
1933 #undef STATE_COMPARE
1934 #undef STATES_COMPARE
1935 }
1936