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