cogl: Move "flush framebuffers" under the context scope

It was namespaced as a CoglFramebuffer function, but was passed two
framebuffers, and operated on state kept in CoglContext. Move and rename
accordingly.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
This commit is contained in:
Jonas Ådahl 2020-10-19 17:42:43 +02:00 committed by Robert Mader
parent 5be5529269
commit e3de0be678
17 changed files with 248 additions and 207 deletions

View File

@ -603,16 +603,19 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
validate_layer_cb, validate_layer_cb,
&layers_state); &layers_state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should * as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this * always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip * before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array * stack can cause some drawing which would change the array
* pointers. */ * pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH)) if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (framebuffer, {
cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_ALL); COGL_FRAMEBUFFER_STATE_ALL);
}
/* In cogl_read_pixels we have a fast-path when reading a single /* In cogl_read_pixels we have a fast-path when reading a single
* pixel and the scene is just comprised of simple rectangles still * pixel and the scene is just comprised of simple rectangles still

View File

@ -82,7 +82,8 @@ struct _CoglDriverVtable
(* offscreen_free) (CoglOffscreen *offscreen); (* offscreen_free) (CoglOffscreen *offscreen);
void void
(* framebuffer_flush_state) (CoglFramebuffer *draw_buffer, (* flush_framebuffer_state) (CoglContext *context,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer, CoglFramebuffer *read_buffer,
CoglFramebufferState state); CoglFramebufferState state);

View File

@ -189,7 +189,8 @@ void
_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer); _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer);
void void
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, cogl_context_flush_framebuffer_state (CoglContext *context,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer, CoglFramebuffer *read_buffer,
CoglFramebufferState state); CoglFramebufferState state);

View File

@ -477,6 +477,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
{ {
CoglFramebufferPrivate *priv = CoglFramebufferPrivate *priv =
cogl_framebuffer_get_instance_private (framebuffer); cogl_framebuffer_get_instance_private (framebuffer);
CoglContext *context = cogl_framebuffer_get_context (framebuffer);
CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer);
gboolean had_depth_and_color_buffer_bits; gboolean had_depth_and_color_buffer_bits;
int scissor_x0; int scissor_x0;
@ -580,10 +581,11 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
_cogl_framebuffer_flush_journal (framebuffer); _cogl_framebuffer_flush_journal (framebuffer);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should * as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */ * always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (framebuffer, framebuffer, cogl_context_flush_framebuffer_state (context,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_ALL); COGL_FRAMEBUFFER_STATE_ALL);
_cogl_framebuffer_clear_without_flush4f (framebuffer, buffers, _cogl_framebuffer_clear_without_flush4f (framebuffer, buffers,
@ -1074,13 +1076,13 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
} }
void void
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer, cogl_context_flush_framebuffer_state (CoglContext *ctx,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer, CoglFramebuffer *read_buffer,
CoglFramebufferState state) CoglFramebufferState state)
{ {
CoglContext *ctx = cogl_framebuffer_get_context (draw_buffer); ctx->driver_vtable->flush_framebuffer_state (ctx,
draw_buffer,
ctx->driver_vtable->framebuffer_flush_state (draw_buffer,
read_buffer, read_buffer,
state); state);
} }
@ -1593,10 +1595,11 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
/* Make sure the current framebuffers are bound. We explicitly avoid /* Make sure the current framebuffers are bound. We explicitly avoid
flushing the clip state so we can bind our own empty state */ flushing the clip state so we can bind our own empty state */
_cogl_framebuffer_flush_state (dst, cogl_context_flush_framebuffer_state (ctx,
dst,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_ALL & (COGL_FRAMEBUFFER_STATE_ALL &
~COGL_FRAMEBUFFER_STATE_CLIP); ~COGL_FRAMEBUFFER_STATE_CLIP));
/* Flush any empty clip stack because glBlitFramebuffer is affected /* Flush any empty clip stack because glBlitFramebuffer is affected
by the scissor and we want to hide this feature for the Cogl API by the scissor and we want to hide this feature for the Cogl API

View File

@ -1051,7 +1051,8 @@ _cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start,
cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled); cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled);
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER; ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER;
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_DITHER); COGL_FRAMEBUFFER_STATE_DITHER);
@ -1097,7 +1098,8 @@ _cogl_journal_flush_viewport_and_entries (CoglJournalEntry *batch_start,
cogl_framebuffer_get_viewport4fv (framebuffer, current_viewport); cogl_framebuffer_get_viewport4fv (framebuffer, current_viewport);
cogl_framebuffer_set_viewport4fv (framebuffer, batch_start->viewport); cogl_framebuffer_set_viewport4fv (framebuffer, batch_start->viewport);
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_VIEWPORT); COGL_FRAMEBUFFER_STATE_VIEWPORT);
@ -1402,7 +1404,8 @@ _cogl_journal_flush (CoglJournal *journal)
/* NB: the journal deals with flushing the viewport, the modelview /* NB: the journal deals with flushing the viewport, the modelview
* stack and clip state manually */ * stack and clip state manually */
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_ALL & COGL_FRAMEBUFFER_STATE_ALL &
~(COGL_FRAMEBUFFER_STATE_DITHER | ~(COGL_FRAMEBUFFER_STATE_DITHER |

View File

@ -52,11 +52,6 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
void void
_cogl_offscreen_gl_free (CoglOffscreen *offscreen); _cogl_offscreen_gl_free (CoglOffscreen *offscreen);
void
_cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state);
void void
_cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer, _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
unsigned long buffers, unsigned long buffers,
@ -111,6 +106,10 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
CoglBitmap *bitmap, CoglBitmap *bitmap,
GError **error); GError **error);
void
cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer,
unsigned long differences);
#endif /* __COGL_FRAMEBUFFER_GL_PRIVATE_H__ */ #endif /* __COGL_FRAMEBUFFER_GL_PRIVATE_H__ */

View File

@ -303,6 +303,55 @@ _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
} }
} }
void
cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer,
unsigned long differences)
{
CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer);
CoglFramebuffer *framebuffer =
cogl_framebuffer_driver_get_framebuffer (driver);
int bit;
COGL_FLAGS_FOREACH_START (&differences, 1, bit)
{
/* XXX: We considered having an array of callbacks for each state index
* that we'd call here but decided that this way the compiler is more
* likely going to be able to in-line the flush functions and use the
* index to jump straight to the required code. */
switch (bit)
{
case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT:
_cogl_framebuffer_gl_flush_viewport_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_CLIP:
_cogl_framebuffer_gl_flush_clip_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_DITHER:
_cogl_framebuffer_gl_flush_dither_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW:
_cogl_framebuffer_gl_flush_modelview_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION:
_cogl_framebuffer_gl_flush_projection_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
_cogl_framebuffer_gl_flush_front_face_winding_state (framebuffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE:
/* Nothing to do for depth write state change; the state will always
* be taken into account when flushing the pipeline's depth state. */
break;
case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
_cogl_framebuffer_gl_flush_stereo_mode_state (framebuffer);
break;
default:
g_warn_if_reached ();
}
}
COGL_FLAGS_FOREACH_END;
}
void void
_cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target) _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
{ {
@ -354,132 +403,6 @@ _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
} }
} }
void
_cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state)
{
CoglContext *ctx = cogl_framebuffer_get_context (draw_buffer);
unsigned long differences;
int bit;
/* We can assume that any state that has changed for the current
* framebuffer is different to the currently flushed value. */
differences = ctx->current_draw_buffer_changes;
/* Any state of the current framebuffer that hasn't already been
* flushed is assumed to be unknown so we will always flush that
* state if asked. */
differences |= ~ctx->current_draw_buffer_state_flushed;
/* We only need to consider the state we've been asked to flush */
differences &= state;
if (ctx->current_draw_buffer != draw_buffer)
{
/* If the previous draw buffer is NULL then we'll assume
everything has changed. This can happen if a framebuffer is
destroyed while it is the last flushed draw buffer. In that
case the framebuffer destructor will set
ctx->current_draw_buffer to NULL */
if (ctx->current_draw_buffer == NULL)
differences |= state;
else
/* NB: we only need to compare the state we're being asked to flush
* and we don't need to compare the state we've already decided
* we will definitely flush... */
differences |= _cogl_framebuffer_compare (ctx->current_draw_buffer,
draw_buffer,
state & ~differences);
/* NB: we don't take a reference here, to avoid a circular
* reference. */
ctx->current_draw_buffer = draw_buffer;
ctx->current_draw_buffer_state_flushed = 0;
}
if (ctx->current_read_buffer != read_buffer &&
state & COGL_FRAMEBUFFER_STATE_BIND)
{
differences |= COGL_FRAMEBUFFER_STATE_BIND;
/* NB: we don't take a reference here, to avoid a circular
* reference. */
ctx->current_read_buffer = read_buffer;
}
if (!differences)
return;
/* Lazily ensure the framebuffers have been allocated */
if (G_UNLIKELY (!cogl_framebuffer_is_allocated (draw_buffer)))
cogl_framebuffer_allocate (draw_buffer, NULL);
if (G_UNLIKELY (!cogl_framebuffer_is_allocated (read_buffer)))
cogl_framebuffer_allocate (read_buffer, NULL);
/* We handle buffer binding separately since the method depends on whether
* we are binding the same buffer for read and write or not unlike all
* other state that only relates to the draw_buffer. */
if (differences & COGL_FRAMEBUFFER_STATE_BIND)
{
if (draw_buffer == read_buffer)
_cogl_framebuffer_gl_bind (draw_buffer, GL_FRAMEBUFFER);
else
{
/* NB: Currently we only take advantage of binding separate
* read/write buffers for framebuffer blit purposes. */
g_return_if_fail (cogl_has_feature
(ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER));
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
}
differences &= ~COGL_FRAMEBUFFER_STATE_BIND;
}
COGL_FLAGS_FOREACH_START (&differences, 1, bit)
{
/* XXX: We considered having an array of callbacks for each state index
* that we'd call here but decided that this way the compiler is more
* likely going to be able to in-line the flush functions and use the
* index to jump straight to the required code. */
switch (bit)
{
case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT:
_cogl_framebuffer_gl_flush_viewport_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_CLIP:
_cogl_framebuffer_gl_flush_clip_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_DITHER:
_cogl_framebuffer_gl_flush_dither_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW:
_cogl_framebuffer_gl_flush_modelview_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION:
_cogl_framebuffer_gl_flush_projection_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
_cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
break;
case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE:
/* Nothing to do for depth write state change; the state will always
* be taken into account when flushing the pipeline's depth state. */
break;
case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE:
_cogl_framebuffer_gl_flush_stereo_mode_state (draw_buffer);
break;
default:
g_warn_if_reached ();
}
}
COGL_FLAGS_FOREACH_END;
ctx->current_draw_buffer_state_flushed |= state;
ctx->current_draw_buffer_changes &= ~state;
}
static GList * static GList *
try_creating_renderbuffers (CoglContext *ctx, try_creating_renderbuffers (CoglContext *ctx,
int width, int width,
@ -902,6 +825,12 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
GE (ctx, glClear (gl_buffers)); GE (ctx, glClear (gl_buffers));
} }
CoglGlFramebuffer *
cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer)
{
return ensure_gl_framebuffer (framebuffer);
}
static CoglGlFramebuffer * static CoglGlFramebuffer *
ensure_gl_framebuffer (CoglFramebuffer *framebuffer) ensure_gl_framebuffer (CoglFramebuffer *framebuffer)
{ {
@ -935,7 +864,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
cogl_framebuffer_allocate (framebuffer, NULL); cogl_framebuffer_allocate (framebuffer, NULL);
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
@ -1072,7 +1002,8 @@ _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
attachments[i++] = GL_STENCIL_ATTACHMENT; attachments[i++] = GL_STENCIL_ATTACHMENT;
} }
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments)); GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments));
@ -1190,7 +1121,8 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (ctx,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);

View File

@ -499,10 +499,11 @@ _cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d,
/* Make sure the current framebuffers are bound, though we don't need to /* Make sure the current framebuffers are bound, though we don't need to
* flush the clip state here since we aren't going to draw to the * flush the clip state here since we aren't going to draw to the
* framebuffer. */ * framebuffer. */
_cogl_framebuffer_flush_state (ctx->current_draw_buffer, cogl_context_flush_framebuffer_state (ctx,
ctx->current_draw_buffer,
src_fb, src_fb,
COGL_FRAMEBUFFER_STATE_ALL & (COGL_FRAMEBUFFER_STATE_ALL &
~COGL_FRAMEBUFFER_STATE_CLIP); ~COGL_FRAMEBUFFER_STATE_CLIP));
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D, _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
tex_2d->gl_texture); tex_2d->gl_texture);

View File

@ -94,6 +94,12 @@ _cogl_driver_gl_context_init (CoglContext *context);
void void
_cogl_driver_gl_context_deinit (CoglContext *context); _cogl_driver_gl_context_deinit (CoglContext *context);
void
_cogl_driver_gl_flush_framebuffer_state (CoglContext *context,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state);
GLenum GLenum
_cogl_gl_util_get_error (CoglContext *ctx); _cogl_gl_util_get_error (CoglContext *ctx);

View File

@ -34,6 +34,7 @@
#include "cogl-types.h" #include "cogl-types.h"
#include "cogl-context-private.h" #include "cogl-context-private.h"
#include "driver/gl/cogl-framebuffer-gl-private.h"
#include "driver/gl/cogl-pipeline-opengl-private.h" #include "driver/gl/cogl-pipeline-opengl-private.h"
#include "driver/gl/cogl-util-gl-private.h" #include "driver/gl/cogl-util-gl-private.h"
@ -130,6 +131,97 @@ _cogl_driver_gl_context_deinit (CoglContext *context)
g_free (context->driver_context); g_free (context->driver_context);
} }
void
_cogl_driver_gl_flush_framebuffer_state (CoglContext *ctx,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state)
{
CoglGlFramebuffer *draw_gl_framebuffer;
unsigned long differences;
/* We can assume that any state that has changed for the current
* framebuffer is different to the currently flushed value. */
differences = ctx->current_draw_buffer_changes;
/* Any state of the current framebuffer that hasn't already been
* flushed is assumed to be unknown so we will always flush that
* state if asked. */
differences |= ~ctx->current_draw_buffer_state_flushed;
/* We only need to consider the state we've been asked to flush */
differences &= state;
if (ctx->current_draw_buffer != draw_buffer)
{
/* If the previous draw buffer is NULL then we'll assume
everything has changed. This can happen if a framebuffer is
destroyed while it is the last flushed draw buffer. In that
case the framebuffer destructor will set
ctx->current_draw_buffer to NULL */
if (ctx->current_draw_buffer == NULL)
differences |= state;
else
/* NB: we only need to compare the state we're being asked to flush
* and we don't need to compare the state we've already decided
* we will definitely flush... */
differences |= _cogl_framebuffer_compare (ctx->current_draw_buffer,
draw_buffer,
state & ~differences);
/* NB: we don't take a reference here, to avoid a circular
* reference. */
ctx->current_draw_buffer = draw_buffer;
ctx->current_draw_buffer_state_flushed = 0;
}
if (ctx->current_read_buffer != read_buffer &&
state & COGL_FRAMEBUFFER_STATE_BIND)
{
differences |= COGL_FRAMEBUFFER_STATE_BIND;
/* NB: we don't take a reference here, to avoid a circular
* reference. */
ctx->current_read_buffer = read_buffer;
}
if (!differences)
return;
/* Lazily ensure the framebuffers have been allocated */
if (G_UNLIKELY (!cogl_framebuffer_is_allocated (draw_buffer)))
cogl_framebuffer_allocate (draw_buffer, NULL);
if (G_UNLIKELY (!cogl_framebuffer_is_allocated (read_buffer)))
cogl_framebuffer_allocate (read_buffer, NULL);
/* We handle buffer binding separately since the method depends on whether
* we are binding the same buffer for read and write or not unlike all
* other state that only relates to the draw_buffer. */
if (differences & COGL_FRAMEBUFFER_STATE_BIND)
{
if (draw_buffer == read_buffer)
_cogl_framebuffer_gl_bind (draw_buffer, GL_FRAMEBUFFER);
else
{
/* NB: Currently we only take advantage of binding separate
* read/write buffers for framebuffer blit purposes. */
g_return_if_fail (cogl_has_feature
(ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER));
_cogl_framebuffer_gl_bind (draw_buffer, GL_DRAW_FRAMEBUFFER);
_cogl_framebuffer_gl_bind (read_buffer, GL_READ_FRAMEBUFFER);
}
differences &= ~COGL_FRAMEBUFFER_STATE_BIND;
}
draw_gl_framebuffer = cogl_gl_framebuffer_from_framebuffer (draw_buffer);
cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer,
differences);
ctx->current_draw_buffer_state_flushed |= state;
ctx->current_draw_buffer_changes &= ~state;
}
GLenum GLenum
_cogl_gl_util_get_error (CoglContext *ctx) _cogl_gl_util_get_error (CoglContext *ctx)
{ {

View File

@ -571,7 +571,7 @@ _cogl_driver_gl =
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_gl_allocate, _cogl_offscreen_gl_allocate,
_cogl_offscreen_gl_free, _cogl_offscreen_gl_free,
_cogl_framebuffer_gl_flush_state, _cogl_driver_gl_flush_framebuffer_state,
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,
_cogl_framebuffer_gl_finish, _cogl_framebuffer_gl_finish,

View File

@ -459,7 +459,7 @@ _cogl_driver_gles =
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_gl_allocate, _cogl_offscreen_gl_allocate,
_cogl_offscreen_gl_free, _cogl_offscreen_gl_free,
_cogl_framebuffer_gl_flush_state, _cogl_driver_gl_flush_framebuffer_state,
_cogl_framebuffer_gl_clear, _cogl_framebuffer_gl_clear,
_cogl_framebuffer_gl_query_bits, _cogl_framebuffer_gl_query_bits,
_cogl_framebuffer_gl_finish, _cogl_framebuffer_gl_finish,

View File

@ -67,6 +67,14 @@ _cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
return FALSE; return FALSE;
} }
static void
_cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx,
CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state)
{
}
const CoglDriverVtable const CoglDriverVtable
_cogl_driver_nop = _cogl_driver_nop =
{ {
@ -79,7 +87,7 @@ _cogl_driver_nop =
_cogl_driver_update_features, _cogl_driver_update_features,
_cogl_offscreen_nop_allocate, _cogl_offscreen_nop_allocate,
_cogl_offscreen_nop_free, _cogl_offscreen_nop_free,
_cogl_framebuffer_nop_flush_state, _cogl_driver_nop_flush_framebuffer_state,
_cogl_framebuffer_nop_clear, _cogl_framebuffer_nop_clear,
_cogl_framebuffer_nop_query_bits, _cogl_framebuffer_nop_query_bits,
_cogl_framebuffer_nop_finish, _cogl_framebuffer_nop_finish,

View File

@ -45,11 +45,6 @@ _cogl_offscreen_nop_allocate (CoglOffscreen *offscreen,
void void
_cogl_offscreen_nop_free (CoglOffscreen *offscreen); _cogl_offscreen_nop_free (CoglOffscreen *offscreen);
void
_cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state);
void void
_cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer, _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
unsigned long buffers, unsigned long buffers,

View File

@ -35,13 +35,6 @@
#include <glib.h> #include <glib.h>
#include <string.h> #include <string.h>
void
_cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferState state)
{
}
gboolean gboolean
_cogl_offscreen_nop_allocate (CoglOffscreen *offscreen, _cogl_offscreen_nop_allocate (CoglOffscreen *offscreen,
CoglOffscreenFlags flags, CoglOffscreenFlags flags,

View File

@ -240,7 +240,8 @@ _cogl_winsys_onscreen_egl_swap_region (CoglOnscreen *onscreen,
swap must be bound to the current context. It looks like Mesa swap must be bound to the current context. It looks like Mesa
also validates that this is the case for eglSwapBuffersRegion so also validates that this is the case for eglSwapBuffersRegion so
we must bind here too */ we must bind here too */
_cogl_framebuffer_flush_state (COGL_FRAMEBUFFER (onscreen), cogl_context_flush_framebuffer_state (context,
COGL_FRAMEBUFFER (onscreen),
COGL_FRAMEBUFFER (onscreen), COGL_FRAMEBUFFER (onscreen),
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
@ -274,7 +275,8 @@ _cogl_winsys_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
although it may change in future. Mesa explicitly checks for this although it may change in future. Mesa explicitly checks for this
and just returns an error if this is not the case so we can't and just returns an error if this is not the case so we can't
just pretend this isn't in the spec. */ just pretend this isn't in the spec. */
_cogl_framebuffer_flush_state (COGL_FRAMEBUFFER (onscreen), cogl_context_flush_framebuffer_state (context,
COGL_FRAMEBUFFER (onscreen),
COGL_FRAMEBUFFER (onscreen), COGL_FRAMEBUFFER (onscreen),
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);

View File

@ -721,7 +721,8 @@ _cogl_winsys_onscreen_glx_swap_region (CoglOnscreen *onscreen,
} }
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (context,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);
@ -891,7 +892,8 @@ _cogl_winsys_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen,
* the Intel drivers we have see that if we don't call * the Intel drivers we have see that if we don't call
* glXMakeContextCurrent for the drawable we are swapping then * glXMakeContextCurrent for the drawable we are swapping then
* we get a BadDrawable error from the X server. */ * we get a BadDrawable error from the X server. */
_cogl_framebuffer_flush_state (framebuffer, cogl_context_flush_framebuffer_state (context,
framebuffer,
framebuffer, framebuffer,
COGL_FRAMEBUFFER_STATE_BIND); COGL_FRAMEBUFFER_STATE_BIND);