1// Adds compile-time JS functions to augment the CanvasKit interface. 2// Specifically, anything that should only be on the WebGL version of canvaskit. 3// Functions in this file are supplemented by cpu.js. 4(function(CanvasKit){ 5 CanvasKit._extraInitializations = CanvasKit._extraInitializations || []; 6 CanvasKit._extraInitializations.push(function() { 7 CanvasKit.MakeGPUDeviceContext = function(device) { 8 if (!device) { 9 return null; 10 } 11 12 // This allows native code to access this device by calling 13 // `emscripten_webgpu_get_device().` 14 CanvasKit.preinitializedWebGPUDevice = device; 15 var context = this._MakeGrContext(); 16 context._device = device; 17 18 return context; 19 }; 20 21 CanvasKit.MakeGPUCanvasContext = function(devCtx, canvas, opts) { 22 var canvasCtx = canvas.getContext('webgpu'); 23 if (!canvasCtx) { 24 return null; 25 } 26 27 let format = (opts && opts.format) ? opts.format : navigator.gpu.getPreferredCanvasFormat(); 28 // GPUCanvasConfiguration 29 canvasCtx.configure({ 30 device: devCtx._device, 31 format: format, 32 alphaMode: (opts && opts.alphaMode) ? opts.alphaMode : undefined, 33 }); 34 35 var context = { 36 '_inner': canvasCtx, 37 '_deviceContext': devCtx, 38 '_textureFormat': format, 39 }; 40 context['requestAnimationFrame'] = function(callback) { 41 requestAnimationFrame(function() { 42 const surface = CanvasKit.MakeGPUCanvasSurface(context); 43 if (!surface) { 44 console.error('Failed to initialize Surface for current canvas swapchain texture'); 45 return; 46 } 47 callback(surface.getCanvas()); 48 surface.flush(); 49 surface.dispose(); 50 }); 51 }; 52 return context; 53 }; 54 55 CanvasKit.MakeGPUCanvasSurface = function(canvasCtx, colorSpace, width, height) { 56 let context = canvasCtx._inner; 57 if (!width) { 58 width = context.canvas.width; 59 } 60 if (!height) { 61 height = context.canvas.height; 62 } 63 let surface = this.MakeGPUTextureSurface(canvasCtx._deviceContext, 64 context.getCurrentTexture(), 65 canvasCtx._textureFormat, 66 width, height, colorSpace); 67 surface._canvasContext = canvasCtx; 68 return surface; 69 }; 70 71 CanvasKit.MakeGPUTextureSurface = function (devCtx, texture, textureFormat, width, height, colorSpace) { 72 colorSpace = colorSpace || null; 73 74 // JsValStore and WebGPU are objects in Emscripten's library_html5_webgpu.js utility 75 // library. JsValStore allows a WebGPU object to be imported by native code by calling the 76 // various `emscripten_webgpu_import_*` functions. 77 // 78 // The CanvasKit WASM module is responsible for removing entries from the value store by 79 // calling `emscripten_webgpu_release_js_handle` after importing the object. 80 // 81 // (see 82 // https://github.com/emscripten-core/emscripten/blob/0e63f74f36b06849ef1c777b130783a43316ade0/src/library_html5_webgpu.js 83 // for reference) 84 return this._MakeGPUTextureSurface( 85 devCtx, 86 this.JsValStore.add(texture), 87 this.WebGPU.TextureFormat.indexOf(textureFormat), 88 width, height, 89 colorSpace); 90 }; 91 92 CanvasKit.Surface.prototype.assignCurrentSwapChainTexture = function() { 93 // This feature is only supported for a Surface that was created via MakeGPUCanvasSurface. 94 if (!this._canvasContext) { 95 console.log('Surface is not bound to a canvas context'); 96 return false; 97 } 98 let ctx = this._canvasContext._inner; 99 return this._replaceBackendTexture( 100 CanvasKit.JsValStore.add(ctx.getCurrentTexture()), 101 CanvasKit.WebGPU.TextureFormat.indexOf(this._canvasContext._textureFormat), 102 ctx.canvas.width, ctx.canvas.height); 103 }; 104 105 CanvasKit.Surface.prototype.requestAnimationFrame = function(callback, dirtyRect) { 106 if (!this.reportBackendTypeIsGPU()) { 107 return this._requestAnimationFrameInternal(callback, dirtyRect); 108 } 109 110 return requestAnimationFrame(function() { 111 // Replace the render target of the Surface with the current swapchain surface if this is 112 // bound to a canvas context. 113 if (this._canvasContext && !this.assignCurrentSwapChainTexture()) { 114 console.log('failed to replace GPU backend texture'); 115 return; 116 } 117 callback(this.getCanvas()); 118 this.flush(dirtyRect); 119 }.bind(this)); 120 }; 121 122 CanvasKit.Surface.prototype.drawOnce = function(callback, dirtyRect) { 123 if (!this.reportBackendTypeIsGPU()) { 124 this._drawOnceInternal(callback, dirtyRect); 125 return; 126 } 127 128 requestAnimationFrame(function() { 129 // Replace the render target of the Surface with the current swapchain surface if this is 130 // bound to a canvas context. 131 if (this._canvasContext && !this.assignCurrentSwapChainTexture()) { 132 console.log('failed to replace GPU backend texture'); 133 return; 134 } 135 callback(this.getCanvas()); 136 this.flush(dirtyRect); 137 this.dispose(); 138 }.bind(this)); 139 }; 140 }); 141}(Module)); // When this file is loaded in, the high level object is "Module". 142