Optimized CTX, STATE tracing (add more if statements)
[platform/core/uifw/coregl.git] / src / coregl_fastpath.c
1 #include "coregl_fastpath.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/time.h>
6
7 GLenum FPGL_Error = GL_NO_ERROR;
8
9 Mutex init_context_mutex = MUTEX_INITIALIZER;
10 GLGlueContext *initial_ctx = NULL;
11
12 static void
13 _get_texture_states(GLenum pname, GLint *params)
14 {
15         GLuint cur_active_tex = 0;
16
17         AST(initial_ctx != NULL);
18
19         _sym_glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&cur_active_tex);
20         int i;
21         for (i = 0; i < initial_ctx->gl_num_tex_units[0]; i++)
22         {
23                 _sym_glActiveTexture(GL_TEXTURE0 + i);
24                 _sym_glGetIntegerv(pname, &(((GLint *)params)[i]));
25         }
26         _sym_glActiveTexture(cur_active_tex);
27 }
28
29 static GLuint
30 _get_stencil_max_mask()
31 {
32         GLuint stencil_bit = 0;
33
34         _sym_glGetIntegerv(GL_STENCIL_BITS, (GLint *)&stencil_bit);
35         return (1 << stencil_bit) - 1;
36 }
37
38 void
39 init_fast_gl()
40 {
41 }
42
43 void
44 free_fast_gl()
45 {
46 }
47
48 static GL_Object **
49 _get_shared_object(GL_Shared_Object_State *sostate, GL_Object_Type type)
50 {
51         switch (type)
52         {
53                 case GL_OBJECT_TYPE_TEXTURE:
54                         return sostate->texture;
55                 case GL_OBJECT_TYPE_BUFFER:
56                         return sostate->buffer;
57                 case GL_OBJECT_TYPE_FRAMEBUFFER:
58                         return sostate->framebuffer;
59                 case GL_OBJECT_TYPE_RENDERBUFFER:
60                         return sostate->renderbuffer;
61                 case GL_OBJECT_TYPE_PROGRAM:
62                         return sostate->program;
63                 default:
64                         return NULL;
65         }
66 }
67
68
69 GLuint
70 sostate_create_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
71 {
72         GL_Object **object = NULL;
73         GLuint ret = _COREGL_INT_INIT_VALUE;
74         int i;
75
76         object = _get_shared_object(sostate, type);
77
78         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
79         {
80                 if (object[i] == NULL)
81                 {
82                         GL_Object *newobj = (GL_Object *)calloc(1, sizeof(GL_Object));
83                         newobj->id = (int)type + i;
84                         newobj->real_id = real_name;
85                         object[i] = newobj;
86                         ret = newobj->id;
87                         goto finish;
88                 }
89         }
90         goto finish;
91
92 finish:
93         return ret;
94 }
95
96 GLuint
97 sostate_remove_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
98 {
99         GL_Object **object = NULL;
100         GLuint ret = _COREGL_INT_INIT_VALUE;
101         int hash = _COREGL_INT_INIT_VALUE;
102
103         object = _get_shared_object(sostate, type);
104
105         hash = glue_name - (int)type;
106         if (hash < 0 ||
107             hash > MAX_GL_OBJECT_SIZE ||
108             object[hash] == NULL ||
109             object[hash]->id != glue_name)
110         {
111                 ret = 0;
112                 goto finish;
113         }
114
115         free(object[hash]);
116         object[hash] = NULL;
117         ret = 1;
118         goto finish;
119
120 finish:
121         return ret;
122 }
123
124 GLuint
125 sostate_get_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint glue_name)
126 {
127         GL_Object **object = NULL;
128         GLuint ret = _COREGL_INT_INIT_VALUE;
129         int hash = _COREGL_INT_INIT_VALUE;
130
131         object = _get_shared_object(sostate, type);
132
133         hash = glue_name - (int)type;
134         if (hash < 0 ||
135             hash > MAX_GL_OBJECT_SIZE ||
136             object[hash] == NULL ||
137             object[hash]->id != glue_name)
138         {
139                 ret = 0;
140                 goto finish;
141         }
142         ret = object[hash]->real_id;
143         goto finish;
144
145 finish:
146         return ret;
147 }
148
149 GLuint
150 sostate_find_object(GL_Shared_Object_State *sostate, GL_Object_Type type, GLuint real_name)
151 {
152         GL_Object **object = NULL;
153         GLuint ret = _COREGL_INT_INIT_VALUE;
154         int i;
155
156         object = _get_shared_object(sostate, type);
157
158         for (i = 1; i < MAX_GL_OBJECT_SIZE; i++)
159         {
160                 if (object[i] != NULL && object[i]->real_id == real_name)
161                 {
162                         ret = object[i]->id;
163                         goto finish;
164                 }
165         }
166         ret = 0;
167         goto finish;
168
169 finish:
170         return ret;
171 }
172
173 void
174 dump_context_states(GLGlueContext *ctx, int force_output)
175 {
176         static struct timeval tv_last = { 0, 0 };
177
178         if (trace_state_flag != 1) return;
179
180         if (!force_output)
181         {
182                 struct timeval tv_now = { 0, 0 };
183                 AST(gettimeofday(&tv_now, NULL) == 0);
184                 if (tv_now.tv_sec - tv_last.tv_sec < _COREGL_TRACE_OUTPUT_INTERVAL_SEC)
185                 {
186                         goto finish;
187                 }
188                 tv_last = tv_now;
189         }
190
191         TRACE("\n");
192         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
193         TRACE("\E[0;32;1m  State info \E[1;37;1m: GlueCTX = %p\E[0m\n", ctx);
194         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
195
196 #define PRINTF_CHAR_GLenum "%10d"
197 #define PRINTF_CHAR_GLboolean "%10d"
198 #define PRINTF_CHAR_GLint "%10d"
199 #define PRINTF_CHAR_GLsizei "%10u"
200 #define PRINTF_CHAR_GLuint "%10u"
201 #define PRINTF_CHAR_GLuintmask "0x%8X"
202
203 #define PRINTF_CHAR_GLclampf "%10.6f"
204 #define PRINTF_CHAR_GLfloat "%10.6f"
205
206 #define PRINTF_CHAR_GLvoidptr "%10p"
207
208 #define PRINTF_CHAR(type) PRINTF_CHAR_##type
209
210 #define INITIAL_CTX initial_ctx
211 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
212    { \
213       TYPE valuedata[SIZE]; \
214       TYPE *value = NULL; \
215       value = valuedata; GET_STMT; value = valuedata; \
216       TRACE("\E[0;37;1m %-30.30s : (\E[0m ", #NAME); \
217       for (int i = 0; i < SIZE; i++) \
218       { \
219          if (i > 0) { \
220             if (i % 4 == 0) \
221                TRACE("\n %-30.30s     ", "");\
222             else \
223                TRACE(", "); \
224          } \
225          TRACE(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
226          TRACE("["PRINTF_CHAR(TYPE)"]", value[i]); \
227       } \
228       TRACE(" \E[0;37;1m)\E[0m\n"); \
229    }
230 # include "coregl_fastpath_state.h"
231 #undef GLUE_STATE
232 #undef INITIAL_CTX
233
234         TRACE("\E[0;40;34m========================================================================================================================\E[0m\n");
235         TRACE("\n");
236
237         TRACE_END();
238
239 finish:
240         return;
241 }
242
243 int
244 init_context_states(GLGlueContext *ctx)
245 {
246         int ret = 0;
247
248         AST(mutex_lock(&init_context_mutex) == 1);
249
250         if (ctx == NULL)
251         {
252                 ERR("Context NULL\n");
253                 ret = 0;
254                 goto finish;
255         }
256
257         AST(ctx->initialized == 0);
258         AST(ctx->sostate != NULL);
259
260         if (initial_ctx == NULL)
261         {
262                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
263                 AST(initial_ctx != NULL);
264
265 //#define FORCE_DEFAULT_VALUE
266 #ifdef FORCE_DEFAULT_VALUE
267 # define INITIAL_CTX initial_ctx
268 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
269       { \
270          int i; \
271          TYPE valuedata[SIZE]; \
272          TYPE *value = NULL; \
273          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
274          value = valuedata; DEFAULT_STMT; value = valuedata; \
275          for (i = 0; i < SIZE; i++) \
276          { \
277             if (*((char *)(&value[i])) == 0xcc) \
278             { \
279                memset(&value[i], 0xaa, sizeof(TYPE)); \
280                value = valuedata; DEFAULT_STMT; value = valuedata; \
281                if (*((char *)(&value[i])) == 0xaa) \
282                { \
283                   ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
284                   break; \
285                } \
286             } \
287             initial_ctx->NAME[i] = value[i]; \
288          } \
289       }
290 #  include "coregl_fastpath_state.h"
291 # undef GLUE_STATE
292 # undef INITIAL_CTX
293 #else
294 # define INITIAL_CTX initial_ctx
295 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
296       if (try_step == 1) \
297       { \
298          value = valuedata; DEFAULT_STMT; value = valuedata; \
299       } \
300       else \
301       { \
302          value = valuedata; FALLBACK_STMT; value = valuedata; \
303       }
304
305 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
306       { \
307          int i; \
308          int try_step = 0;\
309          TYPE valuedata[SIZE]; \
310          TYPE *value = NULL; \
311          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
312          do { \
313             try_step++; \
314             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
315             for (i = 0; i < SIZE; i++) \
316             { \
317                if (*((char *)(&value[i])) == 0xcc) \
318                { \
319                   memset(&value[i], 0xaa, sizeof(TYPE)); \
320                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
321                   if (*((char *)(&value[i])) == 0xaa) \
322                   { \
323                      try_step++; \
324                      if (try_step == 2) \
325                      { \
326                         ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
327                      } \
328                      break; \
329                   } \
330                } \
331                initial_ctx->NAME[i] = value[i]; \
332             } \
333             if (try_step != 2) \
334             { \
335                value = valuedata; DEFAULT_STMT; value = valuedata; \
336                for (i = 0; i < SIZE; i++) \
337                { \
338                   if (initial_ctx->NAME[i] != value[i]) \
339                   { \
340                      ERR("WARNING : GL-state '"#NAME"'[%d] value ["PRINTF_CHAR(TYPE)"] is different from SPEC-DEFAULT ["PRINTF_CHAR(TYPE)"]\n", i, ctx->NAME[i], value[i]); \
341                   } \
342                } \
343             } \
344          } \
345          while (try_step == 2); \
346       }
347 #  include "coregl_fastpath_state.h"
348 # undef SET_GLUE_VALUE
349 # undef GLUE_STATE
350 # undef INITIAL_CTX
351 #endif
352
353                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
354                 {
355                         ERR("\E[0;31;1mWARNING : Number of vertex attrib is too big! (%d-%d)\E[0m\n", MAX_VERTEX_ATTRIBS, initial_ctx->gl_num_vertex_attribs[0]);
356                 }
357                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
358                 {
359                         ERR("\E[0;31;1mWARNING : Number of texture unit is too big! (%d-%d)\E[0m\n", MAX_TEXTURE_UNITS, initial_ctx->gl_num_tex_units[0]);
360                 }
361         }
362
363         {
364                 int i;
365 #define INITIAL_CTX initial_ctx
366 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
367          for (i = 0; i < SIZE; i++) \
368          { \
369             ctx->NAME[i] = initial_ctx->NAME[i]; \
370          }
371 # include "coregl_fastpath_state.h"
372 #undef GLUE_STATE
373 #undef INITIAL_CTX
374         }
375
376         ctx->initialized = 1;
377         ret = 1;
378         goto finish;
379
380 finish:
381         AST(mutex_unlock(&init_context_mutex) == 1);
382
383         return ret;
384 }
385
386 void
387 make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
388 {
389         unsigned char flag = 0;
390         int i = 0;
391
392         if (debug_nofp == 1) goto finish;
393
394         // Return if they're the same
395         if (oldctx == newctx) goto finish;
396
397 #ifdef EVAS_GL_DEBUG
398 #  define STATE_COMPARE(state)
399 #  define STATES_COMPARE(state_ptr, bytes)
400 #else
401 #  define STATE_COMPARE(state) \
402    if ((oldctx->state) != (newctx->state))
403 #  define STATES_COMPARE(state_ptr, bytes) \
404    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
405 #endif
406
407         static void *trace_hint_glfinish = NULL;
408         trace_hint_glfinish = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
409         _sym_glFlush();
410         _COREGL_TRACE_API_END("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
411
412
413         static void *trace_hint_bindbuffers = NULL;
414         trace_hint_bindbuffers = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
415
416         //------------------//
417         // _bind_flag
418         flag = oldctx->_bind_flag | newctx->_bind_flag;
419         if (flag)
420         {
421                 STATE_COMPARE(gl_array_buffer_binding[0])
422                 {
423                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
424                 }
425                 STATE_COMPARE(gl_element_array_buffer_binding[0])
426                 {
427                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
428                 }
429                 STATE_COMPARE(gl_framebuffer_binding[0])
430                 {
431                         _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
432                 }
433                 STATE_COMPARE(gl_renderbuffer_binding[0])
434                 {
435                         _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
436                 }
437         }
438
439         _COREGL_TRACE_API_END("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
440
441
442         //------------------//
443         // Enable States
444         // _enable_flag1
445         static void *trace_hint_enable_states = NULL;
446         trace_hint_enable_states = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
447
448         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
449         if (flag)
450         {
451                 STATE_COMPARE(gl_blend[0])
452                 {
453                         if (newctx->gl_blend[0])
454                                 _sym_glEnable(GL_BLEND);
455                         else
456                                 _sym_glDisable(GL_BLEND);
457                 }
458                 STATE_COMPARE(gl_cull_face[0])
459                 {
460                         if (newctx->gl_cull_face[0])
461                                 _sym_glEnable(GL_CULL_FACE);
462                         else
463                                 _sym_glDisable(GL_CULL_FACE);
464                 }
465                 STATE_COMPARE(gl_depth_test[0])
466                 {
467                         if (newctx->gl_depth_test[0])
468                                 _sym_glEnable(GL_DEPTH_TEST);
469                         else
470                                 _sym_glDisable(GL_DEPTH_TEST);
471                 }
472                 STATE_COMPARE(gl_dither[0])
473                 {
474                         if (newctx->gl_dither[0])
475                                 _sym_glEnable(GL_DITHER);
476                         else
477                                 _sym_glDisable(GL_DITHER);
478                 }
479         }
480
481         // _enable_flag2
482         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
483         if (flag)
484         {
485                 STATE_COMPARE(gl_polygon_offset_fill[0])
486                 {
487                         if (newctx->gl_polygon_offset_fill[0])
488                                 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
489                         else
490                                 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
491                 }
492                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
493                 {
494                         if (newctx->gl_sample_alpha_to_coverage[0])
495                                 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
496                         else
497                                 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
498                 }
499                 STATE_COMPARE(gl_sample_coverage[0])
500                 {
501                         if (newctx->gl_sample_coverage[0])
502                                 _sym_glEnable(GL_SAMPLE_COVERAGE);
503                         else
504                                 _sym_glDisable(GL_SAMPLE_COVERAGE);
505                 }
506                 STATE_COMPARE(gl_scissor_test[0])
507                 {
508                         if (newctx->gl_scissor_test[0])
509                                 _sym_glEnable(GL_SCISSOR_TEST);
510                         else
511                                 _sym_glDisable(GL_SCISSOR_TEST);
512                 }
513                 STATE_COMPARE(gl_stencil_test[0])
514                 {
515                         if (newctx->gl_stencil_test[0])
516                                 _sym_glEnable(GL_STENCIL_TEST);
517                         else
518                                 _sym_glDisable(GL_STENCIL_TEST);
519                 }
520         }
521
522         _COREGL_TRACE_API_END("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
523
524         //------------------//
525         // _clear_flag1
526         static void *trace_hint_clear_viewport = NULL;
527         trace_hint_clear_viewport = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
528
529         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
530         if (flag)
531         {
532                 // Viewport.
533                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
534                 {
535                         _sym_glViewport(newctx->gl_viewport[0],
536                                         newctx->gl_viewport[1],
537                                         newctx->gl_viewport[2],
538                                         newctx->gl_viewport[3]);
539                 }
540
541                 STATE_COMPARE(gl_current_program[0])
542                 {
543                         _sym_glUseProgram(newctx->gl_current_program[0]);
544                 }
545                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
546                 {
547                         _sym_glClearColor(newctx->gl_color_clear_value[0],
548                                           newctx->gl_color_clear_value[1],
549                                           newctx->gl_color_clear_value[2],
550                                           newctx->gl_color_clear_value[3]);
551                 }
552         }
553
554
555         // _clear_flag2
556         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
557         if (flag)
558         {
559                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
560                 {
561                         _sym_glColorMask(newctx->gl_color_writemask[0],
562                                          newctx->gl_color_writemask[1],
563                                          newctx->gl_color_writemask[2],
564                                          newctx->gl_color_writemask[3]);
565                 }
566                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
567                 {
568                         _sym_glDepthRangef(newctx->gl_depth_range[0],
569                                            newctx->gl_depth_range[1]);
570                 }
571                 STATE_COMPARE(gl_depth_clear_value[0])
572                 {
573                         _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
574                 }
575                 STATE_COMPARE(gl_depth_func[0])
576                 {
577                         _sym_glDepthFunc(newctx->gl_depth_func[0]);
578                 }
579                 STATE_COMPARE(gl_depth_writemask[0])
580                 {
581                         _sym_glDepthMask(newctx->gl_depth_writemask[0]);
582                 }
583                 STATE_COMPARE(gl_cull_face_mode[0])
584                 {
585                         _sym_glCullFace(newctx->gl_cull_face_mode[0]);
586                 }
587
588         }
589
590         _COREGL_TRACE_API_END("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
591
592         //------------------//
593         // Texture here...
594         static void *trace_hint_bind_textures = NULL;
595         trace_hint_bind_textures = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
596
597         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
598         if (flag)
599         {
600
601                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
602                 {
603                         STATE_COMPARE(gl_tex_2d_state[i])
604                         {
605                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
606                                 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
607                         }
608
609                         STATE_COMPARE(gl_tex_cube_state[i])
610                         {
611                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
612                                 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
613                         }
614                 }
615
616                 // Restore active texture
617                 _sym_glActiveTexture(newctx->gl_active_texture[0]);
618
619                 STATE_COMPARE(gl_generate_mipmap_hint[0])
620                 {
621                         _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
622                 }
623         }
624         _COREGL_TRACE_API_END("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
625
626         //------------------//
627         static void *trace_hint_etc = NULL;
628         trace_hint_etc = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
629
630         flag = oldctx->_blend_flag | newctx->_blend_flag;
631         if (flag)
632         {
633                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
634                 {
635                         _sym_glBlendColor(newctx->gl_blend_color[0],
636                                           newctx->gl_blend_color[1],
637                                           newctx->gl_blend_color[2],
638                                           newctx->gl_blend_color[3]);
639                 }
640                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
641                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
642                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
643                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
644                 {
645                         _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
646                                                  newctx->gl_blend_dst_rgb[0],
647                                                  newctx->gl_blend_src_alpha[0],
648                                                  newctx->gl_blend_dst_alpha[0]);
649                 }
650                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
651                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
652                 {
653                         _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
654                 }
655
656         }
657
658         //------------------//
659         // _stencil_flag1
660         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
661         if (flag)
662         {
663                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
664                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
665                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
666                 {
667                         _sym_glStencilFuncSeparate(GL_FRONT,
668                                                    newctx->gl_stencil_func[0],
669                                                    newctx->gl_stencil_ref[0],
670                                                    newctx->gl_stencil_value_mask[0]);
671                 }
672                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
673                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
674                     (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
675                 {
676                         _sym_glStencilOpSeparate(GL_FRONT,
677                                                  newctx->gl_stencil_fail[0],
678                                                  newctx->gl_stencil_pass_depth_fail[0],
679                                                  newctx->gl_stencil_pass_depth_pass[0]);
680                 }
681
682                 STATE_COMPARE(gl_stencil_writemask[0])
683                 {
684                         _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
685                 }
686         }
687
688
689         // _stencil_flag1
690         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
691         if (flag)
692         {
693                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
694                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
695                     (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
696                 {
697                         _sym_glStencilFuncSeparate(GL_BACK,
698                                                    newctx->gl_stencil_back_func[0],
699                                                    newctx->gl_stencil_back_ref[0],
700                                                    newctx->gl_stencil_back_value_mask[0]);
701                 }
702                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
703                     (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
704                     (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
705                 {
706                         _sym_glStencilOpSeparate(GL_BACK,
707                                                  newctx->gl_stencil_back_fail[0],
708                                                  newctx->gl_stencil_back_pass_depth_fail[0],
709                                                  newctx->gl_stencil_back_pass_depth_pass[0]);
710                 }
711
712                 STATE_COMPARE(gl_stencil_back_writemask[0])
713                 {
714                         _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
715                 }
716                 STATE_COMPARE(gl_stencil_clear_value[0])
717                 {
718                         _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
719                 }
720         }
721
722         //------------------//
723         // _misc_flag1
724         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
725         if (flag)
726         {
727                 STATE_COMPARE(gl_front_face[0])
728                 {
729                         _sym_glFrontFace(newctx->gl_front_face[0]);
730                 }
731                 STATE_COMPARE(gl_line_width[0])
732                 {
733                         _sym_glLineWidth(newctx->gl_line_width[0]);
734                 }
735                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
736                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0]))
737                 {
738                         _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
739                                              newctx->gl_polygon_offset_units[0]);
740                 }
741                 if ((oldctx->gl_sample_coverage_value[0]  != newctx->gl_sample_coverage_value[0]) ||
742                     (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
743                 {
744                         _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
745                                               newctx->gl_sample_coverage_invert[0]);
746                 }
747         }
748
749         // _misc_flag2
750         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
751         if (flag)
752         {
753                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
754                 {
755                         _sym_glScissor(newctx->gl_scissor_box[0],
756                                        newctx->gl_scissor_box[1],
757                                        newctx->gl_scissor_box[2],
758                                        newctx->gl_scissor_box[3]);
759                 }
760                 STATE_COMPARE(gl_pack_alignment[0])
761                 {
762                         _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
763                 }
764                 STATE_COMPARE(gl_unpack_alignment[0])
765                 {
766                         _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
767                 }
768         }
769         _COREGL_TRACE_API_END("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
770
771         // _varray_flag
772         static void *trace_hint_vertex_attrib = NULL;
773         trace_hint_vertex_attrib = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
774         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
775         if (flag)
776         {
777                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
778                 {
779                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
780                         {
781                                 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
782                         }
783                         else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
784
785                         _sym_glVertexAttribPointer(i,
786                                                    newctx->gl_vertex_array_size[i],
787                                                    newctx->gl_vertex_array_type[i],
788                                                    newctx->gl_vertex_array_normalized[i],
789                                                    newctx->gl_vertex_array_stride[i],
790                                                    newctx->gl_vertex_array_pointer[i]);
791
792                         STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
793                         {
794                                 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
795                         }
796
797                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
798                         {
799                                 _sym_glEnableVertexAttribArray(i);
800                         }
801                         else
802                         {
803                                 _sym_glDisableVertexAttribArray(i);
804                         }
805                 }
806
807                 STATE_COMPARE(gl_array_buffer_binding[0])
808                 {
809                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
810                 }
811                 STATE_COMPARE(gl_element_array_buffer_binding[0])
812                 {
813                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
814                 }
815
816         }
817
818         _COREGL_TRACE_API_END("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
819         goto finish;
820
821 finish:
822
823 #ifdef COREGL_TRACE_STATE_INFO
824         if (trace_state_flag == 1)
825                 dump_context_states(newctx, 0);
826 #endif // COREGL_TRACE_STATE_INFO
827         return;
828 #undef STATE_COMPARE
829 #undef STATES_COMPARE
830 }
831