In direct2d there are two types of clips: axis aligned clips used with PushAxisAlignedClip
and PopAxisAlignedClip
and layer clips used with PushLayer
and PopLayer
. The docs say that the each call to PushAxisAlignedClip
must be matched with a call to PopAxisAlignedClip
and the same for PushLayer
and PopLayer
but I didn't find anything regarding the order of push/pop when using both clips.
What I want to do is to save the current rendering state and push some clips using PushAxisAlignedClip
if the rectangle has no round corners and PushAxisAlignedClip
if the is any round corners and when I finish, I pop all the clips using PopAxisAlignedClip
and PopLayer
.
I think of two methods to pop the layers:
1- On each push I store a flag to remember whether it was an axis aligned clip or a layer and iterate the flags in reverse order when going to pop. a good example for this flags store is std::vector<bool>
2- Have to counters one for aligned axis clips and one for layers and increment on push. When popping I will call PopAxisAlignedClip
times the aligned clips counter and PopLayer
times the layers counter.
I'm asking about the second method because I will not have to maintain a state of flags to track the type of pushed layers. Must the order of aligned clips be reserved with the order of layers? In other words, can I use something like this demonstrating code:
render_target->PushAxisAlignedClip(...)
render_target->PushLayer(...)
// some drawing code
render_target->PopAxisAlignedClip(...)
render_target->PopLayer(...)
I just tried the second way and it gave me the following HRESULT
error from EndDraw
: 0x88990014 which maps to D2DERR_POP_CALL_DID_NOT_MATCH_PUSH
and the docs explains:
The application attempted to pop a layer off the stack when a clip was at the top, or pop a clip off the stack when a layer was at the top.
So the answer to the question is: Yes the order of clips and layers must be reserved
EDIT: It is well documented here PushAxisAlignedClip:
A PushAxisAlignedClip and PopAxisAlignedClip pair can occur around or within a PushLayer and PopLayer, but cannot overlap. For example, the sequence of PushAxisAlignedClip, PushLayer, PopLayer, PopAxisAlignedClip is valid, but the sequence of PushAxisAlignedClip, PushLayer, PopAxisAlignedClip, PopLayer is invalid.