skia2/modules/canvaskit/cpu.js
Michael Ludwig 1f49ceb404 Revert "[canvaskit] Change SkRects to be arrays, not objects."
Revert submission 314622

Reason for revert: breaking wasm bots
Reverted Changes:
Ia1ba13814:[canvaskit] Replace RRect objects with TypedArrays...
Ib80b15e2d:[canvaskit] Change SkRects to be arrays, not objec...
I790b2d6fc:[canvaskit] Add drawRect4f as example 'fast path' ...

Change-Id: Ie6e4c57ba412ca9ff8e4446b06681b51029da2d6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314893
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
2020-09-02 21:21:36 +00:00

104 lines
4.2 KiB
JavaScript

// Adds compile-time JS functions to augment the CanvasKit interface.
// Implementations in this file are considerate of GPU builds, i.e. some
// behavior is predicated on whether or not this is being compiled alongside
// gpu.js.
(function(CanvasKit){
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
CanvasKit._extraInitializations.push(function() {
// Takes in an html id or a canvas element
CanvasKit.MakeSWCanvasSurface = function(idOrElement) {
var canvas = idOrElement;
if (canvas.tagName !== 'CANVAS') {
// TODO(nifong): unit test
canvas = document.getElementById(idOrElement);
if (!canvas) {
throw 'Canvas with id ' + idOrElement + ' was not found';
}
}
// Maybe better to use clientWidth/height. See:
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
var surface = CanvasKit.MakeSurface(canvas.width, canvas.height);
if (surface) {
surface._canvas = canvas;
}
return surface;
};
// Don't over-write the MakeCanvasSurface set by gpu.js if it exists.
if (!CanvasKit.MakeCanvasSurface) {
CanvasKit.MakeCanvasSurface = CanvasKit.MakeSWCanvasSurface;
}
// Note that color spaces are currently not supported in CPU surfaces. due to the limitation
// canvas.getContext('2d').putImageData imposes a limitatin of using an RGBA_8888 color type.
// TODO(nifong): support WGC color spaces while still using an RGBA_8888 color type when
// on a cpu backend.
CanvasKit.MakeSurface = function(width, height) {
/* @dict */
var imageInfo = {
'width': width,
'height': height,
'colorType': CanvasKit.ColorType.RGBA_8888,
// Since we are sending these pixels directly into the HTML canvas,
// (and those pixels are un-premultiplied, i.e. straight r,g,b,a)
'alphaType': CanvasKit.AlphaType.Unpremul,
'colorSpace': CanvasKit.SkColorSpace.SRGB,
}
var pixelLen = width * height * 4; // it's 8888, so 4 bytes per pixel
// Allocate the buffer of pixels to be drawn into.
var pixelPtr = CanvasKit._malloc(pixelLen);
var surface = this._getRasterDirectSurface(imageInfo, pixelPtr, width*4);
if (surface) {
surface._canvas = null;
surface._width = width;
surface._height = height;
surface._pixelLen = pixelLen;
surface._pixelPtr = pixelPtr;
// rasterDirectSurface does not initialize the pixels, so we clear them
// to transparent black.
surface.getCanvas().clear(CanvasKit.TRANSPARENT);
}
return surface;
};
// For GPU builds, simply proxies to native code flush. For CPU builds,
// also updates the underlying HTML canvas, optionally with dirtyRect.
CanvasKit.SkSurface.prototype.flush = function(dirtyRect) {
this._flush();
// Do we have an HTML canvas to write the pixels to?
// We will not if this a GPU build or a raster surface, for example.
if (this._canvas) {
var pixels = new Uint8ClampedArray(CanvasKit.HEAPU8.buffer, this._pixelPtr, this._pixelLen);
var imageData = new ImageData(pixels, this._width, this._height);
if (!dirtyRect) {
this._canvas.getContext('2d').putImageData(imageData, 0, 0);
} else {
this._canvas.getContext('2d').putImageData(imageData, 0, 0,
dirtyRect.fLeft, dirtyRect.fTop,
dirtyRect.fRight - dirtyRect.fLeft,
dirtyRect.fBottom - dirtyRect.fTop);
}
}
};
// Call dispose() instead of delete to clean up the underlying memory
CanvasKit.SkSurface.prototype.dispose = function() {
if (this._pixelPtr) {
CanvasKit._free(this._pixelPtr);
}
this.delete();
}
CanvasKit.currentContext = CanvasKit.currentContext || function() {
// no op if this is a cpu-only build.
};
CanvasKit.setCurrentContext = CanvasKit.setCurrentContext || function() {
// no op if this is a cpu-only build.
};
});
}(Module)); // When this file is loaded in, the high level object is "Module";