Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
55 changes: 0 additions & 55 deletions Sources/OpenSwiftUICore/Graphic/Color/ColorRenderingMode.swift

This file was deleted.

5 changes: 0 additions & 5 deletions Sources/OpenSwiftUICore/Render/DisplayList/DisplayList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,3 @@ extension GraphicsImage: ProtobufMessage {
}
}
package struct ResolvedShadowStyle {}

package struct RasterizationOptions {}
package protocol RBDisplayListContents {} // RenderBox.RBDisplayListContents
public struct PlatformDrawableOptions {}
public protocol PlatformDrawable : AnyObject {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// PlatformViewDefinition.swift
// DisplayListViewPlatform.swift
// OpenSwiftUICore
//
// Audited for 6.0.87
Expand Down
142 changes: 142 additions & 0 deletions Sources/OpenSwiftUICore/Render/PlatformDrawable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// PlatformDrawable.swift
// OpenSwiftUICore
//
// Audited for 6.5.4
// Status: WIP

public import CoreGraphics
public import QuartzCore
import OpenAttributeGraphShims
import OpenRenderBoxShims
import CoreAnimation_Private

// MARK: - PlatformDrawable

@_spi(DisplayList_ViewSystem)
@available(OpenSwiftUI_v6_0, *)
public protocol PlatformDrawable: AnyObject {
var options: PlatformDrawableOptions { get set }

static var allowsContentsMultiplyColor: Bool { get }

func update(content: PlatformDrawableContent?, required: Bool) -> Bool

func makeAsyncUpdate(
content: PlatformDrawableContent,
required: Bool,
layer: CALayer,
bounds: CGRect
) -> (() -> Void)?

func setContentsScale(_ scale: CGFloat)

func drawForTesting(in: RBDisplayList) -> ()
}

// MARK: - PlatformDrawableContent [WIP]

@_spi(DisplayList_ViewSystem)
@available(OpenSwiftUI_v6_0, *)
public struct PlatformDrawableContent: @unchecked Sendable {
enum Storage {
case graphicsCallback((inout GraphicsContext, CGSize) -> ())
case platformCallback((CGSize) -> ())
case displayList(DisplayList, CGPoint, Time)
case rbDisplayList(RBDisplayListContents, CGPoint)
case rbInterpolator(RBDisplayListInterpolator, Float, CGPoint)
case empty
}

private var storage: Storage = .empty

public struct State {
package var mode: DisplayList.GraphicsRenderer.PlatformViewMode

package var _renderer: DisplayList.GraphicsRenderer?

package init() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlatformDrawableContent.State is public but its initializers are package, and PlatformDrawableContent.draw(...) requires an inout State; SPI clients outside this package may have no way to create/retain a State. If draw is intended for external PlatformDrawable implementers, it likely needs a constructible state type.

🤖 Was this useful? React with 👍 or 👎

mode = .unsupported
_renderer = nil
}

package init(platformViewMode: DisplayList.GraphicsRenderer.PlatformViewMode) {
mode = platformViewMode
_renderer = nil
}

package mutating func renderer() -> DisplayList.GraphicsRenderer {
guard let _renderer else {
let render = DisplayList.GraphicsRenderer(platformViewMode: mode)
_renderer = render
return render
}
return _renderer
}
}

public init() {
_openSwiftUIEmptyStub()
}

public func draw(
in ctx: CGContext,
size: CGSize,
contentsScale: CGFloat,
state: inout PlatformDrawableContent.State
) {
_openSwiftUIUnimplementedFailure()
}

public func draw(
in list: RBDisplayList,
size: CGSize,
state: inout PlatformDrawableContent.State
) {
_openSwiftUIUnimplementedFailure()
}
}

@_spi(DisplayList_ViewSystem)
@available(*, unavailable)
extension PlatformDrawableContent.State: Sendable {}

// MARK: - PlatformDrawableOptions [Blocked by RBLayer]

@_spi(DisplayList_ViewSystem)
@available(OpenSwiftUI_v6_0, *)
public struct PlatformDrawableOptions: Equatable, Sendable {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PlatformDrawableOptions is public SPI and PlatformDrawable.options is get set, but there’s no public/SPI initializer (and base is internal), which can make it impossible for external adopters to initialize their stored options. If the intent is framework-owned mutation only, consider making that contract explicit.

🤖 Was this useful? React with 👍 or 👎

var base: RasterizationOptions

public var isAccelerated: Bool {
base.isAccelerated
}

public var isOpaque: Bool {
base.isOpaque
}

public var rendersAsynchronously: Bool {
base.rendersAsynchronously
}

public var rendersFirstFrameAsynchronously: Bool {
base.rendersFirstFrameAsynchronously
}

public var caLayerContentsFormat: CALayerContentsFormat {
var format = CALayerContentsFormat.automatic
if base.flags.contains(.rgbaContext) {
format = .RGBA8Uint
}
if base.flags.contains(.alphaOnly) {
format = .A8
}
return format
}

public func update(rbLayer: AnyObject) {
// TODO: RBLayer
_openSwiftUIUnimplementedFailure()
}
}
181 changes: 181 additions & 0 deletions Sources/OpenSwiftUICore/Render/RasterizationOptions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
//
// RasterizationOptions.swift
// OpenSwiftUICore
//
// Audited for 6.5.4
// Status: WIP

// MARK: - ColorRenderingMode

/// The set of possible working color spaces for color-compositing operations.
///
/// Each color space guarantees the preservation of a particular range of color
/// values.
public enum ColorRenderingMode: Sendable {

/// The non-linear sRGB working color space.
///
/// Color component values outside the range `[0, 1]` produce undefined
/// results. This color space is gamma corrected.
case nonLinear

/// The linear sRGB working color space.
///
/// Color component values outside the range `[0, 1]` produce undefined
/// results. This color space isn't gamma corrected.
case linear

/// The extended linear sRGB working color space.
///
/// Color component values outside the range `[0, 1]` are preserved.
/// This color space isn't gamma corrected.
case extendedLinear
}

extension ColorRenderingMode: ProtobufEnum {
package var protobufValue: UInt {
switch self {
case .nonLinear: return 0
case .linear: return 1
case .extendedLinear: return 2
}
}

package init?(protobufValue value: UInt) {
switch value {
case 0: self = .nonLinear
case 1: self = .linear
case 2: self = .extendedLinear
default: return nil
}
}
}

// MARK: - RasterizationOptions [WIP]

package struct RasterizationOptions: Equatable {
package struct Flags: OptionSet {
package let rawValue: UInt32

package init(rawValue: UInt32) {
self.rawValue = rawValue
}

package static let isAccelerated: RasterizationOptions.Flags = .init(rawValue: 1 << 0)

package static let isOpaque: RasterizationOptions.Flags = .init(rawValue: 1 << 1)

package static let rendersAsynchronously: RasterizationOptions.Flags = .init(rawValue: 1 << 2)

package static let prefersDisplayCompositing: RasterizationOptions.Flags = .init(rawValue: 1 << 3)

package static let rendersFirstFrameAsync: RasterizationOptions.Flags = .init(rawValue: 1 << 4)

package static let allowsPackedDrawable: RasterizationOptions.Flags = .init(rawValue: 1 << 5)

package static let alphaOnly: RasterizationOptions.Flags = .init(rawValue: 1 << 6)

package static let requiresLayer: RasterizationOptions.Flags = .init(rawValue: 1 << 7)

package static let rgbaContext: RasterizationOptions.Flags = .init(rawValue: 1 << 8)

package static let highRes: RasterizationOptions.Flags = .init(rawValue: 1 << 9)

package static let defaultFlags: RasterizationOptions.Flags = [.allowsPackedDrawable, .requiresLayer]
}

package var colorMode: ColorRenderingMode

package var rbColorMode: Int32?

package var flags: RasterizationOptions.Flags

package var maxDrawableCount: Int8

package init(
colorMode: ColorRenderingMode = .nonLinear,
rbColorMode: Int32? = nil,
flags: RasterizationOptions.Flags = .defaultFlags,
maxDrawableCount: Int8 = 3
) {
self.colorMode = colorMode
self.rbColorMode = rbColorMode
self.flags = flags
self.maxDrawableCount = maxDrawableCount
}

package var isAccelerated: Bool {
get { flags.contains(.isAccelerated) }
set { flags.setValue(newValue, for: .isAccelerated) }
}

package var isOpaque: Bool {
get { flags.contains(.isOpaque) }
set { flags.setValue(newValue, for: .isOpaque) }
}

package var rendersAsynchronously: Bool {
get { flags.contains(.rendersAsynchronously) }
set { flags.setValue(newValue, for: .rendersAsynchronously) }
}

package var rendersFirstFrameAsynchronously: Bool {
get { flags.contains(.rendersFirstFrameAsync) }
set { flags.setValue(newValue, for: .rendersFirstFrameAsync) }
}

package var prefersDisplayCompositing: Bool {
get { flags.contains(.prefersDisplayCompositing) }
set { flags.setValue(newValue, for: .prefersDisplayCompositing) }
}

package var allowsPackedDrawable: Bool {
get { flags.contains(.allowsPackedDrawable) }
set { flags.setValue(newValue, for: .allowsPackedDrawable) }
}

package var resolvedColorMode: RBColorMode {
_openSwiftUIUnimplementedFailure()
}

package var colorSpace: RBColorSpace {
_openSwiftUIUnimplementedFailure()
}

package var alphaOnly: Bool {
get { flags.contains(.alphaOnly) }
set { flags.setValue(newValue, for: .alphaOnly) }
}

package var requiresLayer: Bool {
get { flags.contains(.requiresLayer) }
set { flags.setValue(newValue, for: .requiresLayer) }
}
}

extension RasterizationOptions: ProtobufMessage {
package func encode(to encoder: inout ProtobufEncoder) {
encoder.enumField(1, colorMode, defaultValue: .nonLinear)
if let rbColorMode {
encoder.intField(2, Int(rbColorMode))
}
encoder.intField(3, Int(flags.rawValue))
encoder.intField(4, Int(maxDrawableCount))
}

package init(from decoder: inout ProtobufDecoder) throws {
var options = RasterizationOptions()
while let field = try decoder.nextField() {
switch field.tag {
case 1: options.colorMode = try decoder.enumField(field) ?? .nonLinear
case 2: options.rbColorMode = Int32(try decoder.intField(field))
case 3: options.flags = Flags(rawValue: UInt32(try decoder.intField(field)))
case 4: options.maxDrawableCount = Int8(try decoder.intField(field))
Comment on lines +171 to +173
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Int32/UInt32/Int8(...) conversions in protobuf decoding will trap on out-of-range (or negative) values, so malformed/forward-version data could crash decoding. Consider validating/clamping before converting so decode failures are handled as errors instead of traps.

🤖 Was this useful? React with 👍 or 👎

default: try decoder.skipField(field)
}
}
self = options
}
}

// TODO: DrawingGroupEffect
Loading
Loading