cogl: Implement retained clip stacks
This adds three new internal API functions which can be used to retain the clip stack state and restore it later: _cogl_get_clip_stack _cogl_set_clip_stack _cogl_clip_stack_copy The functions are currently internal and not yet used but we may want to make them public in future to replace the cogl_clip_stack_save() and cogl_clip_stack_restore() APIs. The get function just returns the handle to the clip stack at the top of the stack of stacks and the set function just replaces it. The copy function makes a cheap copy of an existing stack by taking a reference to the top stack entry. This ends up working like a deep copy because there is no way to modify entries of a stack but it doesn't actually copy the data.
This commit is contained in:
parent
3a58bc440b
commit
708bbc72e1
@ -682,3 +682,29 @@ _cogl_clip_stack_free (CoglClipStack *stack)
|
||||
|
||||
g_slice_free (CoglClipStack, stack);
|
||||
}
|
||||
|
||||
CoglHandle
|
||||
_cogl_clip_stack_copy (CoglHandle handle)
|
||||
{
|
||||
CoglHandle new_handle;
|
||||
CoglClipStack *new_stack, *old_stack;
|
||||
|
||||
if (!cogl_is_clip_stack (handle))
|
||||
return COGL_INVALID_HANDLE;
|
||||
|
||||
old_stack = COGL_CLIP_STACK (handle);
|
||||
|
||||
new_handle = _cogl_clip_stack_new ();
|
||||
new_stack = COGL_CLIP_STACK (new_handle);
|
||||
|
||||
/* We can copy the stack by just referencing the other stack's
|
||||
data. There's no need to implement copy-on-write because the
|
||||
entries of the stack can't be modified. If the other stack pops
|
||||
some entries off they will still be kept alive because this stack
|
||||
holds a reference. */
|
||||
new_stack->stack_top = old_stack->stack_top;
|
||||
if (new_stack->stack_top)
|
||||
new_stack->stack_top->ref_count++;
|
||||
|
||||
return new_handle;
|
||||
}
|
||||
|
@ -53,4 +53,23 @@ void
|
||||
_cogl_clip_stack_flush (CoglHandle handle,
|
||||
gboolean *stencil_used_p);
|
||||
|
||||
|
||||
/* TODO: we may want to make this function public because it can be
|
||||
* used to implement a better API than cogl_clip_stack_save() and
|
||||
* cogl_clip_stack_restore().
|
||||
*/
|
||||
/*
|
||||
* _cogl_clip_stack_copy:
|
||||
* @handle: A handle to a clip stack
|
||||
*
|
||||
* Creates a copy of the given clip stack and returns a new handle to
|
||||
* it. The data from the original stack is shared with the new stack
|
||||
* so making copies is relatively cheap. Modifying the original stack
|
||||
* does not affect the new stack.
|
||||
*
|
||||
* Return value: a new clip stack with the same data as @handle
|
||||
*/
|
||||
CoglHandle
|
||||
_cogl_clip_stack_copy (CoglHandle handle);
|
||||
|
||||
#endif /* __COGL_CLIP_STACK_H */
|
||||
|
@ -403,3 +403,37 @@ _cogl_clip_state_dirty (CoglClipState *clip_state)
|
||||
{
|
||||
clip_state->stack_dirty = TRUE;
|
||||
}
|
||||
|
||||
CoglHandle
|
||||
_cogl_get_clip_stack (void)
|
||||
{
|
||||
CoglHandle framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||
|
||||
framebuffer = _cogl_get_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
return clip_state->stacks->data;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_set_clip_stack (CoglHandle handle)
|
||||
{
|
||||
CoglHandle framebuffer;
|
||||
CoglClipState *clip_state;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (handle == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
framebuffer = _cogl_get_framebuffer ();
|
||||
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
|
||||
|
||||
/* Replace the top of the stack of stacks */
|
||||
cogl_handle_ref (handle);
|
||||
cogl_handle_unref (clip_state->stacks->data);
|
||||
clip_state->stacks->data = handle;
|
||||
}
|
||||
|
@ -47,4 +47,32 @@ _cogl_clip_state_dirty (CoglClipState *state);
|
||||
void
|
||||
_cogl_clip_state_flush (CoglClipState *clip_state);
|
||||
|
||||
/* TODO: we may want to make these two functions public because they
|
||||
* can be used to implement a better API than cogl_clip_stack_save()
|
||||
* and cogl_clip_stack_restore().
|
||||
*/
|
||||
/*
|
||||
* _cogl_get_clip_stack:
|
||||
*
|
||||
* Gets a handle to the current clip stack. This can be used to later
|
||||
* return to the same clip stack state with _cogl_set_clip_stack(). A
|
||||
* reference is not taken on the stack so if you want to keep it you
|
||||
* should call cogl_handle_ref() or _cogl_clip_stack_copy().
|
||||
*
|
||||
* Return value: a handle to the current clip stack.
|
||||
*/
|
||||
CoglHandle
|
||||
_cogl_get_clip_stack (void);
|
||||
|
||||
/*
|
||||
* _cogl_set_clip_stack:
|
||||
* @handle: a handle to the replacement clip stack
|
||||
*
|
||||
* Replaces the current clip stack with @handle.
|
||||
*
|
||||
* Return value: a handle to the current clip stack.
|
||||
*/
|
||||
void
|
||||
_cogl_set_clip_stack (CoglHandle handle);
|
||||
|
||||
#endif /* __COGL_CLIP_STATE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user