diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h index 9fbf54be3..fce41e673 100644 --- a/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl-framebuffer-private.h @@ -65,25 +65,27 @@ typedef enum */ typedef enum _CoglFramebufferStateIndex { - COGL_FRAMEBUFFER_STATE_INDEX_BIND = 0, - COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT = 1, - COGL_FRAMEBUFFER_STATE_INDEX_CLIP = 2, - COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3, - COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4, - COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5, - COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6, - COGL_FRAMEBUFFER_STATE_INDEX_MAX = 7 + COGL_FRAMEBUFFER_STATE_INDEX_BIND = 0, + COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT = 1, + COGL_FRAMEBUFFER_STATE_INDEX_CLIP = 2, + COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3, + COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4, + COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5, + COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6, + COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7, + COGL_FRAMEBUFFER_STATE_INDEX_MAX = 8 } CoglFramebufferStateIndex; typedef enum _CoglFramebufferState { - COGL_FRAMEBUFFER_STATE_BIND = 1<<0, - COGL_FRAMEBUFFER_STATE_VIEWPORT = 1<<1, - COGL_FRAMEBUFFER_STATE_CLIP = 1<<2, - COGL_FRAMEBUFFER_STATE_DITHER = 1<<3, - COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4, - COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5, - COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6 + COGL_FRAMEBUFFER_STATE_BIND = 1<<0, + COGL_FRAMEBUFFER_STATE_VIEWPORT = 1<<1, + COGL_FRAMEBUFFER_STATE_CLIP = 1<<2, + COGL_FRAMEBUFFER_STATE_DITHER = 1<<3, + COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4, + COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5, + COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6, + COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7 } CoglFramebufferState; #define COGL_FRAMEBUFFER_STATE_ALL ((1<type != new_draw_buffer->type && - ctx->current_pipeline && - cogl_pipeline_get_cull_face_mode (ctx->current_pipeline) != - COGL_PIPELINE_CULL_FACE_MODE_NONE) - { - ctx->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_CULL_FACE; - ctx->current_pipeline_age--; - } - } - /* XXX: To support the deprecated cogl_set_draw_buffer API we keep * track of the last onscreen framebuffer that was set so that it * can be restored if the COGL_WINDOW_BUFFER enum is used. A @@ -1132,7 +1113,7 @@ notify_buffers_changed (CoglFramebuffer *old_draw_buffer, * _cogl_onscreen_free as a kind of a cheap weak reference */ if (new_draw_buffer && new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - ctx->window_buffer = new_draw_buffer; + new_draw_buffer->context->window_buffer = new_draw_buffer; } /* Set the current framebuffer without checking if it's already the @@ -1428,6 +1409,16 @@ _cogl_framebuffer_compare_color_mask_state (CoglFramebuffer *a, return 0; } +static unsigned long +_cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a, + CoglFramebuffer *b) +{ + if (a->type != b->type) + return COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING; + else + return 0; +} + static unsigned long _cogl_framebuffer_compare (CoglFramebuffer *a, CoglFramebuffer *b, @@ -1472,6 +1463,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a, differences |= _cogl_framebuffer_compare_color_mask_state (a, b); break; + case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: + differences |= + _cogl_framebuffer_compare_front_face_winding_state (a, b); + break; default: g_warn_if_reached (); } @@ -1565,6 +1560,38 @@ _cogl_framebuffer_flush_color_mask_state (CoglFramebuffer *framebuffer) context->current_pipeline_age--; } +static void +_cogl_framebuffer_flush_front_face_winding_state (CoglFramebuffer *framebuffer) +{ + CoglContext *context = framebuffer->context; + CoglPipelineCullFaceMode mode; + + /* NB: The face winding state is actually owned by the current + * CoglPipeline. + * + * If we don't have a current pipeline then we can just assume that + * when we later do flush a pipeline we will check the current + * framebuffer to know how to setup the winding */ + if (!context->current_pipeline) + return; + + mode = cogl_pipeline_get_cull_face_mode (context->current_pipeline); + + /* If the current CoglPipeline has a culling mode that doesn't care + * about the winding we can avoid forcing an update of the state and + * bail out. */ + if (mode == COGL_PIPELINE_CULL_FACE_MODE_NONE || + mode == COGL_PIPELINE_CULL_FACE_MODE_BOTH) + return; + + /* Since the winding state is really owned by the current pipeline + * the way we "flush" an updated winding is to dirty the pipeline + * state... */ + context->current_pipeline_changes_since_flush |= + COGL_PIPELINE_STATE_CULL_FACE; + context->current_pipeline_age--; +} + void _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, CoglFramebuffer *read_buffer, @@ -1668,6 +1695,9 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK: _cogl_framebuffer_flush_color_mask_state (draw_buffer); break; + case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: + _cogl_framebuffer_flush_front_face_winding_state (draw_buffer); + break; default: g_warn_if_reached (); }