跳到主要内容

GPU Canvas

GPU Canvas 用于在 Apple 运行时中启用 3D 内容。它通过 Swift Concurrency API 提供,并在创建 Worker 时进行配置。该设置对该 worker 加载的每一个 File 以及由这些文件创建的每一个 Rive 对象生效。

渲染 3D 内容必须启用 GPU Canvas。

启用 GPU Canvas

创建 worker 时,传入 enableGPUCanvastrue 的配置:

let worker = try await Worker(
configuration: .init(enableGPUCanvas: true)
)

Worker 的 GPU Canvas 设置在其整个生命周期内是固定的。请在加载任何需要 GPU Canvas 或 3D 支持的文件之前启用它。

使用该 worker 创建的每个 File 都会沿用同一设置:

let worker = try await Worker(
configuration: .init(enableGPUCanvas: true)
)
let file = try await File(
source: .local("my_file", Bundle.main),
worker: worker
)
let rive = try await Rive(file: file)

创建 RiveUIViewRiveUIViewRepresentableAsyncRiveUIViewRepresentable 时无需额外配置。每个视图都会从其 Rive 对象所关联的 worker 继承 GPU Canvas 设置。

默认行为

GPU Canvas 默认处于关闭状态。当你的内容不需要它时,仍可按不带配置的方式创建 worker:

let worker = try await Worker()

共享 GPU Canvas Worker

当多个文件或视图可以共用同一个 worker 时,可以共享一个 GPU Canvas worker。下面是一个示例实现。

下面的 AsyncShared 以及 Worker 扩展属于应用层的辅助代码,并不包含在 RiveRuntime 中。

📌 AsyncShared.swift

/// 懒加载并缓存一个值。初始化失败后可以重试。
@MainActor
final class AsyncShared<Value> {
private let makeValue: @MainActor () async throws -> Value
private var cachedValue: Value?
private var loadingTask: Task<Value, Error>?

init(_ makeValue: @escaping @MainActor () async throws -> Value) {
self.makeValue = makeValue
}

func value() async throws -> Value {
if let cachedValue {
return cachedValue
}

let task = loadingTask ?? Task {
defer { loadingTask = nil }
let value = try await makeValue()
cachedValue = value
return value
}
loadingTask = task

return try await task.value
}
}

📌 AsyncShared+Worker.swift

import RiveRuntime

extension AsyncShared where Value == Worker {
convenience init(configuration: Worker.Configuration = .init()) {
self.init {
try await Worker(configuration: configuration)
}
}
}

extension Worker {
@MainActor
private static let sharedWorker = AsyncShared<Worker>()

@MainActor
private static let sharedGPUCanvasWorker = AsyncShared<Worker>(
configuration: .init(enableGPUCanvas: true)
)

@MainActor
static func shared() async throws -> Worker {
try await sharedWorker.value()
}

@MainActor
static func sharedGPUCanvas() async throws -> Worker {
try await sharedGPUCanvasWorker.value()
}
}

在加载需要 GPU Canvas 的文件时,使用 Worker.sharedGPUCanvas()

let worker = try await Worker.sharedGPUCanvas()
let file = try await File(
source: .local("my_file", Bundle.main),
worker: worker
)
let rive = try await Rive(file: file)

完整的设置示例请参阅 Apple 快速开始

看完还有疑问?进群交流下!
与众多 Rive 创作者、开发者一起交流探讨与答疑解惑。
加入交流群