framebuffer: don't reference default fb in _clear apis
Some of the functions we were calling in cogl_framebuffer_clear[4f] were referring to the current framebuffer, which would result in a crash if nothing had been pushed before trying to explicitly clear a given framebuffer. Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
parent
19d12e65e5
commit
f7b1bab1ad
@ -67,14 +67,14 @@ project_vertex (const CoglMatrix *modelview_projection,
|
||||
}
|
||||
|
||||
static void
|
||||
set_clip_plane (GLint plane_num,
|
||||
set_clip_plane (CoglFramebuffer *framebuffer,
|
||||
GLint plane_num,
|
||||
const float *vertex_a,
|
||||
const float *vertex_b)
|
||||
{
|
||||
GLfloat planef[4];
|
||||
double planed[4];
|
||||
GLfloat angle;
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
CoglMatrixStack *projection_stack =
|
||||
@ -135,12 +135,12 @@ set_clip_plane (GLint plane_num,
|
||||
}
|
||||
|
||||
static void
|
||||
set_clip_planes (float x_1,
|
||||
set_clip_planes (CoglFramebuffer *framebuffer,
|
||||
float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
CoglMatrix modelview_matrix;
|
||||
@ -179,29 +179,29 @@ set_clip_planes (float x_1,
|
||||
if (signed_area > 0.0f)
|
||||
{
|
||||
/* counter-clockwise */
|
||||
set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_bl);
|
||||
set_clip_plane (GL_CLIP_PLANE1, vertex_bl, vertex_br);
|
||||
set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_tr);
|
||||
set_clip_plane (GL_CLIP_PLANE3, vertex_tr, vertex_tl);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE0, vertex_tl, vertex_bl);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE1, vertex_bl, vertex_br);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE2, vertex_br, vertex_tr);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE3, vertex_tr, vertex_tl);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* clockwise */
|
||||
set_clip_plane (GL_CLIP_PLANE0, vertex_tl, vertex_tr);
|
||||
set_clip_plane (GL_CLIP_PLANE1, vertex_tr, vertex_br);
|
||||
set_clip_plane (GL_CLIP_PLANE2, vertex_br, vertex_bl);
|
||||
set_clip_plane (GL_CLIP_PLANE3, vertex_bl, vertex_tl);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE0, vertex_tl, vertex_tr);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE1, vertex_tr, vertex_br);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE2, vertex_br, vertex_bl);
|
||||
set_clip_plane (framebuffer, GL_CLIP_PLANE3, vertex_bl, vertex_tl);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_stencil_clip_rectangle (float x_1,
|
||||
add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
|
||||
float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2,
|
||||
gboolean first)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
CoglMatrixStack *projection_stack =
|
||||
@ -584,7 +584,8 @@ _cogl_clip_stack_get_bounds (CoglClipStack *stack,
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
_cogl_clip_stack_flush (CoglClipStack *stack,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
int has_clip_planes;
|
||||
gboolean using_clip_planes = FALSE;
|
||||
@ -613,7 +614,7 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
ctx->current_clip_stack = _cogl_clip_stack_ref (stack);
|
||||
|
||||
modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (cogl_get_draw_framebuffer ());
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
|
||||
has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
|
||||
|
||||
@ -644,8 +645,6 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0;
|
||||
else
|
||||
{
|
||||
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
|
||||
|
||||
/* We store the entry coordinates in Cogl coordinate space
|
||||
* but OpenGL requires the window origin to be the bottom
|
||||
* left so we may need to convert the incoming coordinates.
|
||||
@ -714,7 +713,8 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
{
|
||||
COGL_NOTE (CLIPPING, "Adding clip planes clip for rectangle");
|
||||
|
||||
set_clip_planes (rect->x0,
|
||||
set_clip_planes (framebuffer,
|
||||
rect->x0,
|
||||
rect->y0,
|
||||
rect->x1,
|
||||
rect->y1);
|
||||
@ -726,7 +726,8 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
|
||||
{
|
||||
COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle");
|
||||
|
||||
add_stencil_clip_rectangle (rect->x0,
|
||||
add_stencil_clip_rectangle (framebuffer,
|
||||
rect->x0,
|
||||
rect->y0,
|
||||
rect->x1,
|
||||
rect->y1,
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "cogl2-path.h"
|
||||
#include "cogl-matrix.h"
|
||||
#include "cogl.h"
|
||||
|
||||
/* The clip stack works like a GSList where only a pointer to the top
|
||||
of the stack is stored. The empty clip stack is represented simply
|
||||
@ -178,7 +179,8 @@ _cogl_clip_stack_get_bounds (CoglClipStack *stack,
|
||||
int *scissor_y1);
|
||||
|
||||
void
|
||||
_cogl_clip_stack_flush (CoglClipStack *stack);
|
||||
_cogl_clip_stack_flush (CoglClipStack *stack,
|
||||
CoglFramebuffer *framebuffer);
|
||||
|
||||
CoglClipStack *
|
||||
_cogl_clip_stack_ref (CoglClipStack *stack);
|
||||
|
@ -41,7 +41,8 @@ void
|
||||
_cogl_clip_state_destroy (CoglClipState *state);
|
||||
|
||||
void
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state);
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state,
|
||||
CoglFramebuffer *framebuffer);
|
||||
|
||||
CoglClipStack *
|
||||
_cogl_clip_state_get_stack (CoglClipState *clip_state);
|
||||
|
@ -146,11 +146,13 @@ cogl_clip_pop (void)
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state)
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
/* Flush the topmost stack. The clip stack code will bail out early
|
||||
if this is already flushed */
|
||||
_cogl_clip_stack_flush (clip_state->stacks->data);
|
||||
_cogl_clip_stack_flush (clip_state->stacks->data,
|
||||
framebuffer);
|
||||
}
|
||||
|
||||
/* XXX: This should never have been made public API! */
|
||||
@ -166,7 +168,7 @@ cogl_clip_ensure (void)
|
||||
application however so it makes sense to flush the journal
|
||||
here */
|
||||
_cogl_framebuffer_flush_journal (framebuffer);
|
||||
_cogl_clip_state_flush (clip_state);
|
||||
_cogl_clip_state_flush (clip_state, framebuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -146,11 +146,12 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
|
||||
int width, int height);
|
||||
|
||||
void
|
||||
_cogl_clear4f (unsigned long buffers,
|
||||
float red,
|
||||
float green,
|
||||
float blue,
|
||||
float alpha);
|
||||
_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
|
||||
unsigned long buffers,
|
||||
float red,
|
||||
float green,
|
||||
float blue,
|
||||
float alpha);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_clear (CoglFramebuffer *framebuffer,
|
||||
|
@ -228,11 +228,12 @@ _cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer)
|
||||
* 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)
|
||||
_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
|
||||
unsigned long buffers,
|
||||
float red,
|
||||
float green,
|
||||
float blue,
|
||||
float alpha)
|
||||
{
|
||||
GLbitfield gl_buffers = 0;
|
||||
|
||||
@ -240,15 +241,12 @@ _cogl_clear4f (unsigned long buffers,
|
||||
|
||||
if (buffers & COGL_BUFFER_BIT_COLOR)
|
||||
{
|
||||
CoglFramebuffer *draw_framebuffer;
|
||||
|
||||
GE( ctx, glClearColor (red, green, blue, alpha) );
|
||||
gl_buffers |= GL_COLOR_BUFFER_BIT;
|
||||
|
||||
draw_framebuffer = cogl_get_draw_framebuffer ();
|
||||
if (ctx->current_gl_color_mask != draw_framebuffer->color_mask)
|
||||
if (ctx->current_gl_color_mask != framebuffer->color_mask)
|
||||
{
|
||||
CoglColorMask color_mask = draw_framebuffer->color_mask;
|
||||
CoglColorMask color_mask = framebuffer->color_mask;
|
||||
GE( ctx, glColorMask (!!(color_mask & COGL_COLOR_MASK_RED),
|
||||
!!(color_mask & COGL_COLOR_MASK_GREEN),
|
||||
!!(color_mask & COGL_COLOR_MASK_BLUE),
|
||||
@ -396,7 +394,8 @@ _cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (framebuffer, framebuffer, 0);
|
||||
|
||||
_cogl_clear4f (buffers, red, green, blue, alpha);;
|
||||
_cogl_framebuffer_clear_without_flush4f (framebuffer, 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
|
||||
@ -1463,7 +1462,8 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
|
||||
* matrices so we must do it before flushing the matrices...
|
||||
*/
|
||||
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE))
|
||||
_cogl_clip_state_flush (&draw_buffer->clip_state);
|
||||
_cogl_clip_state_flush (&draw_buffer->clip_state,
|
||||
draw_buffer);
|
||||
|
||||
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW))
|
||||
_cogl_matrix_stack_flush_to_gl (draw_buffer->modelview_stack,
|
||||
@ -1651,7 +1651,7 @@ _cogl_blit_framebuffer (unsigned int src_x,
|
||||
by the scissor and we want to hide this feature for the Cogl API
|
||||
because it's not obvious to an app how the clip state will affect
|
||||
the scissor */
|
||||
_cogl_clip_stack_flush (NULL);
|
||||
_cogl_clip_stack_flush (NULL, draw_buffer);
|
||||
|
||||
ctx->glBlitFramebuffer (src_x, src_y,
|
||||
src_x + width, src_y + height,
|
||||
|
@ -95,6 +95,8 @@ typedef struct _CoglJournalFlushState
|
||||
{
|
||||
CoglJournal *journal;
|
||||
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
CoglAttributeBuffer *attribute_buffer;
|
||||
GArray *attributes;
|
||||
int current_attribute;
|
||||
@ -705,7 +707,7 @@ _cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start,
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING)))
|
||||
g_print ("BATCHING: clip stack batch len = %d\n", batch_len);
|
||||
|
||||
_cogl_clip_stack_flush (batch_start->clip_stack);
|
||||
_cogl_clip_stack_flush (batch_start->clip_stack, state->framebuffer);
|
||||
|
||||
_cogl_matrix_stack_push (state->modelview_stack);
|
||||
|
||||
@ -1352,6 +1354,7 @@ _cogl_journal_flush (CoglJournal *journal,
|
||||
* that the timer isn't started recursively. */
|
||||
COGL_TIMER_START (_cogl_uprof_context, flush_timer);
|
||||
|
||||
state.framebuffer = framebuffer;
|
||||
cogl_push_framebuffer (framebuffer);
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING)))
|
||||
|
@ -401,9 +401,11 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
will have set up a scissor for the minimum bounding box of
|
||||
all of the clips. That box will likely mean that this
|
||||
_cogl_clear won't need to clear the entire
|
||||
buffer. _cogl_clear4f is used instead of cogl_clear because
|
||||
it won't try to flush the journal */
|
||||
_cogl_clear4f (COGL_BUFFER_BIT_STENCIL, 0, 0, 0, 0);
|
||||
buffer. _cogl_framebuffer_clear_without_flush4f is used instead
|
||||
of cogl_clear because it won't try to flush the journal */
|
||||
_cogl_framebuffer_clear_without_flush4f (framebuffer,
|
||||
COGL_BUFFER_BIT_STENCIL,
|
||||
0, 0, 0, 0);
|
||||
else
|
||||
{
|
||||
/* Just clear the bounding box */
|
||||
|
Loading…
Reference in New Issue
Block a user