142 lines
5.6 KiB
JavaScript
142 lines
5.6 KiB
JavaScript
// Adds compile-time JS functions to augment the CanvasKit interface.
|
|
// Specifically, anything that should only be on the WebGL version of canvaskit.
|
|
// Functions in this file are supplemented by cpu.js.
|
|
(function(CanvasKit){
|
|
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
|
|
CanvasKit._extraInitializations.push(function() {
|
|
CanvasKit.MakeGPUDeviceContext = function(device) {
|
|
if (!device) {
|
|
return null;
|
|
}
|
|
|
|
// This allows native code to access this device by calling
|
|
// `emscripten_webgpu_get_device().`
|
|
CanvasKit.preinitializedWebGPUDevice = device;
|
|
var context = this._MakeGrContext();
|
|
context._device = device;
|
|
|
|
return context;
|
|
};
|
|
|
|
CanvasKit.MakeGPUCanvasContext = function(devCtx, canvas, opts) {
|
|
var canvasCtx = canvas.getContext('webgpu');
|
|
if (!canvasCtx) {
|
|
return null;
|
|
}
|
|
|
|
let format = (opts && opts.format) ? opts.format : navigator.gpu.getPreferredCanvasFormat();
|
|
// GPUCanvasConfiguration
|
|
canvasCtx.configure({
|
|
device: devCtx._device,
|
|
format: format,
|
|
alphaMode: (opts && opts.alphaMode) ? opts.alphaMode : undefined,
|
|
});
|
|
|
|
var context = {
|
|
'_inner': canvasCtx,
|
|
'_deviceContext': devCtx,
|
|
'_textureFormat': format,
|
|
};
|
|
context['requestAnimationFrame'] = function(callback) {
|
|
requestAnimationFrame(function() {
|
|
const surface = CanvasKit.MakeGPUCanvasSurface(context);
|
|
if (!surface) {
|
|
console.error('Failed to initialize Surface for current canvas swapchain texture');
|
|
return;
|
|
}
|
|
callback(surface.getCanvas());
|
|
surface.flush();
|
|
surface.dispose();
|
|
});
|
|
};
|
|
return context;
|
|
};
|
|
|
|
CanvasKit.MakeGPUCanvasSurface = function(canvasCtx, colorSpace, width, height) {
|
|
let context = canvasCtx._inner;
|
|
if (!width) {
|
|
width = context.canvas.width;
|
|
}
|
|
if (!height) {
|
|
height = context.canvas.height;
|
|
}
|
|
let surface = this.MakeGPUTextureSurface(canvasCtx._deviceContext,
|
|
context.getCurrentTexture(),
|
|
canvasCtx._textureFormat,
|
|
width, height, colorSpace);
|
|
surface._canvasContext = canvasCtx;
|
|
return surface;
|
|
};
|
|
|
|
CanvasKit.MakeGPUTextureSurface = function (devCtx, texture, textureFormat, width, height, colorSpace) {
|
|
colorSpace = colorSpace || null;
|
|
|
|
// JsValStore and WebGPU are objects in Emscripten's library_html5_webgpu.js utility
|
|
// library. JsValStore allows a WebGPU object to be imported by native code by calling the
|
|
// various `emscripten_webgpu_import_*` functions.
|
|
//
|
|
// The CanvasKit WASM module is responsible for removing entries from the value store by
|
|
// calling `emscripten_webgpu_release_js_handle` after importing the object.
|
|
//
|
|
// (see
|
|
// https://github.com/emscripten-core/emscripten/blob/0e63f74f36b06849ef1c777b130783a43316ade0/src/library_html5_webgpu.js
|
|
// for reference)
|
|
return this._MakeGPUTextureSurface(
|
|
devCtx,
|
|
this.JsValStore.add(texture),
|
|
this.WebGPU.TextureFormat.indexOf(textureFormat),
|
|
width, height,
|
|
colorSpace);
|
|
};
|
|
|
|
CanvasKit.Surface.prototype.assignCurrentSwapChainTexture = function() {
|
|
// This feature is only supported for a Surface that was created via MakeGPUCanvasSurface.
|
|
if (!this._canvasContext) {
|
|
console.log('Surface is not bound to a canvas context');
|
|
return false;
|
|
}
|
|
let ctx = this._canvasContext._inner;
|
|
return this._replaceBackendTexture(
|
|
CanvasKit.JsValStore.add(ctx.getCurrentTexture()),
|
|
CanvasKit.WebGPU.TextureFormat.indexOf(this._canvasContext._textureFormat),
|
|
ctx.canvas.width, ctx.canvas.height);
|
|
};
|
|
|
|
CanvasKit.Surface.prototype.requestAnimationFrame = function(callback, dirtyRect) {
|
|
if (!this.reportBackendTypeIsGPU()) {
|
|
return this._requestAnimationFrameInternal(callback, dirtyRect);
|
|
}
|
|
|
|
return requestAnimationFrame(function() {
|
|
// Replace the render target of the Surface with the current swapchain surface if this is
|
|
// bound to a canvas context.
|
|
if (this._canvasContext && !this.assignCurrentSwapChainTexture()) {
|
|
console.log('failed to replace GPU backend texture');
|
|
return;
|
|
}
|
|
callback(this.getCanvas());
|
|
this.flush(dirtyRect);
|
|
}.bind(this));
|
|
};
|
|
|
|
CanvasKit.Surface.prototype.drawOnce = function(callback, dirtyRect) {
|
|
if (!this.reportBackendTypeIsGPU()) {
|
|
this._drawOnceInternal(callback, dirtyRect);
|
|
return;
|
|
}
|
|
|
|
requestAnimationFrame(function() {
|
|
// Replace the render target of the Surface with the current swapchain surface if this is
|
|
// bound to a canvas context.
|
|
if (this._canvasContext && !this.assignCurrentSwapChainTexture()) {
|
|
console.log('failed to replace GPU backend texture');
|
|
return;
|
|
}
|
|
callback(this.getCanvas());
|
|
this.flush(dirtyRect);
|
|
this.dispose();
|
|
}.bind(this));
|
|
};
|
|
});
|
|
}(Module)); // When this file is loaded in, the high level object is "Module".
|