@@ -52,56 +52,76 @@ extension LayerTree {
5252 self . options = options
5353 }
5454
55- func renderCommands( for layer : Layer , colorConverter: any ColorConverter ) -> [ RendererCommand < P . Types > ] {
55+ func renderCommands( for l : Layer , colorConverter c : any ColorConverter ) -> [ RendererCommand < P . Types > ] {
5656 var commands = [ RendererCommand < P . Types > ] ( )
5757
58- let state = makeCommandState ( for: layer, colorConverter: colorConverter)
59-
60- guard state. hasContents else { return commands }
61-
62- if state. hasFilters {
63- logUnsupportedFilters ( layer. filters)
64- }
65-
66- if state. hasOpacity || state. hasTransform || state. hasClip || state. hasMask {
67- commands. append ( . pushState)
68- }
69-
70- commands. append ( contentsOf: renderCommands ( forTransforms: layer. transform) )
71- commands. append ( contentsOf: renderCommands ( forOpacity: layer. opacity) )
72- commands. append ( contentsOf: renderCommands ( forClip: layer. clip, using: layer. clipRule) )
73-
74- if state. hasMask {
75- commands. append ( . pushTransparencyLayer)
76- }
77-
78- //render all of the layer contents
79- for contents in layer. contents {
80- switch makeRenderContents ( for: contents, colorConverter: state. colorConverter) {
81- case let . simple( cmd) :
58+ var stack : [ RenderStep ] = [
59+ . beginLayer( l, c)
60+ ]
61+
62+ while let step = stack. popLast ( ) {
63+ switch step {
64+ case let . beginLayer( layer, colorConverter) :
65+ let state = makeCommandState ( for: layer, colorConverter: colorConverter)
66+
67+ //guard state.hasContents else { continue }
68+ stack. append ( . endLayer( layer, state) )
69+
70+ if state. hasFilters {
71+ logUnsupportedFilters ( layer. filters)
72+ }
73+
74+ if state. hasOpacity || state. hasTransform || state. hasClip || state. hasMask {
75+ commands. append ( . pushState)
76+ }
77+
78+ commands. append ( contentsOf: renderCommands ( forTransforms: layer. transform) )
79+ commands. append ( contentsOf: renderCommands ( forOpacity: layer. opacity) )
80+ commands. append ( contentsOf: renderCommands ( forClip: layer. clip, using: layer. clipRule) )
81+
82+ if state. hasMask {
83+ commands. append ( . pushTransparencyLayer)
84+ }
85+
86+ //push render of all of the layer contents in reverse order
87+ for contents in layer. contents. reversed ( ) {
88+ switch makeRenderContents ( for: contents, colorConverter: colorConverter) {
89+ case let . simple( cmd) :
90+ stack. append ( . contents( cmd) )
91+ case let . layer( layer) :
92+ stack. append ( . beginLayer( layer, colorConverter) )
93+ }
94+ }
95+
96+ case let . contents( cmd) :
8297 commands. append ( contentsOf: cmd)
83- case let . layer( layer) :
84- commands. append ( contentsOf: renderCommands ( for: layer, colorConverter: colorConverter) )
85- }
86- }
8798
88- //render apply mask
89- if state. hasMask {
90- commands. append ( contentsOf: renderCommands ( forMask: layer. mask) )
91- commands. append ( . popTransparencyLayer)
92- }
99+ case let . endLayer( layer, state) :
100+ //render apply mask
101+ if state. hasMask {
102+ commands. append ( contentsOf: renderCommands ( forMask: layer. mask) )
103+ commands. append ( . popTransparencyLayer)
104+ }
93105
94- if state. hasOpacity {
95- commands. append ( . popTransparencyLayer)
96- }
106+ if state. hasOpacity {
107+ commands. append ( . popTransparencyLayer)
108+ }
97109
98- if state. hasOpacity || state. hasTransform || state. hasClip || state. hasMask {
99- commands. append ( . popState)
110+ if state. hasOpacity || state. hasTransform || state. hasClip || state. hasMask {
111+ commands. append ( . popState)
112+ }
113+ }
100114 }
101115
102116 return commands
103117 }
104118
119+ enum RenderStep {
120+ case beginLayer( LayerTree . Layer , any ColorConverter )
121+ case contents( [ RendererCommand < P . Types > ] )
122+ case endLayer( LayerTree . Layer , CommandState )
123+ }
124+
105125 struct CommandState {
106126 var hasOpacity : Bool
107127 var hasTransform : Bool
0 commit comments