Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -915,28 +915,23 @@ final package class DisplayLink: NSObject {
if nextThread != currentThread, let oldLink = self.link {
if nextThread == .async {
Self.asyncPending = true
if Self.asyncRunloop == nil {
let threadName = "org.OpenSwiftUIProject.OpenSwiftUI.AsyncRenderer"
while true {
if Self.asyncThread == nil { // FIXME:
let thread = Thread(
target: DisplayLink.self,
selector: #selector(DisplayLink.asyncThread(with:)),
object: nil
)
thread.qualityOfService = .userInteractive
thread.name = threadName
guard _NSThreadStart(thread) else {
cancelAsyncRendering()
break
}
Self.asyncThread = thread
}
Update.wait()
guard Self.asyncRunloop == nil else {
while Self.asyncRunloop == nil {
if Self.asyncThread == nil {
let thread = Thread(
target: DisplayLink.self,
selector: #selector(DisplayLink.asyncThread(with:)),
object: nil
)
thread.qualityOfService = .userInteractive
thread.name = "org.OpenSwiftUIProject.OpenSwiftUI.AsyncRenderer"
guard _NSThreadStart(thread) else {
cancelAsyncRendering()
break
}
Self.asyncThread = thread
}
Update.wait()
Self.asyncPending = true
}
}
if nextThread != currentThread {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
// UnsafeHeterogeneousBuffer.swift
// OpenSwiftUICore
//
// Audited for 6.0.87
// Audited for 6.5.4
// Status: Complete
// ID: 568350FE259575B5E1AAA52AD722AAAC (SwiftUICore)

package struct UnsafeHeterogeneousBuffer: Collection {
var buf: UnsafeMutableRawPointer!
var available: Int32
var _count: Int32
private var buf: UnsafeMutableRawPointer!
private var available: Int32
private var _count: Int32

package typealias VTable = _UnsafeHeterogeneousBuffer_VTable

package typealias Element = _UnsafeHeterogeneousBuffer_Element

package struct Index: Equatable, Comparable {
Expand All @@ -34,11 +35,13 @@ package struct UnsafeHeterogeneousBuffer: Collection {
}

package var count: Int { Int(_count) }

package var isEmpty: Bool { _count == 0 }

package var startIndex: Index {
Index(index: 0, offset: 0)
}

package var endIndex: Index {
Index(index: _count, offset: 0)
}
Expand Down Expand Up @@ -113,7 +116,13 @@ package struct UnsafeHeterogeneousBuffer: Collection {
}

package func formIndex(after index: inout Index) {
index = self.index(after: index)
let item = self[index].item.pointee
index.index &+= 1
if index.index == _count {
index.offset = 0
} else {
index.offset &+= item.size
}
}

package func index(after index: Index) -> Index {
Expand All @@ -137,14 +146,13 @@ package struct UnsafeHeterogeneousBuffer: Collection {

@discardableResult
package mutating func append<T>(_ value: T, vtable: VTable.Type) -> Index {
defer { _count += 1 }
let bytes = (MemoryLayout<T>.size + MemoryLayout<UnsafeHeterogeneousBuffer.Item>.size + 0xf) & ~0xf
let pointer = allocate(bytes)
let element = _UnsafeHeterogeneousBuffer_Element(item: pointer.assumingMemoryBound(to: Item.self))
element.item.initialize(to: Item(vtable: vtable, size: Int32(bytes), flags: 0))
element.body(as: T.self).initialize(to: value)
let index = Index(index: _count, offset: Int32(pointer - buf))
_count += 1
return index
return Index(index: _count, offset: Int32(pointer - buf))
}
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/OpenSwiftUICore/Graph/GraphHost.swift
Original file line number Diff line number Diff line change
Expand Up @@ -496,17 +496,17 @@ extension GraphHost {
}

package final func finishTransactionUpdate(in subgraph: Subgraph, postUpdate: (_ again: Bool) -> Void = { _ in }) {
var count = 0
var counter = 0
repeat {
let currentContinuations = continuations
let oldContinuations = continuations
continuations = []
for currentContinuation in currentContinuations {
currentContinuation()
for continuation in oldContinuations {
continuation()
}
count &+= 1
counter &+= 1
subgraph.update(flags: .transactional)
postUpdate(!continuations.isEmpty)
} while count != 8 && !continuations.isEmpty
} while counter != 8 && !continuations.isEmpty
inTransaction = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ extension DisplayList {
maxVersion: DisplayList.Version,
environment: DisplayList.ViewRenderer.Environment
) -> Time

@_silgen_name("OpenSwiftUITestStub_DisplayListViewRendererRenderAsync")
package func swiftUI_renderAsync(
to list: DisplayList,
time: Time,
nextTime: Time,
targetTimestamp: Time?,
version: DisplayList.Version,
maxVersion: DisplayList.Version
) -> Time?
#endif

package func render(
Expand All @@ -138,7 +148,14 @@ extension DisplayList {
return time + maxInterval
}

package func renderAsync(to list: DisplayList, time: Time, nextTime: Time, targetTimestamp: Time?, version: DisplayList.Version, maxVersion: DisplayList.Version) -> Time? {
package func renderAsync(
to list: DisplayList,
time: Time,
nextTime: Time,
targetTimestamp: Time?,
version: DisplayList.Version,
maxVersion: DisplayList.Version
) -> Time? {
guard !configChanged, let renderer else {
return nil
}
Expand Down
10 changes: 7 additions & 3 deletions Sources/OpenSwiftUICore/Util/AttributeGraphAdditions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,21 @@ extension Attribute {
}

package func allowsAsyncUpdate() -> Bool {
_openSwiftUIUnimplementedFailure()
!valueState.contains([.dirty, .mainThread])
}
}

extension WeakAttribute {
package var uncheckedIdentifier: Attribute<Value> {
get { _openSwiftUIUnimplementedFailure() }
#if OPENSWIFTUI_ANY_ATTRIBUTE_FIX
_openSwiftUIUnimplementedFailure()
#else
Attribute(identifier: AnyWeakAttribute(self)._details.identifier)
#endif
}

package func allowsAsyncUpdate() -> Bool {
_openSwiftUIUnimplementedFailure()
attribute.map { $0.allowsAsyncUpdate() } ?? false
}
}

Expand Down
135 changes: 74 additions & 61 deletions Sources/OpenSwiftUICore/View/Graph/ViewGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ extension ViewGraph {
}
}

// MARK: - ViewGraph + Update [6.5.4]

extension ViewGraph {
package var updateRequiredMainThread: Bool {
graph.mainUpdates != mainUpdates
Expand All @@ -384,11 +386,31 @@ extension ViewGraph {
beginNextUpdate(at: time)
updateOutputs(async: false)
}

package func updateOutputsAsync(at time: Time) -> (list: DisplayList, version: DisplayList.Version)? {
beginNextUpdate(at: time)
_openSwiftUIUnimplementedWarning()
return nil
guard _rootDisplayList.allowsAsyncUpdate(),
hostPreferenceValues.allowsAsyncUpdate(),
sizeThatFitsObservers.isEmpty || _rootLayoutComputer.allowsAsyncUpdate()
else {
return nil
}
for feature in features {
guard let allowsAsyncUpdate = feature.allowsAsyncUpdate(graph: self) else {
feature.skipsAsyncUpdate = true
continue
}
feature.skipsAsyncUpdate = false
guard allowsAsyncUpdate else {
return nil
}
}
var result: (DisplayList, DisplayList.Version)?
graph.withMainThreadHandler(Update.syncMain) {
updateOutputs(async: true)
result = displayList()
}
return result
}

package func displayList() -> (DisplayList, DisplayList.Version) {
Expand All @@ -400,68 +422,59 @@ extension ViewGraph {
data.updateSeed &+= 1
mainUpdates = graph.mainUpdates
}

// FIXME
private func updateOutputs(async: Bool) {
instantiateIfNeeded()
data.transactionSeed &+= 1

// let oldCachedSizeThatFits = cachedSizeThatFits

private func updateOutputs(async: Bool) {
var preferencesChanged = false
var observedSizeThatFitsChanged = false
var updatedOutputs: Outputs = []

var counter1 = 0
var featuresChanged = false
var sizeThatFitsChanged = false
var counter = 0
repeat {
counter1 &+= 1
inTransaction = true
var counter2 = 0
repeat {
let conts = continuations
continuations = []
for continuation in conts {
continuation()
counter &+= 1
instantiateIfNeeded()
startTransactionUpdate()
finishTransactionUpdate(in: globalSubgraph)
if updatePreferences() {
preferencesChanged = true
}
if sizeThatFitsObservers.needsUpdate(graph: self) {
sizeThatFitsChanged = true
}
for feature in features {
guard !async || !feature.skipsAsyncUpdate else {
continue
}
counter2 &+= 1
data.globalSubgraph.update(flags: .transactional)
} while (continuations.count != 0 && counter2 != 8)
inTransaction = false
preferencesChanged = preferencesChanged || updatePreferences()
observedSizeThatFitsChanged = observedSizeThatFitsChanged || updateObservedSizeThatFits()
updatedOutputs.formUnion(updateRequestedOutputs())
} while (needsTransaction && counter1 != 8)
// guard preferencesChanged || observedSizeThatFitsChanged || !updatedOutputs.isEmpty || needsFocusUpdate else {
// return
// }
// if Thread.isMainThread {
// if preferencesChanged {
// delegate?.preferencesDidChange()
// }
// if observedSizeThatFitsChanged {
// sizeThatFitsObserver?.callback(oldCachedSizeThatFits, self.cachedSizeThatFits)
// }
// if !requestedOutputs.isEmpty {
//// delegate?.outputsDidChange(outputs: updatedOutputs)
// }
// if needsFocusUpdate {
// needsFocusUpdate = false
//// delegate?.focusDidChange()
// }
// } else {
// _openSwiftUIUnimplementedFailure()
// }
// mainUpdates &-= 1
}

private func updateObservedSizeThatFits() -> Bool {
// TODO
return false
}

private func updateRequestedOutputs() -> Outputs {
// TODO
return []
if feature.needsUpdate {
featuresChanged = true
} else if feature.needsUpdate(graph: self) {
feature.needsUpdate = true
featuresChanged = true
}
}
} while (needsTransaction && counter != 8)
guard preferencesChanged || featuresChanged || sizeThatFitsChanged else {
return
}
Update.syncMain {
if preferencesChanged {
delegate?.preferencesDidChange()
preferenceBridge?.updateHostValues(data.$hostPreferenceKeys)
}
if featuresChanged {
for feature in features {
guard !async || !feature.skipsAsyncUpdate else {
continue
}
if feature.needsUpdate {
feature.update(graph: self)
feature.needsUpdate = false
}
}
}
if sizeThatFitsChanged {
sizeThatFitsObservers.notify()
}
}
mainUpdates &-= 1
}
}

Expand Down
Loading
Loading