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
4 changes: 3 additions & 1 deletion Examples/DamageRegionSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ enum DamageRegionSmoke {

let geometry = try await window.geometry
let frame = try await animation.nextFrame(logicalSize: geometry.logicalSize)
try await window.redraw(damage: frame.damage) { softwareFrame in
try await window.redraw(
metadata: SurfaceFrameMetadata(damage: frame.damage)
) { softwareFrame in
draw(softwareFrame, phase: frame.phase)
}
log("operation: submit-partial-damage pass")
Expand Down
14 changes: 7 additions & 7 deletions Examples/GraphicsPreviewColorMetadataSmoke/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ enum GraphicsPreviewColorMetadataSmoke {

private static func requestedMetadata(
_ options: ExampleRunOptions
) throws -> WaylandGraphicsFrameMetadata {
WaylandGraphicsFrameMetadata(
) throws -> SurfaceFrameMetadata {
SurfaceFrameMetadata(
contentType: try requestedContentType(options.contentType),
presentationHint: try requestedPresentationHint(options.presentationHint),
alpha: .opaque,
colorRepresentation: WaylandGraphicsColorRepresentation(
colorRepresentation: SurfaceColorRepresentation(
alphaMode: .premultipliedElectrical
)
)
Expand Down Expand Up @@ -116,7 +116,7 @@ enum GraphicsPreviewColorMetadataSmoke {

private static func requestedContentType(
_ rawValue: String?
) throws -> WaylandGraphicsContentType? {
) throws -> SurfaceContentType? {
switch normalized(rawValue) {
case nil, "none":
nil
Expand All @@ -133,7 +133,7 @@ enum GraphicsPreviewColorMetadataSmoke {

private static func requestedPresentationHint(
_ rawValue: String?
) throws -> WaylandGraphicsPresentationHint? {
) throws -> SurfacePresentationHint? {
switch normalized(rawValue) {
case nil, "none":
nil
Expand Down Expand Up @@ -196,7 +196,7 @@ enum GraphicsPreviewColorMetadataSmoke {
}

nonisolated private static func contentTypeDescription(
_ contentType: WaylandGraphicsContentType?
_ contentType: SurfaceContentType?
) -> String {
switch contentType {
case nil:
Expand All @@ -213,7 +213,7 @@ enum GraphicsPreviewColorMetadataSmoke {
}

nonisolated private static func presentationHintDescription(
_ presentationHint: WaylandGraphicsPresentationHint?
_ presentationHint: SurfacePresentationHint?
) -> String {
switch presentationHint {
case nil:
Expand Down
24 changes: 12 additions & 12 deletions Examples/GraphicsPreviewManagedGPUClear/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ enum GraphicsPreviewManagedGPUClear {
_ events: DisplayEvents,
backing: WaylandGraphicsWindowBacking,
state: ManagedGPUClearRunState,
metadata: WaylandGraphicsFrameMetadata
metadata: SurfaceFrameMetadata
) async throws {
var iterator = events.makeAsyncIterator()
while !Task.isCancelled, let event = try await iterator.next() {
Expand All @@ -186,7 +186,7 @@ enum GraphicsPreviewManagedGPUClear {
nonisolated private static func submitClearFrame(
backing: WaylandGraphicsWindowBacking,
state: ManagedGPUClearRunState,
metadata: WaylandGraphicsFrameMetadata
metadata: SurfaceFrameMetadata
) async throws -> WaylandGraphicsFrameResult {
let lease = try await backing.nextFrame()
let result = try await lease.submit(
Expand Down Expand Up @@ -398,21 +398,21 @@ enum GraphicsPreviewManagedGPUClear {

nonisolated private static func requestedFrameMetadata(
_ options: ExampleRunOptions
) throws -> WaylandGraphicsFrameMetadata {
try WaylandGraphicsFrameMetadata(
) throws -> SurfaceFrameMetadata {
try SurfaceFrameMetadata(
contentType: requestedContentType(options.contentType),
presentationHint: requestedPresentationHint(options.presentationHint)
)
}

nonisolated private static func requestedContentType(
_ rawValue: String?
) throws -> WaylandGraphicsContentType? {
) throws -> SurfaceContentType? {
switch normalized(rawValue) {
case nil:
nil
case "none":
WaylandGraphicsContentType.none
SurfaceContentType.none
case "photo":
.photo
case "video":
Expand All @@ -426,7 +426,7 @@ enum GraphicsPreviewManagedGPUClear {

nonisolated private static func requestedPresentationHint(
_ rawValue: String?
) throws -> WaylandGraphicsPresentationHint? {
) throws -> SurfacePresentationHint? {
switch normalized(rawValue) {
case nil:
nil
Expand Down Expand Up @@ -498,7 +498,7 @@ enum GraphicsPreviewManagedGPUClear {
}

nonisolated fileprivate static func contentTypeDescription(
_ contentType: WaylandGraphicsContentType?
_ contentType: SurfaceContentType?
) -> String {
guard let contentType else { return "not requested" }
switch contentType {
Expand All @@ -514,7 +514,7 @@ enum GraphicsPreviewManagedGPUClear {
}

nonisolated fileprivate static func presentationHintDescription(
_ hint: WaylandGraphicsPresentationHint?
_ hint: SurfacePresentationHint?
) -> String {
guard let hint else { return "not requested" }
switch hint {
Expand Down Expand Up @@ -740,7 +740,7 @@ private struct ManagedGPUClearReport: Sendable {
var synchronizationPolicy: WaylandGraphicsSynchronizationPolicy
var pacingPolicy: WaylandGraphicsPacingPolicy
var metadataPolicy: WaylandGraphicsMetadataPolicy
var metadata: WaylandGraphicsFrameMetadata
var metadata: SurfaceFrameMetadata
var resizeRequestCount: Int
var failure: String?

Expand All @@ -754,7 +754,7 @@ private struct ManagedGPUClearReport: Sendable {
WaylandGraphicsSynchronizationPolicy = .implicitOnly,
pacingPolicy reportedPacingPolicy: WaylandGraphicsPacingPolicy = .none,
metadataPolicy reportedMetadataPolicy: WaylandGraphicsMetadataPolicy = .none,
metadata reportedMetadata: WaylandGraphicsFrameMetadata = .default,
metadata reportedMetadata: SurfaceFrameMetadata = .default,
resizeRequestCount reportedResizeRequestCount: Int = 0,
failure reportedFailure: String? = nil
) {
Expand Down Expand Up @@ -800,7 +800,7 @@ private actor ManagedGPUClearRunState {
synchronizationPolicy: WaylandGraphicsSynchronizationPolicy,
pacingPolicy: WaylandGraphicsPacingPolicy,
metadataPolicy: WaylandGraphicsMetadataPolicy,
metadata: WaylandGraphicsFrameMetadata,
metadata: SurfaceFrameMetadata,
resizeRequestCount: Int
) -> ManagedGPUClearReport {
ManagedGPUClearReport(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,13 @@ struct WaylandFrameworkHostClientTests {
metadataPolicy: .preferAvailable,
presentationFeedbackPolicy: .requestWhenAvailable
)
let damage = WaylandGraphicsDamageRegion(rects: [])
let metadata = WaylandGraphicsFrameMetadata(damage: damage)
let metadata = SurfaceFrameMetadata()

#expect(displayConfiguration.eventStreams == streams)
#expect(windowConfiguration.initialSize.width.rawValue == 128)
#expect(popupConfiguration.positioner.size.width.rawValue == 64)
#expect(graphicsConfiguration.presentationPolicy == .software)
#expect(metadata.damage == .fullFrame)
#expect(metadata.damage == nil)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,13 @@ struct WaylandGraphicsPreviewClientTests {
metadataPolicy: .preferAvailable,
presentationFeedbackPolicy: .requestWhenAvailable
)
let metadata = WaylandGraphicsFrameMetadata(
let metadata = SurfaceFrameMetadata(
contentType: .video,
presentationHint: .async,
alpha: .opaque,
colorRepresentation: WaylandGraphicsColorRepresentation(
colorRepresentation: SurfaceColorRepresentation(
alphaMode: .premultipliedElectrical
),
damage: .fullFrame
)
)
let schedule = WaylandGraphicsFrameSchedule(
synchronization: .preferExplicit,
Expand Down Expand Up @@ -132,7 +131,7 @@ struct WaylandGraphicsPreviewClientTests {
#expect(WaylandGraphicsReason.gbmAllocationFailed != .gbmUnavailable)
#expect(metadata.contentType == .video)
#expect(metadata.alpha == .opaque)
#expect(metadata.damage == .fullFrame)
#expect(metadata.damage == nil)
#expect(frame == expectedFrame)
#expect(result.operation == .show)
#expect(result.backing == .fallback(.forcedSoftware))
Expand All @@ -154,7 +153,11 @@ struct WaylandGraphicsPreviewClientTests {

let secondLease = try await backing.nextFrame()
let result = try await secondLease.submitSoftware(
metadata: WaylandGraphicsFrameMetadata(damage: .fullFrame)
metadata: SurfaceFrameMetadata(
damage: try SurfaceDamageRegion([
LogicalRect(x: 0, y: 0, width: 1, height: 1)
])
)
) { frame in
frame.withXRGB8888Rows { _, pixels in
for index in 0..<pixels.count {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,50 +274,40 @@ struct WaylandPresentationAPISurfaceTests {
private func useAtomicSoftwarePresentationAPI(
_ window: Window
) async throws -> [SoftwarePresentationOutcome] {
let simpleShow = try await window.show(requestPresentationFeedback: true) { _ in () }
let simpleRedraw = try await window.redraw(requestPresentationFeedback: true) { _ in () }
let simpleDamagedShow = try await window.show(
damage: nil,
let dirtyRectangle = try LogicalRect(x: 0, y: 0, width: 1, height: 1)
let metadata = SurfaceFrameMetadata(
contentType: .photo,
presentationHint: .vsync,
alpha: .opaque,
colorRepresentation: SurfaceColorRepresentation(
alphaMode: .premultipliedElectrical
),
damage: try SurfaceDamageRegion([dirtyRectangle])
)

let simpleShow = try await window.show(
metadata: metadata,
requestPresentationFeedback: true,
timeoutMilliseconds: 1_000
) { _ in () }
let simpleDamagedRedraw = try await window.redraw(
damage: nil,
let simpleRedraw = try await window.redraw(
metadata: metadata,
requestPresentationFeedback: true
) { _ in () }
let shown = try await window.show(
requestPresentationFeedback: true,
preparing: { reservation in reservation.id },
{ _, _ in () }
)
let redrawn = try await window.redraw(
let preparedShow = try await window.show(
metadata: metadata,
requestPresentationFeedback: true,
preparing: { reservation in reservation.id },
{ _, _ in () }
)
let damagedShow = try await window.show(
damage: nil,
timeoutMilliseconds: 1_000,
requestPresentationFeedback: true,
preparing: { reservation in reservation.id },
{ _, _ in () }
)
let damagedRedraw = try await window.redraw(
damage: nil,
let preparedRedraw = try await window.redraw(
metadata: metadata,
requestPresentationFeedback: true,
preparing: { reservation in reservation.id },
{ _, _ in () }
)
return [
simpleShow,
simpleRedraw,
simpleDamagedShow,
simpleDamagedRedraw,
shown,
redrawn,
damagedShow,
damagedRedraw,
]
return [simpleShow, simpleRedraw, preparedShow, preparedRedraw]
}
}

Expand Down
15 changes: 10 additions & 5 deletions Sources/WaylandClient/Internal/Display/DisplayCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,16 @@ final class DisplayCore: RawInvariantFailureReporter, WindowFailureSink {

func reserveSoftwareFrameForShow(
_ windowID: WindowID,
timeoutMilliseconds: Int32
timeoutMilliseconds: Int32,
metadata: SurfaceFrameMetadata = .default
) throws -> WindowSoftwareFrameReservationOutcome {
try withFatalFailureFinalization {
guard !isClosed, let window = surfaces.window(windowID) else {
return .closed
}
return try window.reserveShowSoftwareFrameOnOwnerThread(
timeoutMilliseconds: timeoutMilliseconds
timeoutMilliseconds: timeoutMilliseconds,
metadata: metadata
)
}
}
Expand Down Expand Up @@ -165,13 +167,16 @@ final class DisplayCore: RawInvariantFailureReporter, WindowFailureSink {
}

func reserveSoftwareFrameForRedraw(
_ windowID: WindowID
_ windowID: WindowID,
metadata frameMetadata: SurfaceFrameMetadata = .default
) throws -> WindowSoftwareFrameReservationOutcome {
try withFatalFailureFinalization {
guard !isClosed, let window = surfaces.window(windowID) else {
return .closed
}
return try window.reserveRedrawSoftwareFrameOnOwnerThread()
return try window.reserveRedrawSoftwareFrameOnOwnerThread(
metadata: frameMetadata
)
}
}

Expand All @@ -180,7 +185,7 @@ final class DisplayCore: RawInvariantFailureReporter, WindowFailureSink {
_ windowID: WindowID,
reservation: SoftwareFrameReservation,
submitConstraints: SurfaceSubmitConstraints,
metadata: SurfaceCommitMetadata,
metadata: SurfaceFrameMetadata,
requestPresentationFeedback: Bool,
damage: SurfaceDamageRegion?,
_ draw: sending @Sendable (borrowing SoftwareFrame) throws -> Void
Expand Down
3 changes: 1 addition & 2 deletions Sources/WaylandClient/Internal/Events/EventBroker.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Synchronization
import WaylandRuntime

@safe
Expand Down Expand Up @@ -356,7 +355,7 @@ final class TypedEventBroker<Element: Sendable>: Sendable {
private let stream: EventStreamIdentity
private let capacity: Int
private let overflowStrategy: OverflowStrategy<Element>
private let state = Mutex(BrokerState())
private let state = EventBrokerLockedState(BrokerState())

init(
stream eventStream: EventStreamIdentity,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Foundation

// SAFETY: `value` is private and every access is protected by an `NSLock`
// acquired before Swift begins the sanitizer-visible inout access.
@safe
final class EventBrokerLockedState<State>: @unchecked Sendable {
private let lock = NSLock()
private var value: State

init(_ initialValue: consuming State) {
value = initialValue
}

func withLock<Result>(
_ body: (inout State) throws -> Result
) rethrows -> Result {
lock.lock()
defer { lock.unlock() }
return try body(&value)
}
}
Loading
Loading