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