Remove WebGPU backend
This commit is contained in:
parent
25788dae36
commit
d52d38cb3b
|
|
@ -213,7 +213,6 @@ OpenPencil is the alternative: open source (MIT), reads .fig files natively, eve
|
|||
- Grid child positioning UI — column/row span controls, grid overlay on canvas
|
||||
- Skewing and OkHCL color support
|
||||
- Windows code signing (Azure Authenticode certificates)
|
||||
- Experimental WebGPU/Graphite rendering backend
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
|
|||
|
|
@ -4,67 +4,21 @@ import { IS_BROWSER } from './constants'
|
|||
|
||||
let instance: CanvasKit | null = null
|
||||
|
||||
export type GpuBackend = 'webgl' | 'webgpu'
|
||||
|
||||
let activeBackend: GpuBackend = 'webgl'
|
||||
|
||||
export function getGpuBackend(): GpuBackend {
|
||||
return activeBackend
|
||||
}
|
||||
|
||||
export interface CanvasKitOptions {
|
||||
locateFile?: (file: string) => string
|
||||
backend?: GpuBackend
|
||||
}
|
||||
|
||||
function detectBackend(): GpuBackend {
|
||||
if (!IS_BROWSER) return 'webgl'
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
if (params.get('gpu') === 'webgpu' && 'gpu' in navigator) return 'webgpu'
|
||||
return 'webgl'
|
||||
}
|
||||
|
||||
function loadCanvasKitWebGPU(): Promise<(opts?: Record<string, unknown>) => Promise<CanvasKit>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script')
|
||||
script.src = '/canvaskit-webgpu/canvaskit.js'
|
||||
script.onload = () => {
|
||||
const init =
|
||||
'CanvasKitInit' in globalThis
|
||||
? ((globalThis as typeof globalThis & { CanvasKitInit: unknown })
|
||||
.CanvasKitInit as (opts?: {
|
||||
locateFile?: (file: string) => string
|
||||
}) => Promise<CanvasKit>)
|
||||
: null
|
||||
if (!init) return reject(new Error('CanvasKitInit not found after loading WebGPU build'))
|
||||
resolve(init)
|
||||
}
|
||||
script.onerror = () => reject(new Error('Failed to load canvaskit-webgpu/canvaskit.js'))
|
||||
document.head.appendChild(script)
|
||||
})
|
||||
}
|
||||
|
||||
export async function getCanvasKit(options?: CanvasKitOptions): Promise<CanvasKit> {
|
||||
if (instance) return instance
|
||||
|
||||
const backend = options?.backend ?? detectBackend()
|
||||
activeBackend = backend
|
||||
|
||||
const defaultLocate = (file: string) => {
|
||||
if (IS_BROWSER) return `/${file}`
|
||||
return file
|
||||
}
|
||||
|
||||
if (backend === 'webgpu') {
|
||||
const init = await loadCanvasKitWebGPU()
|
||||
instance = await init({
|
||||
locateFile: options?.locateFile ?? ((file: string) => `/canvaskit-webgpu/${file}`)
|
||||
})
|
||||
} else {
|
||||
instance = await CanvasKitInit({
|
||||
locateFile: options?.locateFile ?? defaultLocate
|
||||
})
|
||||
}
|
||||
instance = await CanvasKitInit({
|
||||
locateFile: options?.locateFile ?? defaultLocate
|
||||
})
|
||||
|
||||
return instance
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ export {
|
|||
export type { FrameCapture, NodeProfile } from './profiler'
|
||||
export { computeLayout, computeAllLayouts, setTextMeasurer } from './layout'
|
||||
export type { TextMeasurer } from './layout'
|
||||
export { getCanvasKit, getGpuBackend, type CanvasKitOptions, type GpuBackend } from './canvaskit'
|
||||
export { getCanvasKit, type CanvasKitOptions } from './canvaskit'
|
||||
export {
|
||||
FONT_WEIGHT_NAMES,
|
||||
collectFontKeys,
|
||||
|
|
|
|||
|
|
@ -1,44 +1,13 @@
|
|||
import { useRafFn, useResizeObserver } from '@vueuse/core'
|
||||
import { onMounted, onScopeDispose, type Ref } from 'vue'
|
||||
|
||||
import { getCanvasKit, getGpuBackend, SkiaRenderer } from '@open-pencil/core'
|
||||
import { getCanvasKit, SkiaRenderer } from '@open-pencil/core'
|
||||
|
||||
import { useViewportKind } from '../viewport/useViewportKind'
|
||||
|
||||
import type { Editor } from '@open-pencil/core/editor'
|
||||
import type { CanvasKit } from 'canvaskit-wasm'
|
||||
|
||||
interface WebGPUContext {
|
||||
device: GPUDevice
|
||||
deviceContext: unknown
|
||||
}
|
||||
|
||||
interface CanvasKitWebGPU {
|
||||
MakeGPUDeviceContext(device: GPUDevice): unknown
|
||||
MakeGPUCanvasContext(ctx: unknown, canvas: HTMLCanvasElement, opts?: unknown): unknown
|
||||
MakeGPUCanvasSurface(
|
||||
ctx: unknown,
|
||||
colorSpace?: unknown,
|
||||
width?: number,
|
||||
height?: number
|
||||
): ReturnType<CanvasKit['MakeSurface']>
|
||||
}
|
||||
|
||||
function asWebGPU(ck: CanvasKit): CanvasKitWebGPU {
|
||||
return ck as unknown as CanvasKitWebGPU
|
||||
}
|
||||
|
||||
async function initWebGPU(ck: CanvasKit): Promise<WebGPUContext | null> {
|
||||
if (!('gpu' in navigator)) return null
|
||||
const adapter = await navigator.gpu.requestAdapter()
|
||||
if (!adapter) return null
|
||||
const device = await adapter.requestDevice()
|
||||
// oxlint-disable-next-line typescript/no-unnecessary-condition -- WebGPU CanvasKit API may not exist at runtime
|
||||
const deviceContext = asWebGPU(ck).MakeGPUDeviceContext?.(device)
|
||||
if (!deviceContext) return null
|
||||
return { device, deviceContext }
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for {@link useCanvas}.
|
||||
*/
|
||||
|
|
@ -76,7 +45,6 @@ export function useCanvas(
|
|||
) {
|
||||
let renderer: SkiaRenderer | null = null
|
||||
let ck: CanvasKit | null = null
|
||||
let gpuCtx: WebGPUContext | null = null
|
||||
let glContext: ReturnType<CanvasKit['MakeGrContext']> | null = null
|
||||
let destroyed = false
|
||||
let dirty = true
|
||||
|
|
@ -88,17 +56,8 @@ export function useCanvas(
|
|||
if (!canvas || destroyed) return
|
||||
|
||||
ck = await getCanvasKit()
|
||||
// oxlint-disable-next-line typescript/no-unnecessary-condition -- async race: destroyed may change during await
|
||||
if (destroyed) return
|
||||
|
||||
if (getGpuBackend() === 'webgpu') {
|
||||
gpuCtx = await initWebGPU(ck)
|
||||
if (!gpuCtx) {
|
||||
console.warn('WebGPU init failed, reload without ?gpu=webgpu to use WebGL')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
await new Promise((r) => requestAnimationFrame(r))
|
||||
createSurface(canvas)
|
||||
await renderer?.loadFonts()
|
||||
|
|
@ -133,21 +92,10 @@ export function useCanvas(
|
|||
|
||||
sizeCanvas(canvas)
|
||||
|
||||
let surface
|
||||
if (getGpuBackend() === 'webgpu' && gpuCtx) {
|
||||
const gpu = asWebGPU(ck)
|
||||
const canvasCtx = gpu.MakeGPUCanvasContext(gpuCtx.deviceContext, canvas)
|
||||
surface = gpu.MakeGPUCanvasSurface(canvasCtx, ck.ColorSpace.SRGB, canvas.width, canvas.height)
|
||||
if (!surface) {
|
||||
console.error('Failed to create WebGPU surface')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
surface = makeGLSurface(canvas)
|
||||
if (!surface) {
|
||||
console.error('Failed to create WebGL surface')
|
||||
return
|
||||
}
|
||||
const surface = makeGLSurface(canvas)
|
||||
if (!surface) {
|
||||
console.error('Failed to create WebGL surface')
|
||||
return
|
||||
}
|
||||
|
||||
const glCtx = canvas.getContext('webgl2') ?? null
|
||||
|
|
|
|||
Loading…
Reference in a new issue