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