37a08ed9ae8f9b50076c92d32d53c7e41a757be2
[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         LOG("\n");
192         LOG("\E[0;40;34m========================================================================================================================\E[0m\n");
193         LOG("\E[0;32;1m  State info \E[1;37;1m: GlueCTX = %p\E[0m\n", ctx);
194         LOG("\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       LOG("\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                LOG("\n %-30.30s     ", "");\
222             else \
223                LOG(", "); \
224          } \
225          LOG(PRINTF_CHAR(TYPE), ctx->NAME[i]); \
226          LOG("["PRINTF_CHAR(TYPE)"]", value[i]); \
227       } \
228       LOG(" \E[0;37;1m)\E[0m\n"); \
229    }
230 # include "coregl_fastpath_state.h"
231 #undef GLUE_STATE
232 #undef INITIAL_CTX
233
234         LOG("\E[0;40;34m========================================================================================================================\E[0m\n");
235         LOG("\n");
236
237 finish:
238         return;
239 }
240
241 int
242 init_context_states(GLGlueContext *ctx)
243 {
244         int ret = 0;
245
246         AST(mutex_lock(&init_context_mutex) == 1);
247
248         if (ctx == NULL)
249         {
250                 ERR("Context NULL\n");
251                 ret = 0;
252                 goto finish;
253         }
254
255         AST(ctx->initialized == 0);
256         AST(ctx->sostate != NULL);
257
258         if (initial_ctx == NULL)
259         {
260                 initial_ctx = (GLGlueContext *)calloc(1, sizeof(GLGlueContext));
261                 AST(initial_ctx != NULL);
262
263 //#define FORCE_DEFAULT_VALUE
264 #ifdef FORCE_DEFAULT_VALUE
265 # define INITIAL_CTX initial_ctx
266 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
267       { \
268          int i; \
269          TYPE valuedata[SIZE]; \
270          TYPE *value = NULL; \
271          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
272          value = valuedata; DEFAULT_STMT; value = valuedata; \
273          for (i = 0; i < SIZE; i++) \
274          { \
275             if (*((char *)(&value[i])) == 0xcc) \
276             { \
277                memset(&value[i], 0xaa, sizeof(TYPE)); \
278                value = valuedata; DEFAULT_STMT; value = valuedata; \
279                if (*((char *)(&value[i])) == 0xaa) \
280                { \
281                   ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
282                   break; \
283                } \
284             } \
285             initial_ctx->NAME[i] = value[i]; \
286          } \
287       }
288 #  include "coregl_fastpath_state.h"
289 # undef GLUE_STATE
290 # undef INITIAL_CTX
291 #else
292 # define INITIAL_CTX initial_ctx
293 # define SET_GLUE_VALUE(DEFAULT_STMT, FALLBACK_STMT) \
294       if (try_step == 1) \
295       { \
296          value = valuedata; DEFAULT_STMT; value = valuedata; \
297       } \
298       else \
299       { \
300          value = valuedata; FALLBACK_STMT; value = valuedata; \
301       }
302
303 # define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
304       { \
305          int i; \
306          int try_step = 0;\
307          TYPE valuedata[SIZE]; \
308          TYPE *value = NULL; \
309          memset(valuedata, 0xcc, sizeof(TYPE) * SIZE); \
310          do { \
311             try_step++; \
312             SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
313             for (i = 0; i < SIZE; i++) \
314             { \
315                if (*((char *)(&value[i])) == 0xcc) \
316                { \
317                   memset(&value[i], 0xaa, sizeof(TYPE)); \
318                   SET_GLUE_VALUE(GET_STMT, DEFAULT_STMT); \
319                   if (*((char *)(&value[i])) == 0xaa) \
320                   { \
321                      try_step++; \
322                      if (try_step == 2) \
323                      { \
324                         ERR("\E[0;31;1mWARNING : GL-state '"#NAME"' cannot be retrieved\E[0m\n"); \
325                      } \
326                      break; \
327                   } \
328                } \
329                initial_ctx->NAME[i] = value[i]; \
330             } \
331             if (try_step != 2) \
332             { \
333                value = valuedata; DEFAULT_STMT; value = valuedata; \
334                for (i = 0; i < SIZE; i++) \
335                { \
336                   if (initial_ctx->NAME[i] != value[i]) \
337                   { \
338                      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]); \
339                   } \
340                } \
341             } \
342          } \
343          while (try_step == 2); \
344       }
345 #  include "coregl_fastpath_state.h"
346 # undef SET_GLUE_VALUE
347 # undef GLUE_STATE
348 # undef INITIAL_CTX
349 #endif
350
351                 if (initial_ctx->gl_num_vertex_attribs[0] > MAX_VERTEX_ATTRIBS)
352                 {
353                         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]);
354                 }
355                 if (initial_ctx->gl_num_tex_units[0] > MAX_TEXTURE_UNITS)
356                 {
357                         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]);
358                 }
359         }
360
361         {
362                 int i;
363 #define INITIAL_CTX initial_ctx
364 #define GLUE_STATE(TYPE, NAME, SIZE, ARRAY_SIZE, DEFAULT_STMT, GET_STMT)  \
365          for (i = 0; i < SIZE; i++) \
366          { \
367             ctx->NAME[i] = initial_ctx->NAME[i]; \
368          }
369 # include "coregl_fastpath_state.h"
370 #undef GLUE_STATE
371 #undef INITIAL_CTX
372         }
373
374         ctx->initialized = 1;
375         ret = 1;
376         goto finish;
377
378 finish:
379         AST(mutex_unlock(&init_context_mutex) == 1);
380
381         return ret;
382 }
383
384 void
385 make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
386 {
387         unsigned char flag = 0;
388         int i = 0;
389
390         if (debug_nofp == 1) goto finish;
391
392         // Return if they're the same
393         if (oldctx == newctx) goto finish;
394
395 #ifdef EVAS_GL_DEBUG
396 #  define STATE_COMPARE(state)
397 #  define STATES_COMPARE(state_ptr, bytes)
398 #else
399 #  define STATE_COMPARE(state) \
400    if ((oldctx->state) != (newctx->state))
401 #  define STATES_COMPARE(state_ptr, bytes) \
402    if ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
403 #endif
404
405         static void *trace_hint_glfinish = NULL;
406         trace_hint_glfinish = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
407         _sym_glFlush();
408         _COREGL_TRACE_API_END("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
409
410
411         static void *trace_hint_bindbuffers = NULL;
412         trace_hint_bindbuffers = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
413
414         //------------------//
415         // _bind_flag
416         flag = oldctx->_bind_flag | newctx->_bind_flag;
417         if (flag)
418         {
419                 STATE_COMPARE(gl_array_buffer_binding[0])
420                 {
421                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
422                 }
423                 STATE_COMPARE(gl_element_array_buffer_binding[0])
424                 {
425                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
426                 }
427                 STATE_COMPARE(gl_framebuffer_binding[0])
428                 {
429                         _sym_glBindFramebuffer(GL_FRAMEBUFFER, newctx->gl_framebuffer_binding[0]);
430                 }
431                 STATE_COMPARE(gl_renderbuffer_binding[0])
432                 {
433                         _sym_glBindRenderbuffer(GL_RENDERBUFFER, newctx->gl_renderbuffer_binding[0]);
434                 }
435         }
436
437         _COREGL_TRACE_API_END("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
438
439
440         //------------------//
441         // Enable States
442         // _enable_flag1
443         static void *trace_hint_enable_states = NULL;
444         trace_hint_enable_states = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
445
446         flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
447         if (flag)
448         {
449                 STATE_COMPARE(gl_blend[0])
450                 {
451                         if (newctx->gl_blend[0])
452                                 _sym_glEnable(GL_BLEND);
453                         else
454                                 _sym_glDisable(GL_BLEND);
455                 }
456                 STATE_COMPARE(gl_cull_face[0])
457                 {
458                         if (newctx->gl_cull_face[0])
459                                 _sym_glEnable(GL_CULL_FACE);
460                         else
461                                 _sym_glDisable(GL_CULL_FACE);
462                 }
463                 STATE_COMPARE(gl_depth_test[0])
464                 {
465                         if (newctx->gl_depth_test[0])
466                                 _sym_glEnable(GL_DEPTH_TEST);
467                         else
468                                 _sym_glDisable(GL_DEPTH_TEST);
469                 }
470                 STATE_COMPARE(gl_dither[0])
471                 {
472                         if (newctx->gl_dither[0])
473                                 _sym_glEnable(GL_DITHER);
474                         else
475                                 _sym_glDisable(GL_DITHER);
476                 }
477         }
478
479         // _enable_flag2
480         flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
481         if (flag)
482         {
483                 STATE_COMPARE(gl_polygon_offset_fill[0])
484                 {
485                         if (newctx->gl_polygon_offset_fill[0])
486                                 _sym_glEnable(GL_POLYGON_OFFSET_FILL);
487                         else
488                                 _sym_glDisable(GL_POLYGON_OFFSET_FILL);
489                 }
490                 STATE_COMPARE(gl_sample_alpha_to_coverage[0])
491                 {
492                         if (newctx->gl_sample_alpha_to_coverage[0])
493                                 _sym_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
494                         else
495                                 _sym_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
496                 }
497                 STATE_COMPARE(gl_sample_coverage[0])
498                 {
499                         if (newctx->gl_sample_coverage[0])
500                                 _sym_glEnable(GL_SAMPLE_COVERAGE);
501                         else
502                                 _sym_glDisable(GL_SAMPLE_COVERAGE);
503                 }
504                 STATE_COMPARE(gl_scissor_test[0])
505                 {
506                         if (newctx->gl_scissor_test[0])
507                                 _sym_glEnable(GL_SCISSOR_TEST);
508                         else
509                                 _sym_glDisable(GL_SCISSOR_TEST);
510                 }
511                 STATE_COMPARE(gl_stencil_test[0])
512                 {
513                         if (newctx->gl_stencil_test[0])
514                                 _sym_glEnable(GL_STENCIL_TEST);
515                         else
516                                 _sym_glDisable(GL_STENCIL_TEST);
517                 }
518         }
519
520         _COREGL_TRACE_API_END("eglMakeCurrent(FP enable states)", trace_hint_enable_states, 0);
521
522         //------------------//
523         // _clear_flag1
524         static void *trace_hint_clear_viewport = NULL;
525         trace_hint_clear_viewport = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
526
527         flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
528         if (flag)
529         {
530                 // Viewport.
531                 STATES_COMPARE(gl_viewport, 4 * sizeof(GLint))
532                 {
533                         _sym_glViewport(newctx->gl_viewport[0],
534                                         newctx->gl_viewport[1],
535                                         newctx->gl_viewport[2],
536                                         newctx->gl_viewport[3]);
537                 }
538
539                 STATE_COMPARE(gl_current_program[0])
540                 {
541                         _sym_glUseProgram(newctx->gl_current_program[0]);
542                 }
543                 STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf))
544                 {
545                         _sym_glClearColor(newctx->gl_color_clear_value[0],
546                                           newctx->gl_color_clear_value[1],
547                                           newctx->gl_color_clear_value[2],
548                                           newctx->gl_color_clear_value[3]);
549                 }
550         }
551
552
553         // _clear_flag2
554         flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
555         if (flag)
556         {
557                 STATES_COMPARE(gl_color_writemask, 4 * sizeof(GLboolean))
558                 {
559                         _sym_glColorMask(newctx->gl_color_writemask[0],
560                                          newctx->gl_color_writemask[1],
561                                          newctx->gl_color_writemask[2],
562                                          newctx->gl_color_writemask[3]);
563                 }
564                 STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf))
565                 {
566                         _sym_glDepthRangef(newctx->gl_depth_range[0],
567                                            newctx->gl_depth_range[1]);
568                 }
569                 STATE_COMPARE(gl_depth_clear_value[0])
570                 {
571                         _sym_glClearDepthf(newctx->gl_depth_clear_value[0]);
572                 }
573                 STATE_COMPARE(gl_depth_func[0])
574                 {
575                         _sym_glDepthFunc(newctx->gl_depth_func[0]);
576                 }
577                 STATE_COMPARE(gl_depth_writemask[0])
578                 {
579                         _sym_glDepthMask(newctx->gl_depth_writemask[0]);
580                 }
581                 STATE_COMPARE(gl_cull_face_mode[0])
582                 {
583                         _sym_glCullFace(newctx->gl_cull_face_mode[0]);
584                 }
585
586         }
587
588         _COREGL_TRACE_API_END("eglMakeCurrent(FP clear/viewport)", trace_hint_clear_viewport, 0);
589
590         //------------------//
591         // Texture here...
592         static void *trace_hint_bind_textures = NULL;
593         trace_hint_bind_textures = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
594
595         flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
596         if (flag)
597         {
598
599                 for (i = 0; i < oldctx->gl_num_tex_units[0]; i++)
600                 {
601                         STATE_COMPARE(gl_tex_2d_state[i])
602                         {
603                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
604                                 _sym_glBindTexture(GL_TEXTURE_2D, newctx->gl_tex_2d_state[i]);
605                         }
606
607                         STATE_COMPARE(gl_tex_cube_state[i])
608                         {
609                                 _sym_glActiveTexture(GL_TEXTURE0 + i);
610                                 _sym_glBindTexture(GL_TEXTURE_CUBE_MAP, newctx->gl_tex_cube_state[i]);
611                         }
612                 }
613
614                 // Restore active texture
615                 _sym_glActiveTexture(newctx->gl_active_texture[0]);
616
617                 STATE_COMPARE(gl_generate_mipmap_hint[0])
618                 {
619                         _sym_glHint(GL_GENERATE_MIPMAP_HINT, newctx->gl_generate_mipmap_hint[0]);
620                 }
621         }
622         _COREGL_TRACE_API_END("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
623
624         //------------------//
625         static void *trace_hint_etc = NULL;
626         trace_hint_etc = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
627
628         flag = oldctx->_blend_flag | newctx->_blend_flag;
629         if (flag)
630         {
631                 STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf))
632                 {
633                         _sym_glBlendColor(newctx->gl_blend_color[0],
634                                           newctx->gl_blend_color[1],
635                                           newctx->gl_blend_color[2],
636                                           newctx->gl_blend_color[3]);
637                 }
638                 if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
639                     (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
640                     (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
641                     (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0]))
642                 {
643                         _sym_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
644                                                  newctx->gl_blend_dst_rgb[0],
645                                                  newctx->gl_blend_src_alpha[0],
646                                                  newctx->gl_blend_dst_alpha[0]);
647                 }
648                 if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
649                     (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0]))
650                 {
651                         _sym_glBlendEquationSeparate(newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]);
652                 }
653
654         }
655
656         //------------------//
657         // _stencil_flag1
658         flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
659         if (flag)
660         {
661                 if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
662                     (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
663                     (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0]))
664                 {
665                         _sym_glStencilFuncSeparate(GL_FRONT,
666                                                    newctx->gl_stencil_func[0],
667                                                    newctx->gl_stencil_ref[0],
668                                                    newctx->gl_stencil_value_mask[0]);
669                 }
670                 if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
671                     (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
672                     (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0]))
673                 {
674                         _sym_glStencilOpSeparate(GL_FRONT,
675                                                  newctx->gl_stencil_fail[0],
676                                                  newctx->gl_stencil_pass_depth_fail[0],
677                                                  newctx->gl_stencil_pass_depth_pass[0]);
678                 }
679
680                 STATE_COMPARE(gl_stencil_writemask[0])
681                 {
682                         _sym_glStencilMaskSeparate(GL_FRONT, newctx->gl_stencil_writemask[0]);
683                 }
684         }
685
686
687         // _stencil_flag1
688         flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
689         if (flag)
690         {
691                 if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
692                     (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
693                     (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0]))
694                 {
695                         _sym_glStencilFuncSeparate(GL_BACK,
696                                                    newctx->gl_stencil_back_func[0],
697                                                    newctx->gl_stencil_back_ref[0],
698                                                    newctx->gl_stencil_back_value_mask[0]);
699                 }
700                 if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
701                     (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
702                     (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0]))
703                 {
704                         _sym_glStencilOpSeparate(GL_BACK,
705                                                  newctx->gl_stencil_back_fail[0],
706                                                  newctx->gl_stencil_back_pass_depth_fail[0],
707                                                  newctx->gl_stencil_back_pass_depth_pass[0]);
708                 }
709
710                 STATE_COMPARE(gl_stencil_back_writemask[0])
711                 {
712                         _sym_glStencilMaskSeparate(GL_BACK, newctx->gl_stencil_back_writemask[0]);
713                 }
714                 STATE_COMPARE(gl_stencil_clear_value[0])
715                 {
716                         _sym_glClearStencil(newctx->gl_stencil_clear_value[0]);
717                 }
718         }
719
720         //------------------//
721         // _misc_flag1
722         flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
723         if (flag)
724         {
725                 STATE_COMPARE(gl_front_face[0])
726                 {
727                         _sym_glFrontFace(newctx->gl_front_face[0]);
728                 }
729                 STATE_COMPARE(gl_line_width[0])
730                 {
731                         _sym_glLineWidth(newctx->gl_line_width[0]);
732                 }
733                 if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
734                     (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0]))
735                 {
736                         _sym_glPolygonOffset(newctx->gl_polygon_offset_factor[0],
737                                              newctx->gl_polygon_offset_units[0]);
738                 }
739                 if ((oldctx->gl_sample_coverage_value[0]  != newctx->gl_sample_coverage_value[0]) ||
740                     (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0]))
741                 {
742                         _sym_glSampleCoverage(newctx->gl_sample_coverage_value[0],
743                                               newctx->gl_sample_coverage_invert[0]);
744                 }
745         }
746
747         // _misc_flag2
748         flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
749         if (flag)
750         {
751                 STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint))
752                 {
753                         _sym_glScissor(newctx->gl_scissor_box[0],
754                                        newctx->gl_scissor_box[1],
755                                        newctx->gl_scissor_box[2],
756                                        newctx->gl_scissor_box[3]);
757                 }
758                 STATE_COMPARE(gl_pack_alignment[0])
759                 {
760                         _sym_glPixelStorei(GL_PACK_ALIGNMENT, newctx->gl_pack_alignment[0]);
761                 }
762                 STATE_COMPARE(gl_unpack_alignment[0])
763                 {
764                         _sym_glPixelStorei(GL_UNPACK_ALIGNMENT, newctx->gl_unpack_alignment[0]);
765                 }
766         }
767         _COREGL_TRACE_API_END("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
768
769         // _varray_flag
770         static void *trace_hint_vertex_attrib = NULL;
771         trace_hint_vertex_attrib = _COREGL_TRACE_API_BEGIN("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
772         flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
773         if (flag)
774         {
775                 for (i = 0; i < oldctx->gl_num_vertex_attribs[0]; i++)
776                 {
777                         if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i])
778                         {
779                                 _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_vertex_array_buf_id[i]);
780                         }
781                         else _sym_glBindBuffer(GL_ARRAY_BUFFER, 0);
782
783                         _sym_glVertexAttribPointer(i,
784                                                    newctx->gl_vertex_array_size[i],
785                                                    newctx->gl_vertex_array_type[i],
786                                                    newctx->gl_vertex_array_normalized[i],
787                                                    newctx->gl_vertex_array_stride[i],
788                                                    newctx->gl_vertex_array_pointer[i]);
789
790                         STATES_COMPARE(gl_vertex_attrib_value + 4 * i, 4 * sizeof(GLfloat))
791                         {
792                                 _sym_glVertexAttrib4fv(i, &newctx->gl_vertex_attrib_value[4 * i]);
793                         }
794
795                         if (newctx->gl_vertex_array_enabled[i] == GL_TRUE)
796                         {
797                                 _sym_glEnableVertexAttribArray(i);
798                         }
799                         else
800                         {
801                                 _sym_glDisableVertexAttribArray(i);
802                         }
803                 }
804
805                 STATE_COMPARE(gl_array_buffer_binding[0])
806                 {
807                         _sym_glBindBuffer(GL_ARRAY_BUFFER, newctx->gl_array_buffer_binding[0]);
808                 }
809                 STATE_COMPARE(gl_element_array_buffer_binding[0])
810                 {
811                         _sym_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, newctx->gl_element_array_buffer_binding[0]);
812                 }
813
814         }
815
816         _COREGL_TRACE_API_END("eglMakeCurrent(FP vertex attrib)", trace_hint_vertex_attrib, 0);
817         goto finish;
818
819 finish:
820
821 #ifdef COREGL_TRACE_STATE_INFO
822         dump_context_states(newctx, 0);
823 #endif // COREGL_TRACE_STATE_INFO
824         return;
825 #undef STATE_COMPARE
826 #undef STATES_COMPARE
827 }
828