[canvaskit] Use Raster instead of RasterDirect for Canvas2D surface
This also refactors some internal names to be more consistent with the normal naming convention. Bug: skia:10717 Change-Id: I69a0d95aaca359e121b3ff84002d0b5f7cadb260 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/334041 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Nathaniel Nifong <nifong@google.com>
This commit is contained in:
parent
e4387382c2
commit
15d7a38b04
@ -31,6 +31,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- `CanvasKit.Shader.Blend`, `...Color`, and `...Lerp` have been renamed to
|
||||
`CanvasKit.Shader.MakeBlend`, `...MakeColor` and `...MakeLerp` to align with naming conventions.
|
||||
The old names will be removed in an upcoming release.
|
||||
- `CanvasKit.MakeSurface` no longer uses a RasterDirect surface internally. This means
|
||||
creating Images from this raster surface should be faster.
|
||||
- `CanvasKit.MakeSurface` is Premul instead of Unpremul, which should be more performant when
|
||||
drawing.
|
||||
|
||||
### Removed
|
||||
- `CanvasKit.MakePathFromCmds`; Was deprecated in favor of `CanvasKit.Path.MakeFromCmds`.
|
||||
|
4
modules/canvaskit/canvaskit/types/index.d.ts
vendored
4
modules/canvaskit/canvaskit/types/index.d.ts
vendored
@ -197,8 +197,8 @@ export interface CanvasKit {
|
||||
opts?: WebGLOptions): Surface | null;
|
||||
|
||||
/**
|
||||
* Returns a CPU backed surface with the given dimensions, an SRGB colorspace, Unpremul
|
||||
* alphaType and 8888 color type. The pixels belonging to this surface will be in memory and
|
||||
* Returns a CPU backed surface with the given dimensions, an SRGB colorspace, Premul
|
||||
* alphaType and 8888 color type. The pixels belonging to this surface will be in memory and
|
||||
* not visible.
|
||||
* @param width - number of pixels of the width of the drawable area.
|
||||
* @param height - number of pixels of the height of the drawable area.
|
||||
|
@ -763,13 +763,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
sk_sp<SkData> bytes = SkData::MakeFromMalloc(imgData, length);
|
||||
return SkImage::MakeFromEncoded(std::move(bytes));
|
||||
}), allow_raw_pointers());
|
||||
function("_getRasterDirectSurface", optional_override([](const SimpleImageInfo ii,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
size_t rowBytes)->sk_sp<SkSurface> {
|
||||
uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
|
||||
SkImageInfo imageInfo = toSkImageInfo(ii);
|
||||
return SkSurface::MakeRasterDirect(imageInfo, pixels, rowBytes, nullptr);
|
||||
}), allow_raw_pointers());
|
||||
|
||||
function("getDataBytes", &getSkDataBytes, allow_raw_pointers());
|
||||
|
||||
@ -1019,7 +1012,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("markCTM", optional_override([](SkCanvas& self, std::string marker) {
|
||||
self.markCTM(marker.c_str());
|
||||
}))
|
||||
|
||||
.function("_readPixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
size_t dstRowBytes, int srcX, int srcY) {
|
||||
@ -1028,6 +1020,18 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
|
||||
return self.readPixels(dstInfo, pixels, dstRowBytes, srcX, srcY);
|
||||
}))
|
||||
// This is an internal override for quickly flushing to a Canvas2D. We hard-code the
|
||||
// image info values so we don't need to pass them all over the wire.
|
||||
.function("_readPixelsForCanvas2D", optional_override([](SkCanvas& self,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
int width, int height) {
|
||||
uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
|
||||
// Reminder: Canvas2D's putImageData is unpremul
|
||||
SkImageInfo dstInfo = SkImageInfo::Make(width, height,
|
||||
SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kUnpremul_SkAlphaType);
|
||||
|
||||
return self.readPixels(dstInfo, pixels, width*4, 0, 0);
|
||||
}))
|
||||
.function("restore", &SkCanvas::restore)
|
||||
.function("restoreToCount", &SkCanvas::restoreToCount)
|
||||
.function("rotate", select_overload<void (SkScalar, SkScalar, SkScalar)>(&SkCanvas::rotate))
|
||||
@ -1651,6 +1655,17 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
|
||||
class_<SkSurface>("Surface")
|
||||
.smart_ptr<sk_sp<SkSurface>>("sk_sp<Surface>")
|
||||
.class_function("_makeRaster", optional_override([](const SimpleImageInfo ii)->sk_sp<SkSurface> {
|
||||
SkImageInfo imageInfo = toSkImageInfo(ii);
|
||||
return SkSurface::MakeRaster(imageInfo);
|
||||
}), allow_raw_pointers())
|
||||
.class_function("_makeRasterDirect", optional_override([](const SimpleImageInfo ii,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
size_t rowBytes)->sk_sp<SkSurface> {
|
||||
uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
|
||||
SkImageInfo imageInfo = toSkImageInfo(ii);
|
||||
return SkSurface::MakeRasterDirect(imageInfo, pixels, rowBytes, nullptr);
|
||||
}), allow_raw_pointers())
|
||||
.function("_flush", optional_override([](SkSurface& self) {
|
||||
self.flushAndSubmit(false);
|
||||
}))
|
||||
|
@ -7,19 +7,27 @@
|
||||
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';
|
||||
}
|
||||
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';
|
||||
}
|
||||
}
|
||||
var width = canvas.width;
|
||||
var height = canvas.height;
|
||||
// Maybe better to use clientWidth/height. See:
|
||||
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
|
||||
var surface = CanvasKit.MakeSurface(canvas.width, canvas.height);
|
||||
var surface = CanvasKit.MakeSurface(width, height);
|
||||
if (surface) {
|
||||
// Set the properties we need in order to flush to the canvas.
|
||||
surface._canvas = canvas;
|
||||
surface._width = width;
|
||||
surface._height = height;
|
||||
surface._pixelLen = width * height * 4; // it's 8888, so 4 bytes per pixel
|
||||
// Allocate the buffer of pixels that will be used for readPixels into.
|
||||
surface._pixelPtr = CanvasKit._malloc(surface._pixelLen);
|
||||
}
|
||||
return surface;
|
||||
};
|
||||
@ -34,38 +42,18 @@
|
||||
// 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,
|
||||
'alphaType': CanvasKit.AlphaType.Premul,
|
||||
'colorSpace': CanvasKit.ColorSpace.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);
|
||||
|
||||
// TODO(kjlubick) don't use RDS, as it will always copy if snapping off an SkImage.
|
||||
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;
|
||||
};
|
||||
return CanvasKit.Surface._makeRaster(imageInfo);
|
||||
};
|
||||
|
||||
CanvasKit.MakeRasterDirectSurface = function(imageInfo, mallocObj, bytesPerRow) {
|
||||
return this._getRasterDirectSurface(imageInfo, mallocObj['byteOffset'], bytesPerRow);
|
||||
return CanvasKit.Surface._makeRasterDirect(imageInfo, mallocObj['byteOffset'], bytesPerRow);
|
||||
};
|
||||
|
||||
// For GPU builds, simply proxies to native code flush. For CPU builds,
|
||||
@ -73,8 +61,10 @@
|
||||
CanvasKit.Surface.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.
|
||||
// We will not have a canvas if this a GPU build, for example.
|
||||
if (this._canvas) {
|
||||
// TODO(kjlubick) can this be modified to only read the pixels in dirtyRect?
|
||||
this.getCanvas()._readPixelsForCanvas2D(this._pixelPtr, this._width, this._height);
|
||||
var pixels = new Uint8ClampedArray(CanvasKit.HEAPU8.buffer, this._pixelPtr, this._pixelLen);
|
||||
var imageData = new ImageData(pixels, this._width, this._height);
|
||||
|
||||
|
@ -84,7 +84,6 @@ var CanvasKit = {
|
||||
_decodeAnimatedImage: function() {},
|
||||
_decodeImage: function() {},
|
||||
_drawShapedText: function() {},
|
||||
_getRasterDirectSurface: function() {},
|
||||
|
||||
// The testing object is meant to expose internal functions
|
||||
// for more fine-grained testing, e.g. parseColor
|
||||
@ -271,6 +270,7 @@ var CanvasKit = {
|
||||
_getLocalToDevice: function() {},
|
||||
_getTotalMatrix: function() {},
|
||||
_readPixels: function() {},
|
||||
_readPixelsForCanvas2D: function() {},
|
||||
_saveLayer: function() {},
|
||||
_writePixels: function() {},
|
||||
delete: function() {},
|
||||
@ -647,6 +647,8 @@ var CanvasKit = {
|
||||
// private API
|
||||
_flush: function() {},
|
||||
_makeImageSnapshot: function() {},
|
||||
_makeRaster: function() {},
|
||||
_makeRasterDirect: function() {},
|
||||
delete: function() {},
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user