diff --git a/cogl/cogl-clip-state-private.h b/cogl/cogl-clip-state-private.h index 66bf895a8..799302ffd 100644 --- a/cogl/cogl-clip-state-private.h +++ b/cogl/cogl-clip-state-private.h @@ -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 */ diff --git a/cogl/cogl-clip-state.c b/cogl/cogl-clip-state.c index a68a2f00d..229e6ad12 100644 --- a/cogl/cogl-clip-state.c +++ b/cogl/cogl-clip-state.c @@ -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); +} diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h index 6499c80a8..8f6020c9b 100644 --- a/cogl/cogl-framebuffer-private.h +++ b/cogl/cogl-framebuffer-private.h @@ -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 */ diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index c372963c4..0fcb43364 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -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); +} diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h index c39350d2d..e6be63a55 100644 --- a/cogl/cogl-framebuffer.h +++ b/cogl/cogl-framebuffer.h @@ -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 diff --git a/cogl/cogl2-clip-state.c b/cogl/cogl2-clip-state.c index 347e0daff..698e58cfa 100644 --- a/cogl/cogl2-clip-state.c +++ b/cogl/cogl2-clip-state.c @@ -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); }