coregl_fastpath: Refactor function fastpath_make_context_current
authorZhaowei Yuan <zhaowei.yuan@samsung.com>
Thu, 24 Oct 2019 00:33:48 +0000 (08:33 +0800)
committerJoonbum Ko <joonbum.ko@samsung.com>
Tue, 4 Feb 2020 06:43:52 +0000 (15:43 +0900)
Function fastpath_make_context_current() is too long and too
complex, simplify it by following modifications:
1. split it to several functions
2. improve its coding style according to Tizen standard
3. remove unnecessary comments

Change-Id: I26f780b9cd2f9dfb9df6e0de313125e195692eaf
Signed-off-by: Zhaowei Yuan <zhaowei.yuan@samsung.com>
src/modules/fastpath/coregl_fastpath.c

index a5860ac..1007dd9 100644 (file)
@@ -1695,813 +1695,1044 @@ finish:
 }
 
 #ifdef COREGL_USE_MODULE_TRACEPATH
-extern void *tracepath_api_trace_begin(const char *name, void *hint,
-                                                                          int trace_total_time);
-extern void *tracepath_api_trace_end(const char *name, void *hint,
-                                                                        int trace_total_time);
+extern void *tracepath_api_trace_begin(const char *name, void *hint, int trace_total_time);
+extern void *tracepath_api_trace_end(const char *name, void *hint, int trace_total_time);
 #endif
 
 #define CHECK_GL_ERROR(func) \
-       { \
+       do { \
                func; \
                int err = _orig_fastpath_glGetError(); \
-               if (err != GL_NO_ERROR) \
-               { \
+               if (err != GL_NO_ERROR) { \
                        COREGL_ERR("(GL %p) : %s returns GL error 0x%X", oldctx->cstate, #func, err); \
-                       goto finish; \
+                       return 0; \
                } \
-       }
+       } while(0);
 
-int
-fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
+#define STATE_COMPARE(state) (oldctx->state != newctx->state)
+#define STATES_COMPARE(state_ptr, bytes) (memcmp(oldctx->state_ptr, newctx->state_ptr, bytes) != 0)
+
+GLuint
+fastpath_check_context_vertex_attribs(GLGlueContext *oldctx, GLGlueContext *newctx)
 {
-       int ret = 0;
-       unsigned char flag = 0;
-       int i = 0;
+       int i;
 
-       if (debug_nofp == 1) {
-               ret = 1;
-               goto finish;
+       if(!(oldctx->_vattrib_flag | newctx->_vattrib_flag)) {
+               return 1;
        }
 
-       // Return if they're the same
-       if (oldctx == newctx) {
-               ret = 1;
-               goto finish;
-       }
+       for (i = 0; i < oldctx->gl_vertex_attribs_num[0]; i++) {
+               if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
+                                                  newctx->gl_vertex_array_buf_id[i]))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
+               }
 
-#define STATE_COMPARE(state) \
-   ((oldctx->state) != (newctx->state))
+               if STATE_COMPARE(gl_vertex_array_divisor[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glVertexAttribDivisor(i,
+                                                  newctx->gl_vertex_array_divisor[i]))
+               }
 
-#define STATES_COMPARE(state_ptr, bytes) \
-   ((memcmp((oldctx->state_ptr), (newctx->state_ptr), (bytes))) != 0)
+               if (newctx->gl_vertex_array_size[i] != 0) {
+                       CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
+                                                  newctx->gl_vertex_array_size[i],
+                                                  newctx->gl_vertex_array_type[i],
+                                                  newctx->gl_vertex_array_normalized[i],
+                                                  newctx->gl_vertex_array_stride[i],
+                                                  newctx->gl_vertex_array_pointer[i]))
+               } else {
+                       if (newctx->gl_vertex_array_integer[0] == GL_TRUE) {
+                               if (newctx->gl_vertex_array_type[0] == GL_UNSIGNED_INT) {
+                                       CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4uiv(i,
+                                                                  &newctx->gl_vertex_attrib_value_unsigned_integer[4 * i]))
+                               } else {
+                                       CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4iv(i,
+                                                                  &newctx->gl_vertex_attrib_value_integer[4 * i]))
+                               }
+                       } else {
+                               CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i,
+                                                          &newctx->gl_vertex_attrib_value[4 * i]))
+                       }
+               }
 
+               if (newctx->gl_vertex_array_enabled[i] == GL_TRUE) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
+               }
+       }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_glfinish = NULL;
-       trace_hint_glfinish = tracepath_api_trace_begin("eglMakeCurrent(FP glFinish)",
-                                                 trace_hint_glfinish, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       return 1;
+}
 
-       {
-               int err = _orig_fastpath_glGetError();
-               if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR)
-                       oldctx->gl_error = err;
+GLuint
+fastpath_check_context_bind_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_bind_flag1 | newctx->_bind_flag1)) {
+               return 1;
        }
 
-       CHECK_GL_ERROR(_orig_fastpath_glFlush())
+       if STATE_COMPARE(gl_array_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
+                                          newctx->gl_array_buffer_binding[0]))
+       }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       if STATE_COMPARE(gl_element_array_buffer_binding[0]) {
+               if STATE_COMPARE(gl_vertex_array_binding[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindVertexArray(
+                                                  newctx->gl_vertex_array_binding[0]))
+               }
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
+                                          newctx->gl_element_array_buffer_binding[0]))
+       }
 
-       // _varray_flag
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_vertex_attrib = NULL;
-       trace_hint_vertex_attrib =
-               tracepath_api_trace_begin("eglMakeCurrent(FP vertex attrib)",
-                                                                 trace_hint_vertex_attrib, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       flag = oldctx->_vattrib_flag | newctx->_vattrib_flag;
-       if (flag) {
-               for (i = 0; i < oldctx->gl_vertex_attribs_num[0]; i++) {
-                       if (newctx->gl_vertex_array_buf_id[i] != oldctx->gl_vertex_array_buf_id[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
-                                                          newctx->gl_vertex_array_buf_id[i]))
+       if (newctx->gl_framebuffer_binding_read_used == 1 &&
+                       newctx->gl_framebuffer_binding_draw_used == 1) {
+               if STATE_COMPARE(gl_framebuffer_binding_read[0]) {
+                       if (driver_gl_version >= 2) {
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_READ_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding_read[0]))
                        } else {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER, 0))
-                       }
-
-                       if STATE_COMPARE(gl_vertex_array_divisor[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glVertexAttribDivisor(i,
-                                                          newctx->gl_vertex_array_divisor[i]))
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_READ_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding_read[0]))
                        }
+               }
 
-                       if (newctx->gl_vertex_array_size[i] != 0) {
-                               CHECK_GL_ERROR(_orig_fastpath_glVertexAttribPointer(i,
-                                                          newctx->gl_vertex_array_size[i],
-                                                          newctx->gl_vertex_array_type[i],
-                                                          newctx->gl_vertex_array_normalized[i],
-                                                          newctx->gl_vertex_array_stride[i],
-                                                          newctx->gl_vertex_array_pointer[i]))
+               if STATE_COMPARE(gl_framebuffer_binding_draw[0]) {
+                       if (driver_gl_version >= 2) {
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding_draw[0]))
                        } else {
-                               if (newctx->gl_vertex_array_integer[0] == GL_TRUE) {
-                                       if (newctx->gl_vertex_array_type[0] == GL_UNSIGNED_INT) {
-                                               CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4uiv(i,
-                                                                          &newctx->gl_vertex_attrib_value_unsigned_integer[4 * i]))
-                                       } else {
-                                               CHECK_GL_ERROR(_orig_fastpath_glVertexAttribI4iv(i,
-                                                                          &newctx->gl_vertex_attrib_value_integer[4 * i]))
-                                       }
-                               } else {
-                                       CHECK_GL_ERROR(_orig_fastpath_glVertexAttrib4fv(i,
-                                                                  &newctx->gl_vertex_attrib_value[4 * i]))
-                               }
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_DRAW_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding_draw[0]))
                        }
-
-                       if (newctx->gl_vertex_array_enabled[i] == GL_TRUE) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnableVertexAttribArray(i))
+               }
+       } else {
+               if STATE_COMPARE(gl_framebuffer_binding[0]) {
+                       if (driver_gl_version >= 2) {
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding[0]))
                        } else {
-                               CHECK_GL_ERROR(_orig_fastpath_glDisableVertexAttribArray(i))
+                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_FRAMEBUFFER,
+                                                          newctx->gl_framebuffer_binding[0]))
                        }
                }
+       }
 
+       if STATE_COMPARE(gl_renderbuffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER,
+                                          newctx->gl_renderbuffer_binding[0]))
        }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP vertex attrib)",
-                                                       trace_hint_vertex_attrib, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       return 1;
+}
 
+GLuint
+fastpath_check_context_bind_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_bindbuffers = NULL;
-       trace_hint_bindbuffers =
-               tracepath_api_trace_begin("eglMakeCurrent(FP bind buffers)",
-                                                                 trace_hint_bindbuffers, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       //------------------//
-       // _bind_flag1
-       flag = oldctx->_bind_flag1 | newctx->_bind_flag1;
-       if (flag) {
-               if STATE_COMPARE(gl_array_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ARRAY_BUFFER,
-                                                  newctx->gl_array_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_element_array_buffer_binding[0]) {
-                       if STATE_COMPARE(gl_vertex_array_binding[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindVertexArray(
-                                                                  newctx->gl_vertex_array_binding[0]))
-                       }
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
-                                                  newctx->gl_element_array_buffer_binding[0]))
-               }
-
-               if (newctx->gl_framebuffer_binding_read_used == 1 &&
-                               newctx->gl_framebuffer_binding_draw_used == 1) {
-                       if STATE_COMPARE(gl_framebuffer_binding_read[0]) {
-                               if (driver_gl_version >= 2)
-                                       CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_READ_FRAMEBUFFER,
-                                                                  newctx->gl_framebuffer_binding_read[0]))
-                                       else
-                                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_READ_FRAMEBUFFER,
-                                                                          newctx->gl_framebuffer_binding_read[0]))
-                                       }
-                       if STATE_COMPARE(gl_framebuffer_binding_draw[0]) {
-                               if (driver_gl_version >= 2)
-                                       CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
-                                                                  newctx->gl_framebuffer_binding_draw[0]))
-                                       else
-                                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_DRAW_FRAMEBUFFER,
-                                                                          newctx->gl_framebuffer_binding_draw[0]))
-                                       }
-               } else {
-                       if STATE_COMPARE(gl_framebuffer_binding[0]) {
-                               if (driver_gl_version >= 2)
-                                       CHECK_GL_ERROR(_orig_fastpath_glBindFramebuffer(GL_FRAMEBUFFER,
-                                                                  newctx->gl_framebuffer_binding[0]))
-                                       else
-                                               CHECK_GL_ERROR(_orig_fastpath_glBindFramebufferOES(GL_FRAMEBUFFER,
-                                                                          newctx->gl_framebuffer_binding[0]))
-                                       }
-               }
-               if STATE_COMPARE(gl_renderbuffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindRenderbuffer(GL_RENDERBUFFER,
-                                                  newctx->gl_renderbuffer_binding[0]))
-               }
-       }
-
-       //------------------//
-       // _bind_flag2
-       flag = oldctx->_bind_flag2 | newctx->_bind_flag2;
-       if (flag) {
-               if STATE_COMPARE(gl_copy_read_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_READ_BUFFER,
-                                                  newctx->gl_copy_read_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_copy_write_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_WRITE_BUFFER,
-                                                  newctx->gl_copy_write_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_pixel_pack_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_PACK_BUFFER,
-                                                  newctx->gl_pixel_pack_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_pixel_unpack_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
-                                                  newctx->gl_pixel_unpack_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_transform_feedback_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
-                                                  newctx->gl_transform_feedback_buffer_binding[0]))
-               }
-               if STATE_COMPARE(gl_uniform_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_UNIFORM_BUFFER,
-                                                  newctx->gl_uniform_buffer_binding[0]))
-               }
-               /* handle states set in fastpath_glBindBufferBase() */
-               for (i = 0; i < newctx->gl_transform_feedback_buffer_binding_num[0]; i++) {
-                       if STATE_COMPARE(gl_transform_feedback_buffer_binding_array[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i,
-                                                          newctx->gl_transform_feedback_buffer_binding_array[i]))
-                       }
-               }
-               for (i = 0; i < newctx->gl_uniform_buffer_binding_num[0]; i++) {
-                       if STATE_COMPARE(gl_uniform_buffer_binding_array[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_UNIFORM_BUFFER, i,
-                                                          newctx->gl_uniform_buffer_binding_array[i]))
-                       }
+       if(!(oldctx->_bind_flag2 | newctx->_bind_flag2)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_copy_read_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_READ_BUFFER,
+                                          newctx->gl_copy_read_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_copy_write_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_COPY_WRITE_BUFFER,
+                                          newctx->gl_copy_write_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_pixel_pack_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_PACK_BUFFER,
+                                          newctx->gl_pixel_pack_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_pixel_unpack_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
+                                          newctx->gl_pixel_unpack_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_transform_feedback_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
+                                          newctx->gl_transform_feedback_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_uniform_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_UNIFORM_BUFFER,
+                                          newctx->gl_uniform_buffer_binding[0]))
+       }
+       /* handle states set in fastpath_glBindBufferBase() */
+       for (i = 0; i < newctx->gl_transform_feedback_buffer_binding_num[0]; i++) {
+               if STATE_COMPARE(gl_transform_feedback_buffer_binding_array[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i,
+                                                  newctx->gl_transform_feedback_buffer_binding_array[i]))
                }
        }
 
-       flag = oldctx->_bind_flag3 | newctx->_bind_flag3;
-       if (flag) {
-               if STATE_COMPARE(gl_shader_storage_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_SHADER_STORAGE_BUFFER,
-                                                  newctx->gl_shader_storage_buffer_binding[0]))
+       for (i = 0; i < newctx->gl_uniform_buffer_binding_num[0]; i++) {
+               if STATE_COMPARE(gl_uniform_buffer_binding_array[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_UNIFORM_BUFFER, i,
+                                                  newctx->gl_uniform_buffer_binding_array[i]))
                }
-               if STATE_COMPARE(gl_atomic_counter_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ATOMIC_COUNTER_BUFFER,
-                                                  newctx->gl_atomic_counter_buffer_binding[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_bind_3(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
+
+       if(!(oldctx->_bind_flag3 | newctx->_bind_flag3)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_shader_storage_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_SHADER_STORAGE_BUFFER,
+                                          newctx->gl_shader_storage_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_atomic_counter_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_ATOMIC_COUNTER_BUFFER,
+                                          newctx->gl_atomic_counter_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_draw_indirect_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_DRAW_INDIRECT_BUFFER,
+                                          newctx->gl_draw_indirect_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_dispatch_indirect_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER,
+                                          newctx->gl_dispatch_indirect_buffer_binding[0]))
+       }
+
+       if STATE_COMPARE(gl_texture_buffer_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TEXTURE_BUFFER,
+                                          newctx->gl_texture_buffer_binding[0]))
+       }
+
+       /* handle states set in fastpath_glBindBufferBase() */
+       for (i = 0; i < newctx->gl_shader_storage_buffer_binding_num[0]; i++) {
+               if STATE_COMPARE(gl_shader_storage_buffer_binding_array[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i,
+                                                  newctx->gl_shader_storage_buffer_binding_array[i]))
                }
-               if STATE_COMPARE(gl_draw_indirect_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_DRAW_INDIRECT_BUFFER,
-                                                  newctx->gl_draw_indirect_buffer_binding[0]))
+       }
+
+       for (i = 0; i < newctx->gl_atomic_counter_buffer_binding_num[0]; i++) {
+               if STATE_COMPARE(gl_atomic_counter_buffer_binding_array[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i,
+                                                  newctx->gl_atomic_counter_buffer_binding_array[i]))
                }
-               if STATE_COMPARE(gl_dispatch_indirect_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER,
-                                                  newctx->gl_dispatch_indirect_buffer_binding[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_bind_4(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
+
+       if(!(oldctx->_bind_flag4 | newctx->_bind_flag4)) {
+               return 1;
+       }
+
+       /* handle states set in fastpath_BindBufferRrange() */
+       for (i = 0; i < newctx->gl_transform_feedback_buffer_binding_num[0]; i++) {
+               if (STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array[i]) ||
+                               STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array_offset[i]) ||
+                               STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array_size[i])) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i,
+                                                  newctx->gl_transform_feedback_buffer_range_binding_array[i],
+                                                  newctx->gl_transform_feedback_buffer_range_binding_array_offset[i],
+                                                  newctx->gl_transform_feedback_buffer_range_binding_array_size[i]))
                }
-               if STATE_COMPARE(gl_texture_buffer_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindBuffer(GL_TEXTURE_BUFFER,
-                                                  newctx->gl_texture_buffer_binding[0]))
+       }
+
+       for (i = 0; i < newctx->gl_uniform_buffer_binding_num[0]; i++) {
+               if (STATE_COMPARE(gl_uniform_buffer_range_binding_array[i]) ||
+                               STATE_COMPARE(gl_uniform_buffer_range_binding_array_offset[i]) ||
+                               STATE_COMPARE(gl_uniform_buffer_range_binding_array_size[i])) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_UNIFORM_BUFFER, i,
+                                                  newctx->gl_uniform_buffer_range_binding_array[i],
+                                                  newctx->gl_uniform_buffer_range_binding_array_offset[i],
+                                                  newctx->gl_uniform_buffer_range_binding_array_size[i]))
                }
-               /* handle states set in fastpath_glBindBufferBase() */
-               for (i = 0; i < newctx->gl_shader_storage_buffer_binding_num[0]; i++) {
-                       if STATE_COMPARE(gl_shader_storage_buffer_binding_array[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i,
-                                                          newctx->gl_shader_storage_buffer_binding_array[i]))
-                       }
+       }
+
+       for (i = 0; i < newctx->gl_shader_storage_buffer_binding_num[0]; i++) {
+               if (STATE_COMPARE(gl_shader_storage_buffer_range_binding_array[i]) ||
+                               STATE_COMPARE(gl_shader_storage_buffer_range_binding_array_offset[i]) ||
+                               STATE_COMPARE(gl_shader_storage_buffer_range_binding_array_size[i])) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i,
+                                                  newctx->gl_shader_storage_buffer_range_binding_array[i],
+                                                  newctx->gl_shader_storage_buffer_range_binding_array_offset[i],
+                                                  newctx->gl_shader_storage_buffer_range_binding_array_size[i]))
                }
-               for (i = 0; i < newctx->gl_atomic_counter_buffer_binding_num[0]; i++) {
-                       if STATE_COMPARE(gl_atomic_counter_buffer_binding_array[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, i,
-                                                          newctx->gl_atomic_counter_buffer_binding_array[i]))
-                       }
+       }
+
+       for (i = 0; i < newctx->gl_atomic_counter_buffer_binding_num[0]; i++) {
+               if (STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array[i]) ||
+                               STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array_offset[i]) ||
+                               STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array_size[i])) {
+                       CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i,
+                                                  newctx->gl_atomic_counter_buffer_range_binding_array[i],
+                                                  newctx->gl_atomic_counter_buffer_range_binding_array_offset[i],
+                                                  newctx->gl_atomic_counter_buffer_range_binding_array_size[i]))
                }
        }
 
-       flag = oldctx->_bind_flag4 | newctx->_bind_flag4;
-       if (flag) {
-               /* handle states set in fastpath_BindBufferRrange() */
-               for (i = 0; i < newctx->gl_transform_feedback_buffer_binding_num[0]; i++) {
-                       if (STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array[i]) ||
-                                       STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array_offset[i]) ||
-                                       STATE_COMPARE(gl_transform_feedback_buffer_range_binding_array_size[i])) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i,
-                                                          newctx->gl_transform_feedback_buffer_range_binding_array[i],
-                                                          newctx->gl_transform_feedback_buffer_range_binding_array_offset[i],
-                                                          newctx->gl_transform_feedback_buffer_range_binding_array_size[i]))
-                       }
+       return 1;
+}
+
+GLuint
+fastpath_check_context_enable_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_enable_flag1 | newctx->_enable_flag1)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_blend[0]) {
+               if (newctx->gl_blend[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
                }
-               for (i = 0; i < newctx->gl_uniform_buffer_binding_num[0]; i++) {
-                       if (STATE_COMPARE(gl_uniform_buffer_range_binding_array[i]) ||
-                                       STATE_COMPARE(gl_uniform_buffer_range_binding_array_offset[i]) ||
-                                       STATE_COMPARE(gl_uniform_buffer_range_binding_array_size[i])) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_UNIFORM_BUFFER, i,
-                                                          newctx->gl_uniform_buffer_range_binding_array[i],
-                                                          newctx->gl_uniform_buffer_range_binding_array_offset[i],
-                                                          newctx->gl_uniform_buffer_range_binding_array_size[i]))
-                       }
+       }
+
+       if STATE_COMPARE(gl_cull_face[0]) {
+               if (newctx->gl_cull_face[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
                }
-               for (i = 0; i < newctx->gl_shader_storage_buffer_binding_num[0]; i++) {
-                       if (STATE_COMPARE(gl_shader_storage_buffer_range_binding_array[i]) ||
-                                       STATE_COMPARE(gl_shader_storage_buffer_range_binding_array_offset[i]) ||
-                                       STATE_COMPARE(gl_shader_storage_buffer_range_binding_array_size[i])) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i,
-                                                          newctx->gl_shader_storage_buffer_range_binding_array[i],
-                                                          newctx->gl_shader_storage_buffer_range_binding_array_offset[i],
-                                                          newctx->gl_shader_storage_buffer_range_binding_array_size[i]))
-                       }
+       }
+
+       if STATE_COMPARE(gl_depth_test[0]) {
+               if (newctx->gl_depth_test[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
                }
-               for (i = 0; i < newctx->gl_atomic_counter_buffer_binding_num[0]; i++) {
-                       if (STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array[i]) ||
-                                       STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array_offset[i]) ||
-                                       STATE_COMPARE(gl_atomic_counter_buffer_range_binding_array_size[i])) {
-                               CHECK_GL_ERROR(_orig_fastpath_glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i,
-                                                          newctx->gl_atomic_counter_buffer_range_binding_array[i],
-                                                          newctx->gl_atomic_counter_buffer_range_binding_array_offset[i],
-                                                          newctx->gl_atomic_counter_buffer_range_binding_array_size[i]))
-                       }
+       }
+
+       if STATE_COMPARE(gl_dither[0]) {
+               if (newctx->gl_dither[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
                }
        }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP bind buffers)",
-                                                       trace_hint_bindbuffers, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       return 1;
+}
 
+GLuint
+fastpath_check_context_enable_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_enable_flag2 | newctx->_enable_flag2)) {
+               return 1;
+       }
 
-       //------------------//
-       // Enable States
-       // _enable_flag1
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_enable_states = NULL;
-       trace_hint_enable_states =
-               tracepath_api_trace_begin("eglMakeCurrent(FP enable states)",
-                                                                 trace_hint_enable_states, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       flag = oldctx->_enable_flag1 | newctx->_enable_flag1;
-       if (flag) {
-               if STATE_COMPARE(gl_blend[0]) {
-                       if (newctx->gl_blend[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND))
-                       }
-               if STATE_COMPARE(gl_cull_face[0]) {
-                       if (newctx->gl_cull_face[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_CULL_FACE))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_CULL_FACE))
-                       }
-               if STATE_COMPARE(gl_depth_test[0]) {
-                       if (newctx->gl_depth_test[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DEPTH_TEST))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DEPTH_TEST))
-                       }
-               if STATE_COMPARE(gl_dither[0]) {
-                       if (newctx->gl_dither[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_DITHER))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_DITHER))
-                       }
+       if STATE_COMPARE(gl_polygon_offset_fill[0]) {
+               if (newctx->gl_polygon_offset_fill[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
+               }
        }
 
-       // _enable_flag2
-       flag = oldctx->_enable_flag2 | newctx->_enable_flag2;
-       if (flag) {
-               if STATE_COMPARE(gl_polygon_offset_fill[0]) {
-                       if (newctx->gl_polygon_offset_fill[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_POLYGON_OFFSET_FILL))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_POLYGON_OFFSET_FILL))
-                       }
-               if STATE_COMPARE(gl_sample_alpha_to_coverage[0]) {
-                       if (newctx->gl_sample_alpha_to_coverage[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
-                       }
-               if STATE_COMPARE(gl_sample_coverage[0]) {
-                       if (newctx->gl_sample_coverage[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
-                       }
-               if STATE_COMPARE(gl_scissor_test[0]) {
-                       if (newctx->gl_scissor_test[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
-                       }
-               if STATE_COMPARE(gl_stencil_test[0]) {
-                       if (newctx->gl_stencil_test[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
-                       }
-               if STATE_COMPARE(gl_sample_shading_oes[0]) {
-                       if (newctx->gl_sample_shading_oes[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_SHADING_OES))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_SHADING_OES))
-                       }
-               if STATE_COMPARE(gl_sample_mask[0]) {
-                       if (newctx->gl_sample_mask[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_MASK))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_MASK))
-                       }
+       if STATE_COMPARE(gl_sample_alpha_to_coverage[0]) {
+               if (newctx->gl_sample_alpha_to_coverage[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE))
+               }
        }
 
-       // _enable_flag3
-       flag = oldctx->_enable_flag3 | newctx->_enable_flag3;
-       if (flag) {
-               if STATE_COMPARE(gl_primitive_restart_fixed_index[0]) {
-                       if (newctx->gl_primitive_restart_fixed_index[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
-                       }
-               if STATE_COMPARE(gl_rasterizer_discard[0]) {
-                       if (newctx->gl_rasterizer_discard[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_RASTERIZER_DISCARD))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_RASTERIZER_DISCARD))
-                       }
-               if STATE_COMPARE(gl_blend_advanced_coherent_khr[0]) {
-                       if (newctx->gl_blend_advanced_coherent_khr[0]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND_ADVANCED_COHERENT_KHR))
-                       } else
-                               CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND_ADVANCED_COHERENT_KHR))
-                       }
+       if STATE_COMPARE(gl_sample_coverage[0]) {
+               if (newctx->gl_sample_coverage[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_COVERAGE))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_COVERAGE))
+               }
        }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP enable states)",
-                                                       trace_hint_enable_states, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       if STATE_COMPARE(gl_scissor_test[0]) {
+               if (newctx->gl_scissor_test[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SCISSOR_TEST))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SCISSOR_TEST))
+               }
+       }
 
-       //------------------//
-       // _clear_flag1
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_clear_viewport = NULL;
-       trace_hint_clear_viewport =
-               tracepath_api_trace_begin("eglMakeCurrent(FP clear/viewport)",
-                                                                 trace_hint_clear_viewport, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       flag = oldctx->_clear_flag1 | newctx->_clear_flag1;
-       if (flag) {
-               // Viewport.
-               if STATES_COMPARE(gl_viewport, 4 * sizeof(GLint)) {
-                       CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
-                                                  newctx->gl_viewport[1],
-                                                  newctx->gl_viewport[2],
-                                                  newctx->gl_viewport[3]))
-               }
-
-               if STATE_COMPARE(gl_current_program[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
-               }
-               if STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf)) {
-                       CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
-                                                  newctx->gl_color_clear_value[1],
-                                                  newctx->gl_color_clear_value[2],
-                                                  newctx->gl_color_clear_value[3]))
-               }
-       }
-
-
-       // _clear_flag2
-       flag = oldctx->_clear_flag2 | newctx->_clear_flag2;
-       if (flag) {
-               if STATES_COMPARE(gl_color_writemask,
-                                                 4 * GL_CLOR_WRITEMASK_NUM * sizeof(GLboolean)) {
-                       for (i = 0; i < GL_CLOR_WRITEMASK_NUM; i++) {
-                               if(NULL != _orig_fastpath_glColorMaski)
-                               {
-                                       CHECK_GL_ERROR(_orig_fastpath_glColorMaski(i,
-                                                                  (newctx->gl_color_writemask + i)[0],
-                                                                  (newctx->gl_color_writemask + i)[1],
-                                                                  (newctx->gl_color_writemask + i)[2],
-                                                                  (newctx->gl_color_writemask + i)[3]))
-                               }
-                       }
+       if STATE_COMPARE(gl_stencil_test[0]) {
+               if (newctx->gl_stencil_test[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_STENCIL_TEST))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_STENCIL_TEST))
                }
-               if STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf)) {
-                       CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
-                                                  newctx->gl_depth_range[1]))
+       }
+
+       if STATE_COMPARE(gl_sample_shading_oes[0]) {
+               if (newctx->gl_sample_shading_oes[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_SHADING_OES))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_SHADING_OES))
                }
-               if STATE_COMPARE(gl_depth_clear_value[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
+       }
+
+       if STATE_COMPARE(gl_sample_mask[0]) {
+               if (newctx->gl_sample_mask[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_SAMPLE_MASK))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_SAMPLE_MASK))
                }
-               if STATE_COMPARE(gl_depth_func[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_enable_3(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_enable_flag3 | newctx->_enable_flag3)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_primitive_restart_fixed_index[0]) {
+               if (newctx->gl_primitive_restart_fixed_index[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
                }
-               if STATE_COMPARE(gl_depth_writemask[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
+       }
+
+       if STATE_COMPARE(gl_rasterizer_discard[0]) {
+               if (newctx->gl_rasterizer_discard[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_RASTERIZER_DISCARD))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_RASTERIZER_DISCARD))
                }
-               if STATE_COMPARE(gl_cull_face_mode[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
+       }
+
+       if STATE_COMPARE(gl_blend_advanced_coherent_khr[0]) {
+               if (newctx->gl_blend_advanced_coherent_khr[0]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glEnable(GL_BLEND_ADVANCED_COHERENT_KHR))
+               } else {
+                       CHECK_GL_ERROR(_orig_fastpath_glDisable(GL_BLEND_ADVANCED_COHERENT_KHR))
                }
+       }
+
+       return 1;
+}
 
+GLuint
+fastpath_check_context_clear_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_clear_flag1 | newctx->_clear_flag1)) {
+               return 1;
        }
 
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP clear/viewport)",
-                                                       trace_hint_clear_viewport, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+       /* Viewport */
+       if STATES_COMPARE(gl_viewport, 4 * sizeof(GLint)) {
+               CHECK_GL_ERROR(_orig_fastpath_glViewport(newctx->gl_viewport[0],
+                                          newctx->gl_viewport[1],
+                                          newctx->gl_viewport[2],
+                                          newctx->gl_viewport[3]))
+       }
 
-       //------------------//
-       // Texture here...
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_bind_textures = NULL;
-       trace_hint_bind_textures =
-               tracepath_api_trace_begin("eglMakeCurrent(FP bind textures)",
-                                                                 trace_hint_bind_textures, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       flag = oldctx->_tex_flag1 | newctx->_tex_flag1;
-       if (flag) {
-
-               for (i = 0; i < oldctx->gl_tex_units_num[0]; i++) {
-                       if STATE_COMPARE(gl_tex_2d_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D,
-                                                          newctx->gl_tex_2d_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_3d_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_3D,
-                                                          newctx->gl_tex_3d_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_2d_array_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_ARRAY,
-                                                          newctx->gl_tex_2d_array_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_cube_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP,
-                                                          newctx->gl_tex_cube_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_external_oes_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_EXTERNAL_OES,
-                                                          newctx->gl_tex_external_oes_state[i]))
-                       }
-               }
+       if STATE_COMPARE(gl_current_program[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glUseProgram(newctx->gl_current_program[0]))
+       }
 
-               // Restore active texture
-               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
+       if STATES_COMPARE(gl_color_clear_value, 4 * sizeof(GLclampf)) {
+               CHECK_GL_ERROR(_orig_fastpath_glClearColor(newctx->gl_color_clear_value[0],
+                                          newctx->gl_color_clear_value[1],
+                                          newctx->gl_color_clear_value[2],
+                                          newctx->gl_color_clear_value[3]))
+       }
 
-               if STATE_COMPARE(gl_generate_mipmap_hint[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT,
-                                                                                                newctx->gl_generate_mipmap_hint[0]))
-               }
+       return 1;
+}
+
+GLuint
+fastpath_check_context_clear_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
+
+       if(!(oldctx->_clear_flag2 | newctx->_clear_flag2)) {
+               return 1;
        }
 
-       flag = oldctx->_tex_flag2 | newctx->_tex_flag2;
-       if (flag) {
-               for (i = 0; i < oldctx->gl_tex_units_num[0]; i++) {
-                       if STATE_COMPARE(gl_tex_buffer_ext_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_BUFFER_EXT,
-                                                          newctx->gl_tex_buffer_ext_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_2d_multisample_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
-                                                          newctx->gl_tex_2d_multisample_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_cube_map_array_ext_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY_EXT,
-                                                          newctx->gl_tex_cube_map_array_ext_state[i]))
-                       }
-                       if STATE_COMPARE(gl_tex_2d_multisample_array_oes_state[i]) {
-                               CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
-                               CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES,
-                                                          newctx->gl_tex_2d_multisample_array_oes_state[i]))
+       if STATES_COMPARE(gl_color_writemask, 4 * GL_CLOR_WRITEMASK_NUM * sizeof(GLboolean)) {
+               for (i = 0; i < GL_CLOR_WRITEMASK_NUM; i++) {
+                       if(NULL != _orig_fastpath_glColorMaski) {
+                               CHECK_GL_ERROR(_orig_fastpath_glColorMaski(i,
+                                                          (newctx->gl_color_writemask + i)[0],
+                                                          (newctx->gl_color_writemask + i)[1],
+                                                          (newctx->gl_color_writemask + i)[2],
+                                                          (newctx->gl_color_writemask + i)[3]))
                        }
                }
        }
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP bind textures)",
-                                                       trace_hint_bind_textures, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
 
-       //------------------//
-#ifdef COREGL_USE_MODULE_TRACEPATH
-       static void *trace_hint_etc = NULL;
-       trace_hint_etc = tracepath_api_trace_begin("eglMakeCurrent(FP etc.)",
-                                        trace_hint_etc, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
-
-       flag = oldctx->_blend_flag | newctx->_blend_flag;
-       if (flag) {
-               if STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf)) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
-                                                  newctx->gl_blend_color[1],
-                                                  newctx->gl_blend_color[2],
-                                                  newctx->gl_blend_color[3]))
-               }
-               if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
-                               (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
-                               (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
-                               (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
-                                                  newctx->gl_blend_dst_rgb[0],
-                                                  newctx->gl_blend_src_alpha[0],
-                                                  newctx->gl_blend_dst_alpha[0]))
-               }
-               if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
-                               (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(
-                                                          newctx->gl_blend_equation_rgb[0], newctx->gl_blend_equation_alpha[0]))
-               }
-
-       }
-
-       //------------------//
-       // _stencil_flag1
-       flag = oldctx->_stencil_flag1 | newctx->_stencil_flag1;
-       if (flag) {
-               if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
-                               (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0])  ||
-                               (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
-                                                  newctx->gl_stencil_func[0],
-                                                  newctx->gl_stencil_ref[0],
-                                                  newctx->gl_stencil_value_mask[0]))
-               }
-               if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
-                               (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0])
-                               ||
-                               (oldctx->gl_stencil_pass_depth_pass[0] !=
-                                newctx->gl_stencil_pass_depth_pass[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
-                                                  newctx->gl_stencil_fail[0],
-                                                  newctx->gl_stencil_pass_depth_fail[0],
-                                                  newctx->gl_stencil_pass_depth_pass[0]))
-               }
+       if STATES_COMPARE(gl_depth_range, 2 * sizeof(GLclampf)) {
+               CHECK_GL_ERROR(_orig_fastpath_glDepthRangef(newctx->gl_depth_range[0],
+                                          newctx->gl_depth_range[1]))
+       }
 
-               if STATE_COMPARE(gl_stencil_writemask[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT,
-                                                  newctx->gl_stencil_writemask[0]))
-               }
-       }
-
-
-       // _stencil_flag1
-       flag = oldctx->_stencil_flag2 | newctx->_stencil_flag2;
-       if (flag) {
-               if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
-                               (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0])  ||
-                               (oldctx->gl_stencil_back_value_mask[0] !=
-                                newctx->gl_stencil_back_value_mask[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
-                                                  newctx->gl_stencil_back_func[0],
-                                                  newctx->gl_stencil_back_ref[0],
-                                                  newctx->gl_stencil_back_value_mask[0]))
-               }
-               if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
-                               (oldctx->gl_stencil_back_pass_depth_fail[0] !=
-                                newctx->gl_stencil_back_pass_depth_fail[0]) ||
-                               (oldctx->gl_stencil_back_pass_depth_pass[0] !=
-                                newctx->gl_stencil_back_pass_depth_pass[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
-                                                  newctx->gl_stencil_back_fail[0],
-                                                  newctx->gl_stencil_back_pass_depth_fail[0],
-                                                  newctx->gl_stencil_back_pass_depth_pass[0]))
-               }
-
-               if STATE_COMPARE(gl_stencil_back_writemask[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK,
-                                                  newctx->gl_stencil_back_writemask[0]))
-               }
-               if STATE_COMPARE(gl_stencil_clear_value[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
-               }
-       }
-
-       //------------------//
-       // _pixel_flag1
-       flag = oldctx->_pixel_flag1 | newctx->_pixel_flag1;
-       if (flag) {
-               if STATE_COMPARE(gl_pack_row_length[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ROW_LENGTH,
-                                                  newctx->gl_pack_row_length[0]))
-               }
-               if STATE_COMPARE(gl_pack_skip_rows[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_ROWS,
-                                                  newctx->gl_pack_skip_rows[0]))
-               }
-               if STATE_COMPARE(gl_pack_skip_pixels[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_PIXELS,
-                                                  newctx->gl_pack_skip_pixels[0]))
-               }
-               if STATE_COMPARE(gl_pack_alignment[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT,
-                                                  newctx->gl_pack_alignment[0]))
-               }
-       }
-
-       // _pixel_flag2
-       flag = oldctx->_pixel_flag2 | newctx->_pixel_flag2;
-       if (flag) {
-               if STATE_COMPARE(gl_unpack_row_length[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ROW_LENGTH,
-                                                  newctx->gl_unpack_row_length[0]))
-               }
-               if STATE_COMPARE(gl_unpack_skip_rows[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_ROWS,
-                                                  newctx->gl_unpack_skip_rows[0]))
-               }
-               if STATE_COMPARE(gl_unpack_skip_pixels[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_PIXELS,
-                                                  newctx->gl_unpack_skip_pixels[0]))
-               }
-               if STATE_COMPARE(gl_unpack_alignment[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT,
-                                                  newctx->gl_unpack_alignment[0]))
-               }
-               if STATE_COMPARE(gl_unpack_image_height[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,
-                                                  newctx->gl_unpack_image_height[0]))
-               }
-               if STATE_COMPARE(gl_unpack_skip_images[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_IMAGES,
-                                                  newctx->gl_unpack_skip_images[0]))
-               }
+       if STATE_COMPARE(gl_depth_clear_value[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glClearDepthf(newctx->gl_depth_clear_value[0]))
+       }
+
+       if STATE_COMPARE(gl_depth_func[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glDepthFunc(newctx->gl_depth_func[0]))
+       }
+
+       if STATE_COMPARE(gl_depth_writemask[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glDepthMask(newctx->gl_depth_writemask[0]))
        }
-
-       //------------------//
-       // _misc_flag1
-       flag = oldctx->_misc_flag1 | newctx->_misc_flag1;
-       if (flag) {
-               if STATE_COMPARE(gl_front_face[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
+
+       if STATE_COMPARE(gl_cull_face_mode[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glCullFace(newctx->gl_cull_face_mode[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_tex_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
+
+       if(!(oldctx->_tex_flag1 | newctx->_tex_flag1)) {
+               return 1;
+       }
+
+       for (i = 0; i < oldctx->gl_tex_units_num[0]; i++) {
+               if STATE_COMPARE(gl_tex_2d_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D,
+                                                  newctx->gl_tex_2d_state[i]))
                }
-               if STATE_COMPARE(gl_line_width[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
+
+               if STATE_COMPARE(gl_tex_3d_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_3D,
+                                                  newctx->gl_tex_3d_state[i]))
                }
-               if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0])
-                               ||
-                               (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(
-                                                          newctx->gl_polygon_offset_factor[0],
-                                                          newctx->gl_polygon_offset_units[0]))
-               }
-               if ((oldctx->gl_sample_coverage_value[0]  !=
-                               newctx->gl_sample_coverage_value[0]) ||
-                               (oldctx->gl_sample_coverage_invert[0] !=
-                                newctx->gl_sample_coverage_invert[0])) {
-                       CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(
-                                                          newctx->gl_sample_coverage_value[0],
-                                                          newctx->gl_sample_coverage_invert[0]))
+
+               if STATE_COMPARE(gl_tex_2d_array_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_ARRAY,
+                                                  newctx->gl_tex_2d_array_state[i]))
                }
-               if STATE_COMPARE(gl_fragment_shader_derivative_hint[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES,
-                                                                                                newctx->gl_fragment_shader_derivative_hint[0]))
+
+               if STATE_COMPARE(gl_tex_cube_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP,
+                                                  newctx->gl_tex_cube_state[i]))
                }
-       }
 
-       // _misc_flag2
-       flag = oldctx->_misc_flag2 | newctx->_misc_flag2;
-       if (flag) {
-               if STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint)) {
-                       CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
-                                                                                                       newctx->gl_scissor_box[1],
-                                                                                                       newctx->gl_scissor_box[2],
-                                                                                                       newctx->gl_scissor_box[3]))
+               if STATE_COMPARE(gl_tex_external_oes_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_EXTERNAL_OES,
+                                                  newctx->gl_tex_external_oes_state[i]))
                }
        }
 
-       // _misc_flag3
-       flag = oldctx->_misc_flag3 | newctx->_misc_flag3;
-       if (flag) {
-               if STATE_COMPARE(gl_read_buffer[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glReadBuffer(newctx->gl_read_buffer[0]))
+       /* Restore active texture */
+       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(newctx->gl_active_texture[0]))
+
+       if STATE_COMPARE(gl_generate_mipmap_hint[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glHint(GL_GENERATE_MIPMAP_HINT,
+                                          newctx->gl_generate_mipmap_hint[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_tex_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int i;
+
+       if(!(oldctx->_tex_flag2 | newctx->_tex_flag2)) {
+               return 1;
+       }
+
+       for (i = 0; i < oldctx->gl_tex_units_num[0]; i++) {
+               if STATE_COMPARE(gl_tex_buffer_ext_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_BUFFER_EXT,
+                                                  newctx->gl_tex_buffer_ext_state[i]))
                }
-               if STATES_COMPARE(gl_draw_buffers,
-                                                 oldctx->gl_draw_buffers_num[0] * sizeof(GLenum)) {
-                       int drawBuffSize = 16;
-                       /* If the  context has only default framebuffer, then size of glDrawBuffers can only be 1 */
-                       if (fastpath_ostate_has_object_type(&newctx->ostate,
-                                                                                               GL_OBJECT_TYPE_FRAMEBUFFER) == 0) {
-                               drawBuffSize = 1;
-                       }
 
-                       CHECK_GL_ERROR(_orig_fastpath_glDrawBuffers(drawBuffSize,
-                                                  newctx->gl_draw_buffers))
+               if STATE_COMPARE(gl_tex_2d_multisample_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
+                                                  newctx->gl_tex_2d_multisample_state[i]))
                }
 
-               if (oldctx->gl_transform_feedback_active[0] == GL_TRUE &&
-                               oldctx->gl_transform_feedback_paused[0] == GL_FALSE) {
-                       CHECK_GL_ERROR(_orig_fastpath_glPauseTransformFeedback())
+               if STATE_COMPARE(gl_tex_cube_map_array_ext_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY_EXT,
+                                                  newctx->gl_tex_cube_map_array_ext_state[i]))
                }
-               if STATE_COMPARE(gl_transform_feedback_binding[0]) {
-                       CHECK_GL_ERROR(_orig_fastpath_glBindTransformFeedback(GL_TRANSFORM_FEEDBACK,
-                                                  newctx->gl_transform_feedback_binding[0]))
+
+               if STATE_COMPARE(gl_tex_2d_multisample_array_oes_state[i]) {
+                       CHECK_GL_ERROR(_orig_fastpath_glActiveTexture(GL_TEXTURE0 + i))
+                       CHECK_GL_ERROR(_orig_fastpath_glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES,
+                                                  newctx->gl_tex_2d_multisample_array_oes_state[i]))
                }
-               if (newctx->gl_transform_feedback_active[0] == GL_TRUE &&
-                               newctx->gl_transform_feedback_paused[0] == GL_FALSE) {
-                       CHECK_GL_ERROR(_orig_fastpath_glResumeTransformFeedback())
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_blend(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_blend_flag | newctx->_blend_flag)) {
+               return 1;
+       }
+
+       if STATES_COMPARE(gl_blend_color, 4 * sizeof(GLclampf)) {
+               CHECK_GL_ERROR(_orig_fastpath_glBlendColor(newctx->gl_blend_color[0],
+                                          newctx->gl_blend_color[1],
+                                          newctx->gl_blend_color[2],
+                                          newctx->gl_blend_color[3]))
+       }
+
+       if ((oldctx->gl_blend_src_rgb[0] != newctx->gl_blend_src_rgb[0]) ||
+                       (oldctx->gl_blend_dst_rgb[0] != newctx->gl_blend_dst_rgb[0]) ||
+                       (oldctx->gl_blend_src_alpha[0] != newctx->gl_blend_src_alpha[0]) ||
+                       (oldctx->gl_blend_dst_alpha[0] != newctx->gl_blend_dst_alpha[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glBlendFuncSeparate(newctx->gl_blend_src_rgb[0],
+                                          newctx->gl_blend_dst_rgb[0],
+                                          newctx->gl_blend_src_alpha[0],
+                                          newctx->gl_blend_dst_alpha[0]))
+       }
+
+       if ((oldctx->gl_blend_equation_rgb[0] != newctx->gl_blend_equation_rgb[0]) ||
+                       (oldctx->gl_blend_equation_alpha[0] != newctx->gl_blend_equation_alpha[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glBlendEquationSeparate(
+                                          newctx->gl_blend_equation_rgb[0],
+                                          newctx->gl_blend_equation_alpha[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_stencil_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_stencil_flag1 | newctx->_stencil_flag1)) {
+               return 1;
+       }
+
+       if ((oldctx->gl_stencil_func[0] != newctx->gl_stencil_func[0]) ||
+                       (oldctx->gl_stencil_ref[0]  != newctx->gl_stencil_ref[0]) ||
+                       (oldctx->gl_stencil_value_mask[0] != newctx->gl_stencil_value_mask[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_FRONT,
+                                          newctx->gl_stencil_func[0],
+                                          newctx->gl_stencil_ref[0],
+                                          newctx->gl_stencil_value_mask[0]))
+       }
+
+       if ((oldctx->gl_stencil_fail[0] != newctx->gl_stencil_fail[0]) ||
+                       (oldctx->gl_stencil_pass_depth_fail[0] != newctx->gl_stencil_pass_depth_fail[0]) ||
+                       (oldctx->gl_stencil_pass_depth_pass[0] != newctx->gl_stencil_pass_depth_pass[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_FRONT,
+                                          newctx->gl_stencil_fail[0],
+                                          newctx->gl_stencil_pass_depth_fail[0],
+                                          newctx->gl_stencil_pass_depth_pass[0]))
+       }
+
+       if STATE_COMPARE(gl_stencil_writemask[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_FRONT,
+                                          newctx->gl_stencil_writemask[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_stencil_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_stencil_flag2 | newctx->_stencil_flag2)) {
+               return 1;
+       }
+
+       if ((oldctx->gl_stencil_back_func[0] != newctx->gl_stencil_back_func[0]) ||
+                       (oldctx->gl_stencil_back_ref[0]  != newctx->gl_stencil_back_ref[0]) ||
+                       (oldctx->gl_stencil_back_value_mask[0] != newctx->gl_stencil_back_value_mask[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilFuncSeparate(GL_BACK,
+                                          newctx->gl_stencil_back_func[0],
+                                          newctx->gl_stencil_back_ref[0],
+                                          newctx->gl_stencil_back_value_mask[0]))
+       }
+
+       if ((oldctx->gl_stencil_back_fail[0] != newctx->gl_stencil_back_fail[0]) ||
+                       (oldctx->gl_stencil_back_pass_depth_fail[0] != newctx->gl_stencil_back_pass_depth_fail[0]) ||
+                       (oldctx->gl_stencil_back_pass_depth_pass[0] != newctx->gl_stencil_back_pass_depth_pass[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilOpSeparate(GL_BACK,
+                                          newctx->gl_stencil_back_fail[0],
+                                          newctx->gl_stencil_back_pass_depth_fail[0],
+                                          newctx->gl_stencil_back_pass_depth_pass[0]))
+       }
+
+       if STATE_COMPARE(gl_stencil_back_writemask[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glStencilMaskSeparate(GL_BACK,
+                                          newctx->gl_stencil_back_writemask[0]))
+       }
+
+       if STATE_COMPARE(gl_stencil_clear_value[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glClearStencil(newctx->gl_stencil_clear_value[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_pixel_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_pixel_flag1 | newctx->_pixel_flag1)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_pack_row_length[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ROW_LENGTH,
+                                          newctx->gl_pack_row_length[0]))
+       }
+
+       if STATE_COMPARE(gl_pack_skip_rows[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_ROWS,
+                                          newctx->gl_pack_skip_rows[0]))
+       }
+
+       if STATE_COMPARE(gl_pack_skip_pixels[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_SKIP_PIXELS,
+                                          newctx->gl_pack_skip_pixels[0]))
+       }
+
+       if STATE_COMPARE(gl_pack_alignment[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_PACK_ALIGNMENT,
+                                          newctx->gl_pack_alignment[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_pixel_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_pixel_flag2 | newctx->_pixel_flag2)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_unpack_row_length[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ROW_LENGTH,
+                                          newctx->gl_unpack_row_length[0]))
+       }
+
+       if STATE_COMPARE(gl_unpack_skip_rows[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_ROWS,
+                                          newctx->gl_unpack_skip_rows[0]))
+       }
+
+       if STATE_COMPARE(gl_unpack_skip_pixels[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_PIXELS,
+                                          newctx->gl_unpack_skip_pixels[0]))
+       }
+
+       if STATE_COMPARE(gl_unpack_alignment[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_ALIGNMENT,
+                                          newctx->gl_unpack_alignment[0]))
+       }
+
+       if STATE_COMPARE(gl_unpack_image_height[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,
+                                          newctx->gl_unpack_image_height[0]))
+       }
+
+       if STATE_COMPARE(gl_unpack_skip_images[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glPixelStorei(GL_UNPACK_SKIP_IMAGES,
+                                          newctx->gl_unpack_skip_images[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_misc_1(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_misc_flag1 | newctx->_misc_flag1)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_front_face[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glFrontFace(newctx->gl_front_face[0]))
+       }
+
+       if STATE_COMPARE(gl_line_width[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glLineWidth(newctx->gl_line_width[0]))
+       }
+
+       if ((oldctx->gl_polygon_offset_factor[0] != newctx->gl_polygon_offset_factor[0]) ||
+                       (oldctx->gl_polygon_offset_units[0]  != newctx->gl_polygon_offset_units[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glPolygonOffset(
+                                          newctx->gl_polygon_offset_factor[0],
+                                          newctx->gl_polygon_offset_units[0]))
+       }
+
+       if ((oldctx->gl_sample_coverage_value[0] !=     newctx->gl_sample_coverage_value[0]) ||
+                       (oldctx->gl_sample_coverage_invert[0] != newctx->gl_sample_coverage_invert[0])) {
+               CHECK_GL_ERROR(_orig_fastpath_glSampleCoverage(
+                                          newctx->gl_sample_coverage_value[0],
+                                          newctx->gl_sample_coverage_invert[0]))
+       }
+
+       if STATE_COMPARE(gl_fragment_shader_derivative_hint[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES,
+                                          newctx->gl_fragment_shader_derivative_hint[0]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_misc_2(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_misc_flag2 | newctx->_misc_flag2)) {
+               return 1;
+       }
+
+       if STATES_COMPARE(gl_scissor_box, 4 * sizeof(GLint)) {
+               CHECK_GL_ERROR(_orig_fastpath_glScissor(newctx->gl_scissor_box[0],
+                                          newctx->gl_scissor_box[1],
+                                          newctx->gl_scissor_box[2],
+                                          newctx->gl_scissor_box[3]))
+       }
+
+       return 1;
+}
+
+GLuint
+fastpath_check_context_misc_3(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       if(!(oldctx->_misc_flag3 | newctx->_misc_flag3)) {
+               return 1;
+       }
+
+       if STATE_COMPARE(gl_read_buffer[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glReadBuffer(newctx->gl_read_buffer[0]))
+       }
+
+       if STATES_COMPARE(gl_draw_buffers, oldctx->gl_draw_buffers_num[0] * sizeof(GLenum)) {
+               int drawBuffSize = 16;
+               /* If the  context has only default framebuffer, then size of glDrawBuffers can only be 1 */
+               if (fastpath_ostate_has_object_type(&newctx->ostate, GL_OBJECT_TYPE_FRAMEBUFFER) == 0) {
+                       drawBuffSize = 1;
                }
+
+               CHECK_GL_ERROR(_orig_fastpath_glDrawBuffers(drawBuffSize, newctx->gl_draw_buffers))
+       }
+
+       if (oldctx->gl_transform_feedback_active[0] == GL_TRUE &&
+                       oldctx->gl_transform_feedback_paused[0] == GL_FALSE) {
+               CHECK_GL_ERROR(_orig_fastpath_glPauseTransformFeedback())
+       }
+
+       if STATE_COMPARE(gl_transform_feedback_binding[0]) {
+               CHECK_GL_ERROR(_orig_fastpath_glBindTransformFeedback(GL_TRANSFORM_FEEDBACK,
+                                          newctx->gl_transform_feedback_binding[0]))
        }
 
+       if (newctx->gl_transform_feedback_active[0] == GL_TRUE &&
+                       newctx->gl_transform_feedback_paused[0] == GL_FALSE) {
+               CHECK_GL_ERROR(_orig_fastpath_glResumeTransformFeedback())
+       }
+
+       return 1;
+}
+
 #ifdef COREGL_USE_MODULE_TRACEPATH
-       tracepath_api_trace_end("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
-#endif // COREGL_USE_MODULE_TRACEPATH
+#define TRACEPATH_API_TRACE_BEGIN(funcname, hint, trace_total_time) \
+               tracepath_api_trace_begin(funcname, hint, trace_total_time)
+#define TRACEPATH_API_TRACE_END(funcname, hint, trace_total_time) \
+               tracepath_api_trace_end(funcname, hint, trace_total_time)
+#else
+#define TRACEPATH_API_TRACE_BEGIN(funcname, hint, trace_total_time)
+#define TRACEPATH_API_TRACE_END(funcname, hint, trace_total_time)
+#endif
+
+int
+fastpath_make_context_current(GLGlueContext *oldctx, GLGlueContext *newctx)
+{
+       int ret = 0;
+
+       if (debug_nofp == 1) {
+               ret = 1;
+               goto finish;
+       }
+
+       /* Return if they're the same */
+       if (oldctx == newctx) {
+               ret = 1;
+               goto finish;
+       }
+
+       static void *trace_hint_glfinish = NULL;
+       trace_hint_glfinish = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP glFinish)",
+                                                 trace_hint_glfinish, 0);
+
+       int err = _orig_fastpath_glGetError();
+       if (err != GL_NO_ERROR && oldctx->gl_error == GL_NO_ERROR) {
+               oldctx->gl_error = err;
+       }
+
+       CHECK_GL_ERROR(_orig_fastpath_glFlush())
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP glFinish)", trace_hint_glfinish, 0);
+
+       static void *trace_hint_vertex_attrib = NULL;
+       trace_hint_vertex_attrib = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP vertex attrib)",
+                                                          trace_hint_vertex_attrib, 0);
+
+       if(!fastpath_check_context_vertex_attribs(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP vertex attrib)",     trace_hint_vertex_attrib, 0);
+
+       static void *trace_hint_bindbuffers = NULL;
+       trace_hint_bindbuffers = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP bind buffers)",
+                                                        trace_hint_bindbuffers, 0);
+
+       if(!fastpath_check_context_bind_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_bind_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_bind_3(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_bind_4(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP bind buffers)", trace_hint_bindbuffers, 0);
+
+       static void *trace_hint_enable_states = NULL;
+       trace_hint_enable_states = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP enable states)",
+                                                          trace_hint_enable_states, 0);
+
+       if(!fastpath_check_context_enable_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_enable_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_enable_3(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP enable states)",     trace_hint_enable_states, 0);
+
+       static void *trace_hint_clear_viewport = NULL;
+       trace_hint_clear_viewport = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP clear/viewport)",
+                                                               trace_hint_clear_viewport, 0);
+
+       if(!fastpath_check_context_clear_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_clear_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP clear/viewport)",
+                                                       trace_hint_clear_viewport, 0);
+
+       static void *trace_hint_bind_textures = NULL;
+       trace_hint_bind_textures = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP bind textures)",
+                                                          trace_hint_bind_textures, 0);
+
+       if(!fastpath_check_context_tex_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_tex_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP bind textures)", trace_hint_bind_textures, 0);
+
+       static void *trace_hint_etc = NULL;
+       trace_hint_etc = TRACEPATH_API_TRACE_BEGIN("eglMakeCurrent(FP etc.)",
+                                        trace_hint_etc, 0);
+
+       if(!fastpath_check_context_blend(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_stencil_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_stencil_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_pixel_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_pixel_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_misc_1(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_misc_2(oldctx, newctx)) {
+               goto finish;
+       }
+
+       if(!fastpath_check_context_misc_3(oldctx, newctx)) {
+               goto finish;
+       }
+
+       TRACEPATH_API_TRACE_END("eglMakeCurrent(FP etc.)", trace_hint_etc, 0);
 
        ret = 1;
-       goto finish;
 
 finish:
 
 #ifdef COREGL_FASTPATH_TRACE_STATE_INFO
-       if (unlikely(trace_state_flag == 1))
+       if (unlikely(trace_state_flag == 1)) {
                fastpath_dump_context_states(newctx, 0);
+       }
+
 #endif // COREGL_FASTPATH_TRACE_STATE_INFO
        return ret;
 #undef STATE_COMPARE
 #undef STATES_COMPARE
 }
-