mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
framebuffer: Move clear code to cogl-framebuffer.c
This moves the implementation of cogl_clear into cogl-framebuffer.c as two new internal functions _cogl_framebuffer_clear and _cogl_framebuffer_clear4f. It's not clear if this is what the API will look like as we make more of the CoglFramebuffer API public due to the limitations of using flags to identify buffers when framebuffers may contain any number of ancillary buffers but conceptually it makes some sense to tie the operation of clearing a color buffer to a framebuffer. The short term intention is to enable tracking the current clear color as a property of the framebuffer as part of an optimization for reading back single pixels when the geometry is simple enough that we can compute the result quickly on the CPU. (If the point doesn't intersect any geometry we'll need to return the last clear color.)
This commit is contained in:
parent
34ce527dca
commit
a4e50b5ea5
@ -87,6 +87,26 @@ typedef struct _CoglOnscreen
|
|||||||
void
|
void
|
||||||
_cogl_framebuffer_state_init (void);
|
_cogl_framebuffer_state_init (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clear4f (unsigned long buffers,
|
||||||
|
float red,
|
||||||
|
float green,
|
||||||
|
float blue,
|
||||||
|
float alpha);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_framebuffer_clear (CoglFramebuffer *framebuffer,
|
||||||
|
unsigned long buffers,
|
||||||
|
const CoglColor *color);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||||
|
unsigned long buffers,
|
||||||
|
float red,
|
||||||
|
float green,
|
||||||
|
float blue,
|
||||||
|
float alpha);
|
||||||
|
|
||||||
int
|
int
|
||||||
_cogl_framebuffer_get_width (CoglFramebuffer *framebuffer);
|
_cogl_framebuffer_get_width (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
@ -169,6 +169,109 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
|
|||||||
framebuffer->projection_stack = NULL;
|
framebuffer->projection_stack = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This version of cogl_clear can be used internally as an alternative
|
||||||
|
* to avoid flushing the journal or the framebuffer state. This is
|
||||||
|
* needed when doing operations that may be called whiling flushing
|
||||||
|
* the journal */
|
||||||
|
void
|
||||||
|
_cogl_clear4f (unsigned long buffers,
|
||||||
|
float red,
|
||||||
|
float green,
|
||||||
|
float blue,
|
||||||
|
float alpha)
|
||||||
|
{
|
||||||
|
GLbitfield gl_buffers = 0;
|
||||||
|
|
||||||
|
if (buffers & COGL_BUFFER_BIT_COLOR)
|
||||||
|
{
|
||||||
|
GE( glClearColor (red, green, blue, alpha) );
|
||||||
|
gl_buffers |= GL_COLOR_BUFFER_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffers & COGL_BUFFER_BIT_DEPTH)
|
||||||
|
gl_buffers |= GL_DEPTH_BUFFER_BIT;
|
||||||
|
|
||||||
|
if (buffers & COGL_BUFFER_BIT_STENCIL)
|
||||||
|
gl_buffers |= GL_STENCIL_BUFFER_BIT;
|
||||||
|
|
||||||
|
if (!gl_buffers)
|
||||||
|
{
|
||||||
|
static gboolean shown = FALSE;
|
||||||
|
|
||||||
|
if (!shown)
|
||||||
|
{
|
||||||
|
g_warning ("You should specify at least one auxiliary buffer "
|
||||||
|
"when calling cogl_clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE (glClear (gl_buffers));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||||
|
unsigned long buffers,
|
||||||
|
float red,
|
||||||
|
float green,
|
||||||
|
float blue,
|
||||||
|
float alpha)
|
||||||
|
{
|
||||||
|
COGL_NOTE (DRAW, "Clear begin");
|
||||||
|
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
/* NB: _cogl_framebuffer_flush_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, 0);
|
||||||
|
|
||||||
|
_cogl_clear4f (buffers, red, green, blue, alpha);;
|
||||||
|
|
||||||
|
/* This is a debugging variable used to visually display the quad
|
||||||
|
* batches from the journal. It is reset here to increase the
|
||||||
|
* chances of getting the same colours for each frame during an
|
||||||
|
* animation */
|
||||||
|
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_RECTANGLES) &&
|
||||||
|
buffers & COGL_BUFFER_BIT_COLOR)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
|
||||||
|
ctxt->journal_rectangles_color = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
COGL_NOTE (DRAW, "Clear end");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: We'll need to consider if this API is a good approach for the
|
||||||
|
* planned, public, CoglFramebuffer API. A framebuffer may have
|
||||||
|
* multiple color buffers associated with it and the user may want to
|
||||||
|
* only clear a subset of those buffers. Flags aren't a great
|
||||||
|
* mechanism for handling this, but I don't think it would be very
|
||||||
|
* convenient if you had to explicitly enumerate the individual
|
||||||
|
* ancillary buffers to clear them.
|
||||||
|
*
|
||||||
|
* My current expectation is that we'll keep this flag based API but
|
||||||
|
* also add a way to enumerate the individual color buffers for
|
||||||
|
* clearing individually.
|
||||||
|
*
|
||||||
|
* Note: the 'buffers' and 'color' arguments were switched around on
|
||||||
|
* purpose compared to the original cogl_clear API since it was odd
|
||||||
|
* that you would be expected to specify a color before even
|
||||||
|
* necessarily choosing to clear the color buffer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_framebuffer_clear (CoglFramebuffer *framebuffer,
|
||||||
|
unsigned long buffers,
|
||||||
|
const CoglColor *color)
|
||||||
|
{
|
||||||
|
_cogl_framebuffer_clear4f (framebuffer, buffers,
|
||||||
|
cogl_color_get_red_float (color),
|
||||||
|
cogl_color_get_green_float (color),
|
||||||
|
cogl_color_get_blue_float (color),
|
||||||
|
cogl_color_get_alpha_float (color));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_cogl_framebuffer_get_width (CoglFramebuffer *framebuffer)
|
_cogl_framebuffer_get_width (CoglFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
|
66
cogl/cogl.c
66
cogl/cogl.c
@ -46,6 +46,7 @@
|
|||||||
#include "cogl-texture-private.h"
|
#include "cogl-texture-private.h"
|
||||||
#include "cogl-texture-driver.h"
|
#include "cogl-texture-driver.h"
|
||||||
#include "cogl-vertex-attribute-private.h"
|
#include "cogl-vertex-attribute-private.h"
|
||||||
|
#include "cogl-framebuffer-private.h"
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GL
|
#ifdef HAVE_COGL_GL
|
||||||
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
|
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
|
||||||
@ -145,71 +146,12 @@ cogl_check_extension (const char *name, const char *ext)
|
|||||||
return _cogl_check_extension (name, ext);
|
return _cogl_check_extension (name, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This version of cogl_clear can be used internally as an alternative
|
/* XXX: it's expected that we'll deprecated this with
|
||||||
to avoid flushing the journal or the framebuffer state. This is
|
* cogl_framebuffer_clear at some point. */
|
||||||
needed when doing operations that may be called whiling flushing
|
|
||||||
the journal */
|
|
||||||
void
|
|
||||||
_cogl_clear (const CoglColor *color, unsigned long buffers)
|
|
||||||
{
|
|
||||||
GLbitfield gl_buffers = 0;
|
|
||||||
|
|
||||||
if (buffers & COGL_BUFFER_BIT_COLOR)
|
|
||||||
{
|
|
||||||
GE( glClearColor (cogl_color_get_red_float (color),
|
|
||||||
cogl_color_get_green_float (color),
|
|
||||||
cogl_color_get_blue_float (color),
|
|
||||||
cogl_color_get_alpha_float (color)) );
|
|
||||||
gl_buffers |= GL_COLOR_BUFFER_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffers & COGL_BUFFER_BIT_DEPTH)
|
|
||||||
gl_buffers |= GL_DEPTH_BUFFER_BIT;
|
|
||||||
|
|
||||||
if (buffers & COGL_BUFFER_BIT_STENCIL)
|
|
||||||
gl_buffers |= GL_STENCIL_BUFFER_BIT;
|
|
||||||
|
|
||||||
if (!gl_buffers)
|
|
||||||
{
|
|
||||||
static gboolean shown = FALSE;
|
|
||||||
|
|
||||||
if (!shown)
|
|
||||||
{
|
|
||||||
g_warning ("You should specify at least one auxiliary buffer "
|
|
||||||
"when calling cogl_clear");
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GE (glClear (gl_buffers));
|
|
||||||
|
|
||||||
/* This is a debugging variable used to visually display the quad
|
|
||||||
batches from the journal. It is reset here to increase the
|
|
||||||
chances of getting the same colours for each frame during an
|
|
||||||
animation */
|
|
||||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_RECTANGLES))
|
|
||||||
{
|
|
||||||
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
|
|
||||||
ctxt->journal_rectangles_color = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_clear (const CoglColor *color, unsigned long buffers)
|
cogl_clear (const CoglColor *color, unsigned long buffers)
|
||||||
{
|
{
|
||||||
COGL_NOTE (DRAW, "Clear begin");
|
_cogl_framebuffer_clear (_cogl_get_framebuffer (), buffers, color);
|
||||||
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
/* NB: _cogl_framebuffer_flush_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 (_cogl_get_framebuffer (), 0);
|
|
||||||
|
|
||||||
_cogl_clear (color, buffers);;
|
|
||||||
|
|
||||||
COGL_NOTE (DRAW, "Clear end");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -396,9 +396,9 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
|||||||
will have set up a scissor for the minimum bounding box of
|
will have set up a scissor for the minimum bounding box of
|
||||||
all of the clips. That box will likely mean that this
|
all of the clips. That box will likely mean that this
|
||||||
_cogl_clear won't need to clear the entire
|
_cogl_clear won't need to clear the entire
|
||||||
buffer. _cogl_clear is used instead of cogl_clear because
|
buffer. _cogl_clear4f is used instead of cogl_clear because
|
||||||
it won't try to flush the journal */
|
it won't try to flush the journal */
|
||||||
_cogl_clear (NULL, COGL_BUFFER_BIT_STENCIL);
|
_cogl_clear4f (COGL_BUFFER_BIT_STENCIL, 0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Just clear the bounding box */
|
/* Just clear the bounding box */
|
||||||
|
Loading…
Reference in New Issue
Block a user