mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
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:
parent
5be5529269
commit
e3de0be678
@ -603,16 +603,19 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
|
||||
validate_layer_cb,
|
||||
&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
|
||||
* always be done first when preparing to draw. We need to do this
|
||||
* before setting up the array pointers because setting up the clip
|
||||
* stack can cause some drawing which would change the array
|
||||
* pointers. */
|
||||
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
{
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_ALL);
|
||||
}
|
||||
|
||||
/* In cogl_read_pixels we have a fast-path when reading a single
|
||||
* pixel and the scene is just comprised of simple rectangles still
|
||||
|
@ -82,7 +82,8 @@ struct _CoglDriverVtable
|
||||
(* offscreen_free) (CoglOffscreen *offscreen);
|
||||
|
||||
void
|
||||
(* framebuffer_flush_state) (CoglFramebuffer *draw_buffer,
|
||||
(* flush_framebuffer_state) (CoglContext *context,
|
||||
CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state);
|
||||
|
||||
|
@ -189,7 +189,8 @@ void
|
||||
_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
|
||||
cogl_context_flush_framebuffer_state (CoglContext *context,
|
||||
CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state);
|
||||
|
||||
|
@ -477,6 +477,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
{
|
||||
CoglFramebufferPrivate *priv =
|
||||
cogl_framebuffer_get_instance_private (framebuffer);
|
||||
CoglContext *context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer);
|
||||
gboolean had_depth_and_color_buffer_bits;
|
||||
int scissor_x0;
|
||||
@ -580,10 +581,11 @@ cogl_framebuffer_clear4f (CoglFramebuffer *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
|
||||
* 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_clear_without_flush4f (framebuffer, buffers,
|
||||
@ -1074,13 +1076,13 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
|
||||
cogl_context_flush_framebuffer_state (CoglContext *ctx,
|
||||
CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state)
|
||||
{
|
||||
CoglContext *ctx = cogl_framebuffer_get_context (draw_buffer);
|
||||
|
||||
ctx->driver_vtable->framebuffer_flush_state (draw_buffer,
|
||||
ctx->driver_vtable->flush_framebuffer_state (ctx,
|
||||
draw_buffer,
|
||||
read_buffer,
|
||||
state);
|
||||
}
|
||||
@ -1593,10 +1595,11 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
|
||||
|
||||
/* Make sure the current framebuffers are bound. We explicitly avoid
|
||||
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,
|
||||
COGL_FRAMEBUFFER_STATE_ALL &
|
||||
~COGL_FRAMEBUFFER_STATE_CLIP);
|
||||
(COGL_FRAMEBUFFER_STATE_ALL &
|
||||
~COGL_FRAMEBUFFER_STATE_CLIP));
|
||||
|
||||
/* Flush any empty clip stack because glBlitFramebuffer is affected
|
||||
by the scissor and we want to hide this feature for the Cogl API
|
||||
|
@ -1051,7 +1051,8 @@ _cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start,
|
||||
cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled);
|
||||
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER;
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
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_set_viewport4fv (framebuffer, batch_start->viewport);
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_VIEWPORT);
|
||||
|
||||
@ -1402,7 +1404,8 @@ _cogl_journal_flush (CoglJournal *journal)
|
||||
|
||||
/* NB: the journal deals with flushing the viewport, the modelview
|
||||
* stack and clip state manually */
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_ALL &
|
||||
~(COGL_FRAMEBUFFER_STATE_DITHER |
|
||||
|
@ -52,11 +52,6 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
|
||||
void
|
||||
_cogl_offscreen_gl_free (CoglOffscreen *offscreen);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
|
||||
unsigned long buffers,
|
||||
@ -111,6 +106,10 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
|
||||
CoglBitmap *bitmap,
|
||||
GError **error);
|
||||
|
||||
void
|
||||
cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer,
|
||||
unsigned long differences);
|
||||
|
||||
#endif /* __COGL_FRAMEBUFFER_GL_PRIVATE_H__ */
|
||||
|
||||
|
||||
|
@ -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
|
||||
_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 *
|
||||
try_creating_renderbuffers (CoglContext *ctx,
|
||||
int width,
|
||||
@ -902,6 +825,12 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
|
||||
GE (ctx, glClear (gl_buffers));
|
||||
}
|
||||
|
||||
CoglGlFramebuffer *
|
||||
cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
return ensure_gl_framebuffer (framebuffer);
|
||||
}
|
||||
|
||||
static CoglGlFramebuffer *
|
||||
ensure_gl_framebuffer (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
@ -935,7 +864,8 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
|
||||
|
||||
cogl_framebuffer_allocate (framebuffer, NULL);
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
|
||||
@ -1072,7 +1002,8 @@ _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
|
||||
attachments[i++] = GL_STENCIL_ATTACHMENT;
|
||||
}
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
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);
|
||||
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
|
||||
|
@ -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
|
||||
* flush the clip state here since we aren't going to draw to the
|
||||
* framebuffer. */
|
||||
_cogl_framebuffer_flush_state (ctx->current_draw_buffer,
|
||||
cogl_context_flush_framebuffer_state (ctx,
|
||||
ctx->current_draw_buffer,
|
||||
src_fb,
|
||||
COGL_FRAMEBUFFER_STATE_ALL &
|
||||
~COGL_FRAMEBUFFER_STATE_CLIP);
|
||||
(COGL_FRAMEBUFFER_STATE_ALL &
|
||||
~COGL_FRAMEBUFFER_STATE_CLIP));
|
||||
|
||||
_cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
|
||||
tex_2d->gl_texture);
|
||||
|
@ -94,6 +94,12 @@ _cogl_driver_gl_context_init (CoglContext *context);
|
||||
void
|
||||
_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
|
||||
_cogl_gl_util_get_error (CoglContext *ctx);
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "cogl-types.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-util-gl-private.h"
|
||||
|
||||
@ -130,6 +131,97 @@ _cogl_driver_gl_context_deinit (CoglContext *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
|
||||
_cogl_gl_util_get_error (CoglContext *ctx)
|
||||
{
|
||||
|
@ -571,7 +571,7 @@ _cogl_driver_gl =
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_gl_allocate,
|
||||
_cogl_offscreen_gl_free,
|
||||
_cogl_framebuffer_gl_flush_state,
|
||||
_cogl_driver_gl_flush_framebuffer_state,
|
||||
_cogl_framebuffer_gl_clear,
|
||||
_cogl_framebuffer_gl_query_bits,
|
||||
_cogl_framebuffer_gl_finish,
|
||||
|
@ -459,7 +459,7 @@ _cogl_driver_gles =
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_gl_allocate,
|
||||
_cogl_offscreen_gl_free,
|
||||
_cogl_framebuffer_gl_flush_state,
|
||||
_cogl_driver_gl_flush_framebuffer_state,
|
||||
_cogl_framebuffer_gl_clear,
|
||||
_cogl_framebuffer_gl_query_bits,
|
||||
_cogl_framebuffer_gl_finish,
|
||||
|
@ -67,6 +67,14 @@ _cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx,
|
||||
CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state)
|
||||
{
|
||||
}
|
||||
|
||||
const CoglDriverVtable
|
||||
_cogl_driver_nop =
|
||||
{
|
||||
@ -79,7 +87,7 @@ _cogl_driver_nop =
|
||||
_cogl_driver_update_features,
|
||||
_cogl_offscreen_nop_allocate,
|
||||
_cogl_offscreen_nop_free,
|
||||
_cogl_framebuffer_nop_flush_state,
|
||||
_cogl_driver_nop_flush_framebuffer_state,
|
||||
_cogl_framebuffer_nop_clear,
|
||||
_cogl_framebuffer_nop_query_bits,
|
||||
_cogl_framebuffer_nop_finish,
|
||||
|
@ -45,11 +45,6 @@ _cogl_offscreen_nop_allocate (CoglOffscreen *offscreen,
|
||||
void
|
||||
_cogl_offscreen_nop_free (CoglOffscreen *offscreen);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
|
||||
unsigned long buffers,
|
||||
|
@ -35,13 +35,6 @@
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
_cogl_framebuffer_nop_flush_state (CoglFramebuffer *draw_buffer,
|
||||
CoglFramebuffer *read_buffer,
|
||||
CoglFramebufferState state)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_offscreen_nop_allocate (CoglOffscreen *offscreen,
|
||||
CoglOffscreenFlags flags,
|
||||
|
@ -240,7 +240,8 @@ _cogl_winsys_onscreen_egl_swap_region (CoglOnscreen *onscreen,
|
||||
swap must be bound to the current context. It looks like Mesa
|
||||
also validates that this is the case for eglSwapBuffersRegion so
|
||||
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_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
|
||||
and just returns an error if this is not the case so we can't
|
||||
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_STATE_BIND);
|
||||
|
||||
|
@ -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,
|
||||
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
|
||||
* glXMakeContextCurrent for the drawable we are swapping then
|
||||
* we get a BadDrawable error from the X server. */
|
||||
_cogl_framebuffer_flush_state (framebuffer,
|
||||
cogl_context_flush_framebuffer_state (context,
|
||||
framebuffer,
|
||||
framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_BIND);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user