c++winapidirect2d

Should the order of direct2d push/pop axis aligned clips be reserved with push/pop layers


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(...)

Solution

  • 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.