Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 1 | // Adds compile-time JS functions to handle creation and flushing of wasm's offscreen buffer |
| 2 | // to a visible element on the page. |
| 3 | (function(DebuggerView){ |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 4 | // Takes a canvas element |
| 5 | DebuggerView.MakeSWCanvasSurface = function(canvas) { |
| 6 | // Set the canvas element to have a 2d non-gpu context. (constant until element is destroyed) |
| 7 | // We don't need the context in this scope, we just want the side effect. |
| 8 | canvas.getContext('2d', { |
| 9 | alpha: true, |
| 10 | depth: false |
| 11 | }); |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 12 | // Maybe better to use clientWidth/height. See: |
| 13 | // https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 14 | var surface = DebuggerView.MakeSurface(canvas.width, canvas.height); |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 15 | if (surface) { |
| 16 | surface._canvas = canvas; |
| 17 | } |
Nathaniel Nifong | 46f5ee1 | 2019-03-15 10:58:31 -0400 | [diff] [blame] | 18 | console.log('Made HTML Canvas Surface'); |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 19 | return surface; |
| 20 | }; |
| 21 | |
| 22 | // Don't over-write the MakeCanvasSurface set by gpu.js if it exists. |
| 23 | if (!DebuggerView.MakeCanvasSurface) { |
| 24 | DebuggerView.MakeCanvasSurface = DebuggerView.MakeSWCanvasSurface; |
| 25 | } |
| 26 | |
| 27 | DebuggerView.MakeSurface = function(width, height) { |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 28 | var bufferLen = width * height * 4; // 4 bytes per pixel |
| 29 | // Allocate the buffer of pixels to be drawn into. |
| 30 | var pixelPtr = DebuggerView._malloc(bufferLen); |
| 31 | var imageInfo = { |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 32 | 'width': width, |
| 33 | 'height': height, |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 34 | // RGBA 8888 is the only pixel format we can show on an HTML canvas |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 35 | 'colorType': DebuggerView.ColorType.RGBA_8888, |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 36 | // We are sending these pixels directly into the HTML canvas, |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 37 | // (and those pixels are un-premultiplied, i.e. straight r,g,b,a) |
| 38 | 'alphaType': DebuggerView.AlphaType.Unpremul, |
| 39 | } |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 40 | var surface = this._getRasterDirectSurface(imageInfo, pixelPtr, width * 4); |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 41 | if (surface) { |
| 42 | surface._canvas = null; |
| 43 | surface._width = width; |
| 44 | surface._height = height; |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 45 | surface._bufferLen = bufferLen; |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 46 | |
| 47 | surface._pixelPtr = pixelPtr; |
| 48 | // rasterDirectSurface does not initialize the pixels, so we clear them |
| 49 | // to transparent black. |
| 50 | surface.getCanvas().clear(DebuggerView.TRANSPARENT); |
| 51 | } |
| 52 | return surface; |
| 53 | }; |
| 54 | |
| 55 | |
| 56 | DebuggerView.onRuntimeInitialized = function() { |
| 57 | |
| 58 | DebuggerView.SkSurface.prototype.flush = function() { |
| 59 | this._flush(); |
| 60 | // Do we have an HTML canvas to write the pixels to? |
| 61 | // We will not if this a GPU build or a raster surface, for example. |
| 62 | if (this._canvas) { |
Nathaniel Nifong | de5df65 | 2019-03-28 13:08:51 -0400 | [diff] [blame] | 63 | var pixels = new Uint8ClampedArray(DebuggerView.buffer, this._pixelPtr, this._bufferLen); |
| 64 | var imageData = new ImageData(pixels, this._width, this._height); |
Nathaniel Nifong | ad5f6cd | 2019-03-05 10:45:40 -0500 | [diff] [blame] | 65 | this._canvas.getContext('2d').putImageData(imageData, 0, 0); |
| 66 | } |
| 67 | }; |
| 68 | |
| 69 | // Call dispose() instead of delete to clean up the underlying memory |
| 70 | DebuggerView.SkSurface.prototype.dispose = function() { |
| 71 | if (this._pixelPtr) { |
| 72 | DebuggerView._free(this._pixelPtr); |
| 73 | } |
| 74 | this.delete(); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | DebuggerView.currentContext = DebuggerView.currentContext || function() { |
| 79 | // no op if this is a cpu-only build. |
| 80 | }; |
| 81 | |
| 82 | DebuggerView.setCurrentContext = DebuggerView.setCurrentContext || function() { |
| 83 | // no op if this is a cpu-only build. |
| 84 | }; |
| 85 | }(Module)); // When this file is loaded in, the high level object is "Module"; |