framebuffer: Add CoglFramebuffer clip stack methods
This adds CoglFramebuffer methods for accessing the clip stack. We plan on making some optimizations to how framebuffer state is flushed which will require us to track when a framebuffer's clip state has changed. This api also ties in to the longer term goal of removing the need for a default global CoglContext since these methods are all implicitly related to a specific context via their framebuffer argument. Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
parent
652c8c31cf
commit
6bb409e996
@ -51,4 +51,10 @@ void
|
||||
_cogl_clip_state_set_stack (CoglClipState *clip_state,
|
||||
CoglClipStack *clip_stack);
|
||||
|
||||
void
|
||||
_cogl_clip_state_save_clip_stack (CoglClipState *clip_state);
|
||||
|
||||
void
|
||||
_cogl_clip_state_restore_clip_stack (CoglClipState *clip_state);
|
||||
|
||||
#endif /* __COGL_CLIP_STATE_PRIVATE_H */
|
||||
|
@ -46,18 +46,8 @@ cogl_clip_push_window_rectangle (int x_offset,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_window_rectangle (clip_state->stacks->data,
|
||||
x_offset, y_offset,
|
||||
width, height);
|
||||
cogl_framebuffer_push_scissor_clip (cogl_get_draw_framebuffer (),
|
||||
x_offset, y_offset, width, height);
|
||||
}
|
||||
|
||||
/* XXX: This is deprecated API */
|
||||
@ -76,21 +66,8 @@ cogl_clip_push_rectangle (float x_1,
|
||||
float x_2,
|
||||
float y_2)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
cogl_get_modelview_matrix (&modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_rectangle (clip_state->stacks->data,
|
||||
x_1, y_1, x_2, y_2,
|
||||
&modelview_matrix);
|
||||
cogl_framebuffer_push_rectangle_clip (cogl_get_draw_framebuffer (),
|
||||
x_1, y_1, x_2, y_2);
|
||||
}
|
||||
|
||||
/* XXX: Deprecated API */
|
||||
@ -132,53 +109,30 @@ cogl_clip_push_primitive (CoglPrimitive *primitive,
|
||||
float bounds_x2,
|
||||
float bounds_y2)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
cogl_get_modelview_matrix (&modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_primitive (clip_state->stacks->data,
|
||||
primitive,
|
||||
bounds_x1, bounds_y1,
|
||||
bounds_x2, bounds_y2,
|
||||
&modelview_matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_clip_pop_real (CoglClipState *clip_state)
|
||||
{
|
||||
clip_state->stacks->data = _cogl_clip_stack_pop (clip_state->stacks->data);
|
||||
cogl_framebuffer_push_primitive_clip (cogl_get_draw_framebuffer (),
|
||||
primitive,
|
||||
bounds_x1,
|
||||
bounds_y1,
|
||||
bounds_x2,
|
||||
bounds_y2);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_clip_pop (void)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
_cogl_clip_pop_real (clip_state);
|
||||
cogl_framebuffer_pop_clip (cogl_get_draw_framebuffer ());
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state,
|
||||
CoglFramebuffer *framebuffer)
|
||||
cogl_clip_stack_save (void)
|
||||
{
|
||||
/* 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,
|
||||
framebuffer);
|
||||
_cogl_framebuffer_save_clip_stack (cogl_get_draw_framebuffer ());
|
||||
}
|
||||
|
||||
void
|
||||
cogl_clip_stack_restore (void)
|
||||
{
|
||||
_cogl_framebuffer_restore_clip_stack (cogl_get_draw_framebuffer ());
|
||||
}
|
||||
|
||||
/* XXX: This should never have been made public API! */
|
||||
@ -193,56 +147,6 @@ cogl_clip_ensure (void)
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_clip_stack_save_real (CoglClipState *clip_state)
|
||||
{
|
||||
clip_state->stacks = g_slist_prepend (clip_state->stacks, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_clip_stack_save (void)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_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)
|
||||
{
|
||||
CoglHandle stack;
|
||||
|
||||
_COGL_RETURN_IF_FAIL (clip_state->stacks != NULL);
|
||||
|
||||
stack = clip_state->stacks->data;
|
||||
|
||||
_cogl_clip_stack_unref (stack);
|
||||
|
||||
/* Revert to an old stack */
|
||||
clip_state->stacks = g_slist_delete_link (clip_state->stacks,
|
||||
clip_state->stacks);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_clip_stack_restore (void)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
_cogl_clip_stack_restore_real (clip_state);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_state_init (CoglClipState *clip_state)
|
||||
{
|
||||
@ -251,7 +155,7 @@ _cogl_clip_state_init (CoglClipState *clip_state)
|
||||
clip_state->stacks = NULL;
|
||||
|
||||
/* Add an intial stack */
|
||||
_cogl_clip_stack_save_real (clip_state);
|
||||
_cogl_clip_state_save_clip_stack (clip_state);
|
||||
}
|
||||
|
||||
void
|
||||
@ -259,7 +163,7 @@ _cogl_clip_state_destroy (CoglClipState *clip_state)
|
||||
{
|
||||
/* Destroy all of the stacks */
|
||||
while (clip_state->stacks)
|
||||
_cogl_clip_stack_restore_real (clip_state);
|
||||
_cogl_clip_state_restore_clip_stack (clip_state);
|
||||
}
|
||||
|
||||
CoglClipStack *
|
||||
@ -277,3 +181,35 @@ _cogl_clip_state_set_stack (CoglClipState *clip_state,
|
||||
_cogl_clip_stack_unref (clip_state->stacks->data);
|
||||
clip_state->stacks->data = stack;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_state_save_clip_stack (CoglClipState *clip_state)
|
||||
{
|
||||
clip_state->stacks = g_slist_prepend (clip_state->stacks, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_clip_state_restore_clip_stack (CoglClipState *clip_state)
|
||||
{
|
||||
CoglHandle stack;
|
||||
|
||||
_COGL_RETURN_IF_FAIL (clip_state->stacks != NULL);
|
||||
|
||||
stack = clip_state->stacks->data;
|
||||
|
||||
_cogl_clip_stack_unref (stack);
|
||||
|
||||
/* Revert to an old stack */
|
||||
clip_state->stacks = g_slist_delete_link (clip_state->stacks,
|
||||
clip_state->stacks);
|
||||
}
|
||||
|
||||
void
|
||||
_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,
|
||||
framebuffer);
|
||||
}
|
||||
|
@ -340,4 +340,10 @@ _cogl_framebuffer_push_projection (CoglFramebuffer *framebuffer);
|
||||
void
|
||||
_cogl_framebuffer_pop_projection (CoglFramebuffer *framebuffer);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer);
|
||||
|
||||
void
|
||||
_cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer);
|
||||
|
||||
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
|
||||
|
@ -1981,3 +1981,93 @@ cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer,
|
||||
|
||||
_COGL_MATRIX_DEBUG_PRINT (matrix);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_window_rectangle (clip_state->stacks->data,
|
||||
x, y, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer,
|
||||
float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_rectangle (clip_state->stacks->data,
|
||||
x_1, y_1, x_2, y_2,
|
||||
&modelview_matrix);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
CoglPath *path)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
cogl_framebuffer_get_modelview_matrix (framebuffer, &modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_from_path (clip_state->stacks->data,
|
||||
path,
|
||||
&modelview_matrix);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer,
|
||||
CoglPrimitive *primitive,
|
||||
float bounds_x1,
|
||||
float bounds_y1,
|
||||
float bounds_x2,
|
||||
float bounds_y2)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
cogl_get_modelview_matrix (&modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_primitive (clip_state->stacks->data,
|
||||
primitive,
|
||||
bounds_x1, bounds_y1,
|
||||
bounds_x2, bounds_y2,
|
||||
&modelview_matrix);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
clip_state->stacks->data = _cogl_clip_stack_pop (clip_state->stacks->data);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
_cogl_clip_state_save_clip_stack (clip_state);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
CoglClipState *clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
_cogl_clip_state_restore_clip_stack (clip_state);
|
||||
}
|
||||
|
@ -384,6 +384,138 @@ void
|
||||
cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
#define cogl_framebuffer_push_scissor_clip \
|
||||
cogl_framebuffer_push_scissor_clip_EXP
|
||||
/**
|
||||
* cogl_framebuffer_push_scissor_clip:
|
||||
* @framebuffer: A #CoglFramebuffer pointer
|
||||
* @x: left edge of the clip rectangle in window coordinates
|
||||
* @y: top edge of the clip rectangle in window coordinates
|
||||
* @width: width of the clip rectangle
|
||||
* @height: height of the clip rectangle
|
||||
*
|
||||
* Specifies a rectangular clipping area for all subsequent drawing
|
||||
* operations. Any drawing commands that extend outside the rectangle
|
||||
* will be clipped so that only the portion inside the rectangle will
|
||||
* be displayed. The rectangle dimensions are not transformed by the
|
||||
* current model-view matrix.
|
||||
*
|
||||
* The rectangle is intersected with the current clip region. To undo
|
||||
* the effect of this function, call cogl_framebuffer_pop_clip().
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
#define cogl_framebuffer_push_rectangle_clip \
|
||||
cogl_framebuffer_push_rectangle_clip_EXP
|
||||
/**
|
||||
* cogl_framebuffer_push_rectangle_clip:
|
||||
* @framebuffer: A #CoglFramebuffer pointer
|
||||
* @x_1: x coordinate for top left corner of the clip rectangle
|
||||
* @y_1: y coordinate for top left corner of the clip rectangle
|
||||
* @x_2: x coordinate for bottom right corner of the clip rectangle
|
||||
* @y_2: y coordinate for bottom right corner of the clip rectangle
|
||||
*
|
||||
* Specifies a modelview transformed rectangular clipping area for all
|
||||
* subsequent drawing operations. Any drawing commands that extend
|
||||
* outside the rectangle will be clipped so that only the portion
|
||||
* inside the rectangle will be displayed. The rectangle dimensions
|
||||
* are transformed by the current model-view matrix.
|
||||
*
|
||||
* The rectangle is intersected with the current clip region. To undo
|
||||
* the effect of this function, call cogl_framebuffer_pop_clip().
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer,
|
||||
float x_1,
|
||||
float y_1,
|
||||
float x_2,
|
||||
float y_2);
|
||||
|
||||
#define cogl_framebuffer_push_path_clip \
|
||||
cogl_framebuffer_push_path_clip_EXP
|
||||
/**
|
||||
* cogl_framebuffer_push_path_clip:
|
||||
* @framebuffer: A #CoglFramebuffer pointer
|
||||
* @path: The path to clip with.
|
||||
*
|
||||
* Sets a new clipping area using the silhouette of the specified,
|
||||
* filled @path. The clipping area is intersected with the previous
|
||||
* clipping area. To restore the previous clipping area, call
|
||||
* cogl_framebuffer_pop_clip().
|
||||
*
|
||||
* Since: 1.0
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
CoglPath *path);
|
||||
|
||||
#define cogl_framebuffer_push_primitive_clip \
|
||||
cogl_framebuffer_push_primitive_clip_EXP
|
||||
/**
|
||||
* cogl_framebuffer_push_primitive_clip:
|
||||
* @framebuffer: A #CoglFramebuffer pointer
|
||||
* @primitive: A #CoglPrimitive describing a flat 2D shape
|
||||
* @bounds_x1: x coordinate for the top-left corner of the primitives
|
||||
* bounds
|
||||
* @bounds_y1: y coordinate for the top-left corner of the primitives
|
||||
* bounds
|
||||
* @bounds_x2: x coordinate for the top-left corner of the primitives
|
||||
* bounds
|
||||
* @bounds_y2: x coordinate for the bottom-right corner of the
|
||||
* primitives bounds.
|
||||
* @bounds_x1: y coordinate for the bottom-right corner of the
|
||||
* primitives bounds.
|
||||
*
|
||||
* Sets a new clipping area using a 2D shaped described with a
|
||||
* #CoglPrimitive. The shape must not contain self overlapping
|
||||
* geometry and must lie on a single 2D plane. A bounding box of the
|
||||
* 2D shape in local coordinates (the same coordinates used to
|
||||
* describe the shape) must be given. It is acceptable for the bounds
|
||||
* to be larger than the true bounds but behaviour is undefined if the
|
||||
* bounds are smaller than the true bounds.
|
||||
*
|
||||
* The primitive is transformed by the current model-view matrix and
|
||||
* the silhouette is intersected with the previous clipping area. To
|
||||
* restore the previous clipping area, call
|
||||
* cogl_framebuffer_pop_clip().
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer,
|
||||
CoglPrimitive *primitive,
|
||||
float bounds_x1,
|
||||
float bounds_y1,
|
||||
float bounds_x2,
|
||||
float bounds_y2);
|
||||
|
||||
#define cogl_framebuffer_pop_clip cogl_framebuffer_pop_clip_EXP
|
||||
/**
|
||||
* cogl_framebuffer_pop_clip:
|
||||
* @framebuffer: A #CoglFramebuffer pointer
|
||||
*
|
||||
* Reverts the clipping region to the state before the last call to
|
||||
* cogl_framebuffer_push_clip().
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer);
|
||||
|
||||
/**
|
||||
* cogl_framebuffer_get_red_bits:
|
||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||
|
@ -33,17 +33,5 @@
|
||||
void
|
||||
cogl2_clip_push_from_path (CoglPath *path)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
CoglMatrix modelview_matrix;
|
||||
|
||||
framebuffer = cogl_get_draw_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
cogl_get_modelview_matrix (&modelview_matrix);
|
||||
|
||||
clip_state->stacks->data =
|
||||
_cogl_clip_stack_push_from_path (clip_state->stacks->data,
|
||||
path,
|
||||
&modelview_matrix);
|
||||
cogl_framebuffer_push_path_clip (cogl_get_draw_framebuffer (), path);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user