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