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