Separate out CoglClipStackState from cogl-clip-stack.c
CoglClipStackState has now been renamed to CoglClipState and is moved to a separate file. CoglClipStack now just maintains a stack and doesn't worry about the rest of the state. CoglClipStack sill contains the code to flush the stack to GL.
This commit is contained in:
parent
07a76aacfb
commit
f6f375cb36
9 changed files with 520 additions and 347 deletions
|
@ -103,6 +103,8 @@ cogl_sources_c = \
|
||||||
$(srcdir)/cogl-bitmap-pixbuf.c \
|
$(srcdir)/cogl-bitmap-pixbuf.c \
|
||||||
$(srcdir)/cogl-clip-stack.h \
|
$(srcdir)/cogl-clip-stack.h \
|
||||||
$(srcdir)/cogl-clip-stack.c \
|
$(srcdir)/cogl-clip-stack.c \
|
||||||
|
$(srcdir)/cogl-clip-state.h \
|
||||||
|
$(srcdir)/cogl-clip-state.c \
|
||||||
$(srcdir)/cogl-feature-private.h \
|
$(srcdir)/cogl-feature-private.h \
|
||||||
$(srcdir)/cogl-feature-private.c \
|
$(srcdir)/cogl-feature-private.c \
|
||||||
$(srcdir)/cogl-fixed.c \
|
$(srcdir)/cogl-fixed.c \
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -40,8 +40,6 @@
|
||||||
#include "cogl-util.h"
|
#include "cogl-util.h"
|
||||||
#include "cogl-path-private.h"
|
#include "cogl-path-private.h"
|
||||||
|
|
||||||
typedef struct _CoglClipStack CoglClipStack;
|
|
||||||
|
|
||||||
typedef struct _CoglClipStackEntry CoglClipStackEntry;
|
typedef struct _CoglClipStackEntry CoglClipStackEntry;
|
||||||
typedef struct _CoglClipStackEntryRect CoglClipStackEntryRect;
|
typedef struct _CoglClipStackEntryRect CoglClipStackEntryRect;
|
||||||
typedef struct _CoglClipStackEntryWindowRect CoglClipStackEntryWindowRect;
|
typedef struct _CoglClipStackEntryWindowRect CoglClipStackEntryWindowRect;
|
||||||
|
@ -402,27 +400,16 @@ _cogl_clip_stack_push_entry (CoglClipStack *clip_stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_clip_push_window_rectangle (int x_offset,
|
_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack,
|
||||||
int y_offset,
|
int x_offset,
|
||||||
int width,
|
int y_offset,
|
||||||
int height)
|
int width,
|
||||||
|
int height)
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
CoglClipStack *stack;
|
|
||||||
CoglClipStackEntryWindowRect *entry;
|
CoglClipStackEntryWindowRect *entry;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
entry = _cogl_clip_stack_push_entry (stack,
|
entry = _cogl_clip_stack_push_entry (stack,
|
||||||
sizeof (CoglClipStackEntryWindowRect),
|
sizeof (CoglClipStackEntryWindowRect),
|
||||||
COGL_CLIP_STACK_WINDOW_RECT);
|
COGL_CLIP_STACK_WINDOW_RECT);
|
||||||
|
@ -431,137 +418,18 @@ cogl_clip_push_window_rectangle (int x_offset,
|
||||||
entry->x1 = x_offset + width;
|
entry->x1 = x_offset + width;
|
||||||
entry->y0 = y_offset;
|
entry->y0 = y_offset;
|
||||||
entry->y1 = y_offset + height;
|
entry->y1 = y_offset + height;
|
||||||
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: This is deprecated API */
|
|
||||||
void
|
void
|
||||||
cogl_clip_push_window_rect (float x_offset,
|
_cogl_clip_stack_push_rectangle (CoglClipStack *stack,
|
||||||
float y_offset,
|
float x_1,
|
||||||
float width,
|
float y_1,
|
||||||
float height)
|
|
||||||
{
|
|
||||||
cogl_clip_push_window_rectangle (x_offset, y_offset, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1)
|
|
||||||
* to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with
|
|
||||||
* (0,0) being top left. */
|
|
||||||
#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \
|
|
||||||
( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) )
|
|
||||||
/* Note: for Y we first flip all coordinates around the X axis while in
|
|
||||||
* normalized device coodinates */
|
|
||||||
#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \
|
|
||||||
( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) )
|
|
||||||
|
|
||||||
/* Transform a homogeneous vertex position from model space to Cogl
|
|
||||||
* window coordinates (with 0,0 being top left) */
|
|
||||||
static void
|
|
||||||
transform_point (CoglMatrix *matrix_mv,
|
|
||||||
CoglMatrix *matrix_p,
|
|
||||||
float *viewport,
|
|
||||||
float *x,
|
|
||||||
float *y)
|
|
||||||
{
|
|
||||||
float z = 0;
|
|
||||||
float w = 1;
|
|
||||||
|
|
||||||
/* Apply the modelview matrix transform */
|
|
||||||
cogl_matrix_transform_point (matrix_mv, x, y, &z, &w);
|
|
||||||
|
|
||||||
/* Apply the projection matrix transform */
|
|
||||||
cogl_matrix_transform_point (matrix_p, x, y, &z, &w);
|
|
||||||
|
|
||||||
/* Perform perspective division */
|
|
||||||
*x /= w;
|
|
||||||
*y /= w;
|
|
||||||
|
|
||||||
/* Apply viewport transform */
|
|
||||||
*x = VIEWPORT_TRANSFORM_X (*x, viewport[0], viewport[2]);
|
|
||||||
*y = VIEWPORT_TRANSFORM_Y (*y, viewport[1], viewport[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef VIEWPORT_SCALE_X
|
|
||||||
#undef VIEWPORT_SCALE_Y
|
|
||||||
|
|
||||||
/* Try to push a rectangle given in object coordinates as a rectangle in window
|
|
||||||
* coordinates instead of object coordinates */
|
|
||||||
gboolean
|
|
||||||
try_pushing_rect_as_window_rect (float x_1,
|
|
||||||
float y_1,
|
|
||||||
float x_2,
|
float x_2,
|
||||||
float y_2)
|
float y_2,
|
||||||
|
const CoglMatrix *modelview_matrix)
|
||||||
{
|
{
|
||||||
CoglMatrix matrix;
|
|
||||||
CoglMatrix matrix_p;
|
|
||||||
float v[4];
|
|
||||||
|
|
||||||
cogl_get_modelview_matrix (&matrix);
|
|
||||||
|
|
||||||
/* If the modelview meets these constraints then a transformed rectangle
|
|
||||||
* should still be a rectangle when it reaches screen coordinates.
|
|
||||||
*
|
|
||||||
* FIXME: we are are making certain assumptions about the projection
|
|
||||||
* matrix a.t.m and should really be looking at the combined modelview
|
|
||||||
* and projection matrix.
|
|
||||||
* FIXME: we don't consider rotations that are a multiple of 90 degrees
|
|
||||||
* which could be quite common.
|
|
||||||
*/
|
|
||||||
if (matrix.xy != 0 || matrix.xz != 0 ||
|
|
||||||
matrix.yx != 0 || matrix.yz != 0 ||
|
|
||||||
matrix.zx != 0 || matrix.zy != 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
cogl_get_projection_matrix (&matrix_p);
|
|
||||||
cogl_get_viewport (v);
|
|
||||||
|
|
||||||
transform_point (&matrix, &matrix_p, v, &x_1, &y_1);
|
|
||||||
transform_point (&matrix, &matrix_p, v, &x_2, &y_2);
|
|
||||||
|
|
||||||
/* Consider that the modelview matrix may flip the rectangle
|
|
||||||
* along the x or y axis... */
|
|
||||||
#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0)
|
|
||||||
if (x_1 > x_2)
|
|
||||||
SWAP (x_1, x_2);
|
|
||||||
if (y_1 > y_2)
|
|
||||||
SWAP (y_1, y_2);
|
|
||||||
#undef SWAP
|
|
||||||
|
|
||||||
cogl_clip_push_window_rectangle (COGL_UTIL_NEARBYINT (x_1),
|
|
||||||
COGL_UTIL_NEARBYINT (y_1),
|
|
||||||
COGL_UTIL_NEARBYINT (x_2 - x_1),
|
|
||||||
COGL_UTIL_NEARBYINT (y_2 - y_1));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cogl_clip_push_rectangle (float x_1,
|
|
||||||
float y_1,
|
|
||||||
float x_2,
|
|
||||||
float y_2)
|
|
||||||
{
|
|
||||||
CoglHandle framebuffer;
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
CoglClipStack *stack;
|
|
||||||
CoglClipStackEntryRect *entry;
|
CoglClipStackEntryRect *entry;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
/* Try and catch window space rectangles so we can redirect to
|
|
||||||
* cogl_clip_push_window_rect which will use scissoring. */
|
|
||||||
if (try_pushing_rect_as_window_rect (x_1, y_1, x_2, y_2))
|
|
||||||
return;
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
/* Make a new entry */
|
/* Make a new entry */
|
||||||
entry = _cogl_clip_stack_push_entry (stack,
|
entry = _cogl_clip_stack_push_entry (stack,
|
||||||
sizeof (CoglClipStackEntryRect),
|
sizeof (CoglClipStackEntryRect),
|
||||||
|
@ -572,60 +440,23 @@ cogl_clip_push_rectangle (float x_1,
|
||||||
entry->x1 = x_2;
|
entry->x1 = x_2;
|
||||||
entry->y1 = y_2;
|
entry->y1 = y_2;
|
||||||
|
|
||||||
cogl_get_modelview_matrix (&entry->matrix);
|
entry->matrix = *modelview_matrix;
|
||||||
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: Deprecated API */
|
|
||||||
void
|
|
||||||
cogl_clip_push (float x_offset,
|
|
||||||
float y_offset,
|
|
||||||
float width,
|
|
||||||
float height)
|
|
||||||
{
|
|
||||||
cogl_clip_push_rectangle (x_offset,
|
|
||||||
y_offset,
|
|
||||||
x_offset + width,
|
|
||||||
y_offset + height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_clip_push_from_path_preserve (void)
|
_cogl_clip_stack_push_from_path (CoglClipStack *stack,
|
||||||
|
CoglHandle path,
|
||||||
|
const CoglMatrix *modelview_matrix)
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
CoglClipStack *stack;
|
|
||||||
CoglClipStackEntryPath *entry;
|
CoglClipStackEntryPath *entry;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
entry = _cogl_clip_stack_push_entry (stack,
|
entry = _cogl_clip_stack_push_entry (stack,
|
||||||
sizeof (CoglClipStackEntryPath),
|
sizeof (CoglClipStackEntryPath),
|
||||||
COGL_CLIP_STACK_PATH);
|
COGL_CLIP_STACK_PATH);
|
||||||
|
|
||||||
entry->path = cogl_path_copy (cogl_path_get ());
|
entry->path = cogl_path_copy (path);
|
||||||
|
|
||||||
cogl_get_modelview_matrix (&entry->matrix);
|
entry->matrix = *modelview_matrix;
|
||||||
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cogl_clip_push_from_path (void)
|
|
||||||
{
|
|
||||||
cogl_clip_push_from_path_preserve ();
|
|
||||||
|
|
||||||
cogl_path_new ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -660,18 +491,11 @@ _cogl_clip_stack_entry_unref (CoglClipStackEntry *entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
_cogl_clip_pop_real (CoglClipStackState *clip_state)
|
_cogl_clip_stack_pop (CoglClipStack *stack)
|
||||||
{
|
{
|
||||||
CoglClipStack *stack;
|
|
||||||
CoglClipStackEntry *entry;
|
CoglClipStackEntry *entry;
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
g_return_if_fail (stack->stack_top != NULL);
|
g_return_if_fail (stack->stack_top != NULL);
|
||||||
|
|
||||||
/* To pop we are moving the top of the stack to the old top's parent
|
/* To pop we are moving the top of the stack to the old top's parent
|
||||||
|
@ -687,28 +511,12 @@ _cogl_clip_pop_real (CoglClipStackState *clip_state)
|
||||||
if (stack->stack_top)
|
if (stack->stack_top)
|
||||||
stack->stack_top->ref_count++;
|
stack->stack_top->ref_count++;
|
||||||
_cogl_clip_stack_entry_unref (entry);
|
_cogl_clip_stack_entry_unref (entry);
|
||||||
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_clip_pop (void)
|
_cogl_clip_stack_flush (CoglClipStack *stack,
|
||||||
|
gboolean *stencil_used_p)
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
_cogl_clip_pop_real (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_flush_clip_state (CoglClipStackState *clip_state)
|
|
||||||
{
|
|
||||||
CoglClipStack *stack;
|
|
||||||
int has_clip_planes;
|
int has_clip_planes;
|
||||||
gboolean using_clip_planes = FALSE;
|
gboolean using_clip_planes = FALSE;
|
||||||
gboolean using_stencil_buffer = FALSE;
|
gboolean using_stencil_buffer = FALSE;
|
||||||
|
@ -720,26 +528,8 @@ _cogl_flush_clip_state (CoglClipStackState *clip_state)
|
||||||
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
|
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
|
||||||
CoglClipStackEntry *entry;
|
CoglClipStackEntry *entry;
|
||||||
|
|
||||||
if (!clip_state->stack_dirty)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* The current primitive journal does not support tracking changes to the
|
|
||||||
* clip stack... */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
/* XXX: the handling of clipping is quite complex. It may involve use of
|
|
||||||
* the Cogl Journal or other Cogl APIs which may end up recursively
|
|
||||||
* wanting to ensure the clip state is flushed. We need to ensure we
|
|
||||||
* don't recurse infinitely...
|
|
||||||
*/
|
|
||||||
clip_state->stack_dirty = FALSE;
|
|
||||||
|
|
||||||
has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
|
has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
clip_state->stencil_used = FALSE;
|
|
||||||
|
|
||||||
disable_clip_planes ();
|
disable_clip_planes ();
|
||||||
disable_stencil_buffer ();
|
disable_stencil_buffer ();
|
||||||
GE (glDisable (GL_SCISSOR_TEST));
|
GE (glDisable (GL_SCISSOR_TEST));
|
||||||
|
@ -854,112 +644,27 @@ _cogl_flush_clip_state (CoglClipStackState *clip_state)
|
||||||
scissor_y1 - scissor_y0));
|
scissor_y1 - scissor_y0));
|
||||||
}
|
}
|
||||||
|
|
||||||
clip_state->stencil_used = using_stencil_buffer;
|
*stencil_used_p = using_stencil_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: This should never have been made public API! */
|
CoglClipStack *
|
||||||
void
|
_cogl_clip_stack_new (void)
|
||||||
cogl_clip_ensure (void)
|
|
||||||
{
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (_cogl_get_framebuffer ());
|
|
||||||
_cogl_flush_clip_state (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_cogl_clip_stack_save_real (CoglClipStackState *clip_state)
|
|
||||||
{
|
{
|
||||||
CoglClipStack *stack;
|
CoglClipStack *stack;
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
stack = g_slice_new (CoglClipStack);
|
stack = g_slice_new (CoglClipStack);
|
||||||
stack->stack_top = NULL;
|
stack->stack_top = NULL;
|
||||||
|
|
||||||
clip_state->stacks = g_slist_prepend (clip_state->stacks, stack);
|
return stack;
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_clip_stack_save (void)
|
_cogl_clip_stack_free (CoglClipStack *stack)
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
/* We only need to unref the top node and this
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
_cogl_clip_stack_save_real (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_cogl_clip_stack_restore_real (CoglClipStackState *clip_state)
|
|
||||||
{
|
|
||||||
CoglClipStack *stack;
|
|
||||||
|
|
||||||
g_return_if_fail (clip_state->stacks != NULL);
|
|
||||||
|
|
||||||
/* We don't log clip stack changes in the journal so we must flush
|
|
||||||
* it before making modifications */
|
|
||||||
_cogl_journal_flush ();
|
|
||||||
|
|
||||||
stack = clip_state->stacks->data;
|
|
||||||
|
|
||||||
/* Free the stack. We only need to unref the top node and this
|
|
||||||
should end up freeing all of the parents if need be */
|
should end up freeing all of the parents if need be */
|
||||||
if (stack->stack_top)
|
if (stack->stack_top)
|
||||||
_cogl_clip_stack_entry_unref (stack->stack_top);
|
_cogl_clip_stack_entry_unref (stack->stack_top);
|
||||||
|
|
||||||
/* Revert to an old stack */
|
|
||||||
g_slice_free (CoglClipStack, stack);
|
g_slice_free (CoglClipStack, stack);
|
||||||
clip_state->stacks = g_slist_delete_link (clip_state->stacks,
|
|
||||||
clip_state->stacks);
|
|
||||||
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cogl_clip_stack_restore (void)
|
|
||||||
{
|
|
||||||
CoglHandle framebuffer;
|
|
||||||
CoglClipStackState *clip_state;
|
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
framebuffer = _cogl_get_framebuffer ();
|
|
||||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
|
||||||
|
|
||||||
_cogl_clip_stack_restore_real (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_clip_stack_state_init (CoglClipStackState *clip_state)
|
|
||||||
{
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
|
||||||
|
|
||||||
clip_state->stacks = NULL;
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
|
|
||||||
/* Add an intial stack */
|
|
||||||
_cogl_clip_stack_save_real (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_clip_stack_state_destroy (CoglClipStackState *clip_state)
|
|
||||||
{
|
|
||||||
/* Destroy all of the stacks */
|
|
||||||
while (clip_state->stacks)
|
|
||||||
_cogl_clip_stack_restore_real (clip_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_clip_stack_state_dirty (CoglClipStackState *clip_state)
|
|
||||||
{
|
|
||||||
clip_state->stack_dirty = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -24,27 +24,38 @@
|
||||||
#ifndef __COGL_CLIP_STACK_H
|
#ifndef __COGL_CLIP_STACK_H
|
||||||
#define __COGL_CLIP_STACK_H
|
#define __COGL_CLIP_STACK_H
|
||||||
|
|
||||||
typedef struct _CoglClipStackState CoglClipStackState;
|
typedef struct _CoglClipStack CoglClipStack;
|
||||||
|
|
||||||
struct _CoglClipStackState
|
CoglClipStack *
|
||||||
{
|
_cogl_clip_stack_new (void);
|
||||||
/* Stack of stacks */
|
|
||||||
GSList *stacks;
|
|
||||||
|
|
||||||
gboolean stack_dirty;
|
|
||||||
gboolean stencil_used;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_clip_stack_state_init (CoglClipStackState *state);
|
_cogl_clip_stack_free (CoglClipStack *stack);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_clip_stack_state_destroy (CoglClipStackState *state);
|
_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack,
|
||||||
|
int x_offset,
|
||||||
|
int y_offset,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_clip_stack_state_dirty (CoglClipStackState *state);
|
_cogl_clip_stack_push_rectangle (CoglClipStack *stack,
|
||||||
|
float x_1,
|
||||||
|
float y_1,
|
||||||
|
float x_2,
|
||||||
|
float y_2,
|
||||||
|
const CoglMatrix *modelview_matrix);
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_flush_clip_state (CoglClipStackState *clip_state);
|
_cogl_clip_stack_push_from_path (CoglClipStack *stack,
|
||||||
|
CoglHandle path,
|
||||||
|
const CoglMatrix *modelview_matrix);
|
||||||
|
void
|
||||||
|
_cogl_clip_stack_pop (CoglClipStack *stack);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_stack_flush (CoglClipStack *stack,
|
||||||
|
gboolean *stencil_used_p);
|
||||||
|
|
||||||
#endif /* __COGL_CLIP_STACK_H */
|
#endif /* __COGL_CLIP_STACK_H */
|
||||||
|
|
405
cogl/cogl-clip-state.c
Normal file
405
cogl/cogl-clip-state.c
Normal file
|
@ -0,0 +1,405 @@
|
||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "cogl.h"
|
||||||
|
#include "cogl-clip-stack.h"
|
||||||
|
#include "cogl-clip-state.h"
|
||||||
|
#include "cogl-context.h"
|
||||||
|
#include "cogl-internal.h"
|
||||||
|
#include "cogl-framebuffer-private.h"
|
||||||
|
#include "cogl-journal-private.h"
|
||||||
|
#include "cogl-util.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_push_window_rectangle (int x_offset,
|
||||||
|
int y_offset,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
CoglClipStack *stack;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
_cogl_clip_stack_push_window_rectangle (stack, x_offset, y_offset,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: This is deprecated API */
|
||||||
|
void
|
||||||
|
cogl_clip_push_window_rect (float x_offset,
|
||||||
|
float y_offset,
|
||||||
|
float width,
|
||||||
|
float height)
|
||||||
|
{
|
||||||
|
cogl_clip_push_window_rectangle (x_offset, y_offset, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1)
|
||||||
|
* to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with
|
||||||
|
* (0,0) being top left. */
|
||||||
|
#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \
|
||||||
|
( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) )
|
||||||
|
/* Note: for Y we first flip all coordinates around the X axis while in
|
||||||
|
* normalized device coodinates */
|
||||||
|
#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \
|
||||||
|
( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) )
|
||||||
|
|
||||||
|
/* Transform a homogeneous vertex position from model space to Cogl
|
||||||
|
* window coordinates (with 0,0 being top left) */
|
||||||
|
static void
|
||||||
|
transform_point (CoglMatrix *matrix_mv,
|
||||||
|
CoglMatrix *matrix_p,
|
||||||
|
float *viewport,
|
||||||
|
float *x,
|
||||||
|
float *y)
|
||||||
|
{
|
||||||
|
float z = 0;
|
||||||
|
float w = 1;
|
||||||
|
|
||||||
|
/* Apply the modelview matrix transform */
|
||||||
|
cogl_matrix_transform_point (matrix_mv, x, y, &z, &w);
|
||||||
|
|
||||||
|
/* Apply the projection matrix transform */
|
||||||
|
cogl_matrix_transform_point (matrix_p, x, y, &z, &w);
|
||||||
|
|
||||||
|
/* Perform perspective division */
|
||||||
|
*x /= w;
|
||||||
|
*y /= w;
|
||||||
|
|
||||||
|
/* Apply viewport transform */
|
||||||
|
*x = VIEWPORT_TRANSFORM_X (*x, viewport[0], viewport[2]);
|
||||||
|
*y = VIEWPORT_TRANSFORM_Y (*y, viewport[1], viewport[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef VIEWPORT_SCALE_X
|
||||||
|
#undef VIEWPORT_SCALE_Y
|
||||||
|
|
||||||
|
/* Try to push a rectangle given in object coordinates as a rectangle in window
|
||||||
|
* coordinates instead of object coordinates */
|
||||||
|
gboolean
|
||||||
|
try_pushing_rect_as_window_rect (float x_1,
|
||||||
|
float y_1,
|
||||||
|
float x_2,
|
||||||
|
float y_2)
|
||||||
|
{
|
||||||
|
CoglMatrix matrix;
|
||||||
|
CoglMatrix matrix_p;
|
||||||
|
float v[4];
|
||||||
|
|
||||||
|
cogl_get_modelview_matrix (&matrix);
|
||||||
|
|
||||||
|
/* If the modelview meets these constraints then a transformed rectangle
|
||||||
|
* should still be a rectangle when it reaches screen coordinates.
|
||||||
|
*
|
||||||
|
* FIXME: we are are making certain assumptions about the projection
|
||||||
|
* matrix a.t.m and should really be looking at the combined modelview
|
||||||
|
* and projection matrix.
|
||||||
|
* FIXME: we don't consider rotations that are a multiple of 90 degrees
|
||||||
|
* which could be quite common.
|
||||||
|
*/
|
||||||
|
if (matrix.xy != 0 || matrix.xz != 0 ||
|
||||||
|
matrix.yx != 0 || matrix.yz != 0 ||
|
||||||
|
matrix.zx != 0 || matrix.zy != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cogl_get_projection_matrix (&matrix_p);
|
||||||
|
cogl_get_viewport (v);
|
||||||
|
|
||||||
|
transform_point (&matrix, &matrix_p, v, &x_1, &y_1);
|
||||||
|
transform_point (&matrix, &matrix_p, v, &x_2, &y_2);
|
||||||
|
|
||||||
|
/* Consider that the modelview matrix may flip the rectangle
|
||||||
|
* along the x or y axis... */
|
||||||
|
#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0)
|
||||||
|
if (x_1 > x_2)
|
||||||
|
SWAP (x_1, x_2);
|
||||||
|
if (y_1 > y_2)
|
||||||
|
SWAP (y_1, y_2);
|
||||||
|
#undef SWAP
|
||||||
|
|
||||||
|
cogl_clip_push_window_rectangle (COGL_UTIL_NEARBYINT (x_1),
|
||||||
|
COGL_UTIL_NEARBYINT (y_1),
|
||||||
|
COGL_UTIL_NEARBYINT (x_2 - x_1),
|
||||||
|
COGL_UTIL_NEARBYINT (y_2 - y_1));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_push_rectangle (float x_1,
|
||||||
|
float y_1,
|
||||||
|
float x_2,
|
||||||
|
float y_2)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
CoglClipStack *stack;
|
||||||
|
CoglMatrix modelview_matrix;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
/* Try and catch window space rectangles so we can redirect to
|
||||||
|
* cogl_clip_push_window_rect which will use scissoring. */
|
||||||
|
if (try_pushing_rect_as_window_rect (x_1, y_1, x_2, y_2))
|
||||||
|
return;
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
cogl_get_modelview_matrix (&modelview_matrix);
|
||||||
|
|
||||||
|
_cogl_clip_stack_push_rectangle (stack, x_1, y_1, x_2, y_2,
|
||||||
|
&modelview_matrix);
|
||||||
|
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: Deprecated API */
|
||||||
|
void
|
||||||
|
cogl_clip_push (float x_offset,
|
||||||
|
float y_offset,
|
||||||
|
float width,
|
||||||
|
float height)
|
||||||
|
{
|
||||||
|
cogl_clip_push_rectangle (x_offset,
|
||||||
|
y_offset,
|
||||||
|
x_offset + width,
|
||||||
|
y_offset + height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_push_from_path_preserve (void)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
CoglClipStack *stack;
|
||||||
|
CoglMatrix modelview_matrix;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
cogl_get_modelview_matrix (&modelview_matrix);
|
||||||
|
|
||||||
|
_cogl_clip_stack_push_from_path (stack, cogl_path_get (),
|
||||||
|
&modelview_matrix);
|
||||||
|
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_push_from_path (void)
|
||||||
|
{
|
||||||
|
cogl_clip_push_from_path_preserve ();
|
||||||
|
|
||||||
|
cogl_path_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_clip_pop_real (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
CoglClipStack *stack;
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
_cogl_clip_stack_pop (stack);
|
||||||
|
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_pop (void)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
_cogl_clip_pop_real (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_flush (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
CoglClipStack *stack;
|
||||||
|
|
||||||
|
if (!clip_state->stack_dirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* The current primitive journal does not support tracking changes to the
|
||||||
|
* clip stack... */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
/* XXX: the handling of clipping is quite complex. It may involve use of
|
||||||
|
* the Cogl Journal or other Cogl APIs which may end up recursively
|
||||||
|
* wanting to ensure the clip state is flushed. We need to ensure we
|
||||||
|
* don't recurse infinitely...
|
||||||
|
*/
|
||||||
|
clip_state->stack_dirty = FALSE;
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
_cogl_clip_stack_flush (stack, &clip_state->stencil_used);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: This should never have been made public API! */
|
||||||
|
void
|
||||||
|
cogl_clip_ensure (void)
|
||||||
|
{
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (_cogl_get_framebuffer ());
|
||||||
|
_cogl_clip_state_flush (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_clip_stack_save_real (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
CoglClipStack *stack;
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
stack = _cogl_clip_stack_new ();
|
||||||
|
|
||||||
|
clip_state->stacks = g_slist_prepend (clip_state->stacks, stack);
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_stack_save (void)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
_cogl_clip_stack_save_real (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_clip_stack_restore_real (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
CoglClipStack *stack;
|
||||||
|
|
||||||
|
g_return_if_fail (clip_state->stacks != NULL);
|
||||||
|
|
||||||
|
/* We don't log clip stack changes in the journal so we must flush
|
||||||
|
* it before making modifications */
|
||||||
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
stack = clip_state->stacks->data;
|
||||||
|
|
||||||
|
_cogl_clip_stack_free (stack);
|
||||||
|
|
||||||
|
/* Revert to an old stack */
|
||||||
|
clip_state->stacks = g_slist_delete_link (clip_state->stacks,
|
||||||
|
clip_state->stacks);
|
||||||
|
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_stack_restore (void)
|
||||||
|
{
|
||||||
|
CoglHandle framebuffer;
|
||||||
|
CoglClipState *clip_state;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
framebuffer = _cogl_get_framebuffer ();
|
||||||
|
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||||
|
|
||||||
|
_cogl_clip_stack_restore_real (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_init (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
clip_state->stacks = NULL;
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
|
||||||
|
/* Add an intial stack */
|
||||||
|
_cogl_clip_stack_save_real (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_destroy (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
/* Destroy all of the stacks */
|
||||||
|
while (clip_state->stacks)
|
||||||
|
_cogl_clip_stack_restore_real (clip_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_dirty (CoglClipState *clip_state)
|
||||||
|
{
|
||||||
|
clip_state->stack_dirty = TRUE;
|
||||||
|
}
|
50
cogl/cogl-clip-state.h
Normal file
50
cogl/cogl-clip-state.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_CLIP_STATE_H
|
||||||
|
#define __COGL_CLIP_STATE_H
|
||||||
|
|
||||||
|
typedef struct _CoglClipState CoglClipState;
|
||||||
|
|
||||||
|
struct _CoglClipState
|
||||||
|
{
|
||||||
|
/* Stack of CoglClipStacks */
|
||||||
|
GSList *stacks;
|
||||||
|
|
||||||
|
gboolean stack_dirty;
|
||||||
|
gboolean stencil_used;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_init (CoglClipState *state);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_destroy (CoglClipState *state);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_dirty (CoglClipState *state);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_clip_state_flush (CoglClipState *clip_state);
|
||||||
|
|
||||||
|
#endif /* __COGL_CLIP_STATE_H */
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "cogl-handle.h"
|
#include "cogl-handle.h"
|
||||||
#include "cogl-matrix-stack.h"
|
#include "cogl-matrix-stack.h"
|
||||||
#include "cogl-clip-stack.h"
|
#include "cogl-clip-state.h"
|
||||||
|
|
||||||
typedef enum _CoglFramebufferType {
|
typedef enum _CoglFramebufferType {
|
||||||
COGL_FRAMEBUFFER_TYPE_ONSCREEN,
|
COGL_FRAMEBUFFER_TYPE_ONSCREEN,
|
||||||
|
@ -47,7 +47,7 @@ typedef struct
|
||||||
int viewport_width;
|
int viewport_width;
|
||||||
int viewport_height;
|
int viewport_height;
|
||||||
|
|
||||||
CoglClipStackState clip_state;
|
CoglClipState clip_state;
|
||||||
} CoglFramebuffer;
|
} CoglFramebuffer;
|
||||||
|
|
||||||
#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
|
#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
|
||||||
|
@ -75,7 +75,7 @@ int
|
||||||
_cogl_framebuffer_get_width (CoglHandle handle);
|
_cogl_framebuffer_get_width (CoglHandle handle);
|
||||||
int
|
int
|
||||||
_cogl_framebuffer_get_height (CoglHandle handle);
|
_cogl_framebuffer_get_height (CoglHandle handle);
|
||||||
CoglClipStackState *
|
CoglClipState *
|
||||||
_cogl_framebuffer_get_clip_state (CoglHandle handle);
|
_cogl_framebuffer_get_clip_state (CoglHandle handle);
|
||||||
void
|
void
|
||||||
_cogl_framebuffer_set_viewport (CoglHandle handle,
|
_cogl_framebuffer_set_viewport (CoglHandle handle,
|
||||||
|
|
|
@ -131,13 +131,13 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
|
||||||
framebuffer->projection_stack = _cogl_matrix_stack_new ();
|
framebuffer->projection_stack = _cogl_matrix_stack_new ();
|
||||||
|
|
||||||
/* Initialise the clip stack */
|
/* Initialise the clip stack */
|
||||||
_cogl_clip_stack_state_init (&framebuffer->clip_state);
|
_cogl_clip_state_init (&framebuffer->clip_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_framebuffer_free (CoglFramebuffer *framebuffer)
|
_cogl_framebuffer_free (CoglFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
_cogl_clip_stack_state_destroy (&framebuffer->clip_state);
|
_cogl_clip_state_destroy (&framebuffer->clip_state);
|
||||||
|
|
||||||
_cogl_matrix_stack_destroy (framebuffer->modelview_stack);
|
_cogl_matrix_stack_destroy (framebuffer->modelview_stack);
|
||||||
framebuffer->modelview_stack = NULL;
|
framebuffer->modelview_stack = NULL;
|
||||||
|
@ -160,7 +160,7 @@ _cogl_framebuffer_get_height (CoglHandle handle)
|
||||||
return framebuffer->height;
|
return framebuffer->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglClipStackState *
|
CoglClipState *
|
||||||
_cogl_framebuffer_get_clip_state (CoglHandle handle)
|
_cogl_framebuffer_get_clip_state (CoglHandle handle)
|
||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (handle);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (handle);
|
||||||
|
@ -551,7 +551,7 @@ _cogl_set_framebuffer_real (CoglFramebuffer *framebuffer)
|
||||||
* we flush */
|
* we flush */
|
||||||
_cogl_matrix_stack_dirty (framebuffer->modelview_stack);
|
_cogl_matrix_stack_dirty (framebuffer->modelview_stack);
|
||||||
_cogl_matrix_stack_dirty (framebuffer->projection_stack);
|
_cogl_matrix_stack_dirty (framebuffer->projection_stack);
|
||||||
_cogl_clip_stack_state_dirty (&framebuffer->clip_state);
|
_cogl_clip_state_dirty (&framebuffer->clip_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -697,7 +697,7 @@ _cogl_framebuffer_flush_state (CoglHandle handle,
|
||||||
/* XXX: Flushing clip state may trash the modelview and projection
|
/* XXX: Flushing clip state may trash the modelview and projection
|
||||||
* matrices so we must do it before flushing the matrices...
|
* matrices so we must do it before flushing the matrices...
|
||||||
*/
|
*/
|
||||||
_cogl_flush_clip_state (&framebuffer->clip_state);
|
_cogl_clip_state_flush (&framebuffer->clip_state);
|
||||||
|
|
||||||
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW))
|
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW))
|
||||||
_cogl_matrix_stack_flush_to_gl (framebuffer->modelview_stack,
|
_cogl_matrix_stack_flush_to_gl (framebuffer->modelview_stack,
|
||||||
|
|
|
@ -563,7 +563,7 @@ _cogl_path_fill_nodes (void)
|
||||||
cogl_features_available (COGL_FEATURE_STENCIL_BUFFER))
|
cogl_features_available (COGL_FEATURE_STENCIL_BUFFER))
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
CoglHandle framebuffer;
|
||||||
CoglClipStackState *clip_state;
|
CoglClipState *clip_state;
|
||||||
|
|
||||||
_cogl_journal_flush ();
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
|
@ -586,7 +586,7 @@ _cogl_path_fill_nodes (void)
|
||||||
* we call cogl_flush() to emtpy the journal.
|
* we call cogl_flush() to emtpy the journal.
|
||||||
*/
|
*/
|
||||||
cogl_flush ();
|
cogl_flush ();
|
||||||
_cogl_clip_stack_state_dirty (clip_state);
|
_cogl_clip_state_dirty (clip_state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1043,7 +1043,7 @@ cogl_set_projection_matrix (CoglMatrix *matrix)
|
||||||
_COGL_MATRIX_DEBUG_PRINT (matrix);
|
_COGL_MATRIX_DEBUG_PRINT (matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglClipStackState *
|
CoglClipState *
|
||||||
_cogl_get_clip_state (void)
|
_cogl_get_clip_state (void)
|
||||||
{
|
{
|
||||||
CoglHandle framebuffer;
|
CoglHandle framebuffer;
|
||||||
|
|
Loading…
Reference in a new issue