mirror of
https://github.com/brl/mutter.git
synced 2024-11-10 16:16:20 -05:00
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);
|
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,
|
_cogl_clip_stack_flush (CoglHandle handle,
|
||||||
gboolean *stencil_used_p);
|
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 */
|
#endif /* __COGL_CLIP_STACK_H */
|
||||||
|
@ -403,3 +403,37 @@ _cogl_clip_state_dirty (CoglClipState *clip_state)
|
|||||||
{
|
{
|
||||||
clip_state->stack_dirty = TRUE;
|
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
|
void
|
||||||
_cogl_clip_state_flush (CoglClipState *clip_state);
|
_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 */
|
#endif /* __COGL_CLIP_STATE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user