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