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