Skip to content

Commit ef893dd

Browse files
authored
[Feature] Add LeafDisplayList (#270)
* Update LeafDisplayList * Update DisplayList print
1 parent d9a02bd commit ef893dd

File tree

11 files changed

+247
-34
lines changed

11 files changed

+247
-34
lines changed

Example/HostingExample/ViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,6 @@ class ViewController: NSViewController {
6666

6767
struct ContentView: View {
6868
var body: some View {
69-
AppearanceActionModifierExample()
69+
Color(uiColor: .red)
7070
}
7171
}

Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,66 @@ extension _UIHostingView: ViewRendererHost {
509509
package func updateScrollableContainerSize() {
510510
// preconditionFailure("TODO")
511511
}
512-
513-
package func renderDisplayList(_ list: DisplayList, asynchronously: Bool, time: Time, nextTime: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time {
514-
// preconditionFailure("TODO")
515-
return .infinity
512+
513+
var shouldDisableUIKitAnimations: Bool {
514+
// FIXME
515+
false
516+
}
517+
518+
package func renderDisplayList(
519+
_ list: DisplayList,
520+
asynchronously: Bool,
521+
time: Time,
522+
nextTime: Time,
523+
targetTimestamp: Time?,
524+
version: DisplayList.Version,
525+
maxVersion: DisplayList.Version
526+
) -> Time {
527+
func render() -> Time {
528+
let scale = window?.screen.scale ?? 1
529+
let environment = DisplayList.ViewRenderer.Environment(contentScale: scale)
530+
return renderer.render(
531+
rootView: self,
532+
from: list,
533+
time: time,
534+
nextTime: nextTime,
535+
version: version,
536+
maxVersion: maxVersion,
537+
environment: environment
538+
)
539+
}
540+
541+
if asynchronously {
542+
if let renderedTime = renderer.renderAsync(
543+
to: list,
544+
time: time,
545+
nextTime: nextTime,
546+
targetTimestamp: targetTimestamp,
547+
version: version,
548+
maxVersion: maxVersion
549+
) {
550+
return renderedTime
551+
} else {
552+
var renderedTime = nextTime
553+
Update.syncMain {
554+
renderedTime = render()
555+
}
556+
return renderedTime
557+
}
558+
} else {
559+
if Self.areAnimationsEnabled, shouldDisableUIKitAnimations {
560+
var renderedTime = nextTime // FIXME
561+
Self.performWithoutAnimation {
562+
renderedTime = render()
563+
}
564+
allowUIKitAnimationsForNextUpdate = false
565+
return renderedTime
566+
} else {
567+
let renderedTime = render()
568+
allowUIKitAnimationsForNextUpdate = false
569+
return renderedTime
570+
}
571+
}
516572
}
517573

518574
package func updateRootView() {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// BackdropEffect.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: WIP
7+
8+
package struct BackdropEffect {
9+
package var scale: Float
10+
11+
package var color: Color.Resolved
12+
13+
package var filters: [GraphicsFilter]
14+
15+
package init(scale: Float = 1, color: Color.Resolved = .black, filters: [GraphicsFilter] = [], captureOnly: Bool = false) {
16+
self.scale = scale
17+
self.color = color
18+
self.filters = filters
19+
}
20+
}

Sources/OpenSwiftUICore/Graphic/Color/ColorView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ package struct ColorView: RendererLeafView, Animatable {
3131
}
3232

3333
package func content() -> DisplayList.Content.Value {
34-
preconditionFailure("TODO")
34+
.color(color)
3535
}
3636

3737
package var animatableData: Color.Resolved.AnimatableData {

Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//
55
// Audited for iOS 18.0
66
// Status: WIP
7-
// ID: F37E3733E490AA5E3BDC045E3D34D9F8
7+
// ID: F37E3733E490AA5E3BDC045E3D34D9F8 (SwiftUICore)
88

99
package import Foundation
1010

@@ -105,22 +105,31 @@ extension DisplayList.Version: Sendable {}
105105

106106
extension DisplayList {
107107
package typealias Identity = _DisplayList_Identity
108+
108109
package typealias StableIdentity = _DisplayList_StableIdentity
110+
109111
package typealias StableIdentityMap = _DisplayList_StableIdentityMap
112+
110113
package typealias StableIdentityRoot = _DisplayList_StableIdentityRoot
114+
111115
package typealias StableIdentityScope = _DisplayList_StableIdentityScope
112-
116+
113117
package struct Item: Equatable {
114118
package var frame: CGRect
119+
115120
package var version: Version
121+
116122
package var value: Item.Value
123+
117124
package var identity: Identity
125+
118126
package enum Value {
119127
case empty
120128
case content(Content)
121129
case effect(Effect, DisplayList)
122130
case states([(StrongHash, DisplayList)])
123131
}
132+
124133
package init(_ value: Item.Value, frame: CGRect, identity: Identity, version: Version) {
125134
self.frame = frame
126135
self.version = version
@@ -133,16 +142,19 @@ extension DisplayList {
133142
}
134143

135144
package var position: CGPoint { frame.origin }
145+
136146
package var size: CGSize { frame.size }
137147
}
138148

139149
package struct Content {
140150
package var value: Content.Value
151+
141152
package var seed: Seed
153+
142154
package enum Value {
143-
// indirect case backdrop(BackdropEffect)
155+
indirect case backdrop(BackdropEffect)
144156
indirect case color(Color.Resolved)
145-
// indirect case chameleonColor(fallback: Color.Resolved, filters: [GraphicsFilter])
157+
indirect case chameleonColor(fallback: Color.Resolved, filters: [GraphicsFilter])
146158
// indirect case image(GraphicsImage)
147159
// indirect case shape(Path, AnyResolvedPaint, FillStyle)
148160
// indirect case shadow(Path, ResolvedShadowStyle)
@@ -246,8 +258,14 @@ extension DisplayList {
246258
self.value = value
247259
}
248260

249-
package init() { self.init(value: .zero) }
250-
package init(decodedValue value: UInt16) { self.init(value: value) }
261+
package init() {
262+
self.init(value: .zero)
263+
}
264+
265+
package init(decodedValue value: UInt16) {
266+
self.init(value: value)
267+
}
268+
251269
package init(_ version: Version) {
252270
if version.value == .zero {
253271
self.init(value: .zero)
@@ -267,6 +285,7 @@ extension DisplayList {
267285

268286
package static let undefined: Seed = Seed(value: 2)
269287
}
288+
270289
package struct Properties: OptionSet {
271290
package let rawValue: UInt8
272291
package init(rawValue: UInt8) {
@@ -404,3 +423,18 @@ extension DisplayList {
404423
}
405424
}
406425
}
426+
427+
// MARK: - DisplayList.Item + Extension
428+
429+
extension DisplayList.Item {
430+
package mutating func canonicalize(options: DisplayList.Options = .init()) {
431+
// TODO
432+
}
433+
434+
// package func matchesTopLevelStructure(of other: DisplayList.Item) -> Bool
435+
436+
package var features: DisplayList.Features {
437+
// TODO
438+
[]
439+
}
440+
}

Sources/OpenSwiftUICore/Render/DisplayList/DisplayList+String.swift renamed to Sources/OpenSwiftUICore/Render/DisplayList/DisplayListPrinter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//
2-
// DisplayList+String.swift
2+
// DisplayListPrinter.swift
33
// OpenSwiftUICore
44
//
55
// Audited for iOS 18.0
66
// Status: WIP
7-
// ID: 11125C146A81D1913BFBD53B89D010C6
7+
// ID: 11125C146A81D1913BFBD53B89D010C6 (SwiftUICore)
88

99
extension DisplayList.Item {
1010
// TODO
11-
var features: DisplayList.Features { [] }
11+
// var features: DisplayList.Features { [] }
1212
var properties: DisplayList.Properties { [] }
1313

1414
fileprivate func print(into printer: inout SExpPrinter) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// DisplayListTransforms.swift
3+
// OpenSwiftUICore
4+
//
5+
// Audited for iOS 18.0
6+
// Status: WIP
7+
// ID: 8C82E31DBCFF23E23B8937F47207F4D1 (SwiftUICore)
8+
9+
package import OpenGraphShims
10+
11+
extension DisplayList {
12+
// package mutating func insertLayerFilters(matrices: [_ForegroundLayerLevel : _ColorMatrix], version: DisplayList.Version, premultiplied: Bool) {
13+
//
14+
// }
15+
16+
package mutating func applyViewGraphTransform(time: Attribute<Time>, version: DisplayList.Version) {
17+
// TODO
18+
}
19+
}

Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.ViewRenderer.swift renamed to Sources/OpenSwiftUICore/Render/DisplayList/DisplayListViewRenderer.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//
55
// Audited for iOS 18.0
66
// Status: Blocked by ViewUpdater and ViewRasterizer
7-
// ID: 21FFA3C7D88AC65BB559906758271BFC
7+
// ID: 21FFA3C7D88AC65BB559906758271BFC (SwiftUICore)
88

99
package import Foundation
1010

@@ -118,7 +118,13 @@ extension DisplayList {
118118
renderer?.viewCacheIsEmpty ?? true
119119
}
120120
}
121-
121+
}
122+
123+
// MARK: - DisplayList.ViewRasterizer
124+
125+
private var printTree: Bool?
126+
127+
extension DisplayList {
122128
private final class ViewRasterizer: ViewRendererBase {
123129
let platform: DisplayList.ViewUpdater.Platform
124130
weak var host: ViewRendererHost?
@@ -127,27 +133,34 @@ extension DisplayList {
127133
let renderer: DisplayList.GraphicsRenderer
128134
var seed: DisplayList.Seed
129135
var lastContentsScale: CGFloat
130-
136+
131137
init(platform: DisplayList.ViewUpdater.Platform, host: ViewRendererHost?, rootView: AnyObject, options: _RendererConfiguration.RasterizationOptions) {
132138
preconditionFailure("")
133139
}
134-
140+
135141
var exportedObject: AnyObject? {
136142
platform.definition.getRBLayer(drawingView: drawingView!)
137143
}
138-
144+
139145
func render(rootView: AnyObject, from list: DisplayList, time: Time, version: DisplayList.Version, maxVersion: DisplayList.Version, environment: DisplayList.ViewRenderer.Environment) -> Time {
140-
preconditionFailure("TODO")
146+
// preconditionFailure("TODO")
147+
if printTree == nil {
148+
printTree = ProcessEnvironment.bool(forKey: "OPENSWIFTUI_PRINT_TREE")
149+
}
150+
if let printTree, printTree {
151+
print("View \(Unmanaged.passUnretained(rootView).toOpaque()) at \(time):\n\(list.description)")
152+
}
153+
return .zero
141154
}
142-
155+
143156
func renderAsync(to list: DisplayList, time: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time? {
144157
preconditionFailure("TODO")
145158
}
146-
159+
147160
func destroy(rootView: AnyObject) {
148161
preconditionFailure("TODO")
149162
}
150-
163+
151164
var viewCacheIsEmpty: Bool {
152165
preconditionFailure("TODO")
153166
}

Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.ViewUpdater.swift renamed to Sources/OpenSwiftUICore/Render/DisplayList/DisplayListViewUpdater.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@
44
//
55
// Audited for iOS 18.0
66
// Status: WIP
7+
// ID: B86250B2E056EB47628ECF46032DFA4C (SwiftUICore)
8+
9+
private var printTree: Bool?
710

811
extension DisplayList {
912
// FIXME
1013
final package class ViewUpdater: ViewRendererBase {
1114
init() {
12-
preconditionFailure("")
15+
// preconditionFailure("TODO")
16+
platform = .init(rawValue: 0)
17+
exportedObject = nil
18+
viewCacheIsEmpty = false
1319
}
1420

1521
init(platform: Platform, exportedObject: AnyObject? = nil, viewCacheIsEmpty: Bool) {
@@ -23,7 +29,14 @@ extension DisplayList {
2329
var exportedObject: AnyObject?
2430

2531
func render(rootView: AnyObject, from list: DisplayList, time: Time, version: DisplayList.Version, maxVersion: DisplayList.Version, environment: DisplayList.ViewRenderer.Environment) -> Time {
26-
.zero
32+
// TODO
33+
if printTree == nil {
34+
printTree = ProcessEnvironment.bool(forKey: "OPENSWIFTUI_PRINT_TREE")
35+
}
36+
if let printTree, printTree {
37+
print("View \(Unmanaged.passUnretained(rootView).toOpaque()) at \(time):\n\(list.description)")
38+
}
39+
return .zero
2740
}
2841

2942
func renderAsync(to list: DisplayList, time: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time? {

0 commit comments

Comments
 (0)