[canvaskit] Handle 4x4 matrix passing ourselves.
This reduces the skm44_concat benchmark from 2us to .35us, a 5x speedup. SkCanvas.concat now takes a 3x2, 3x3, or 4x4 matrix and upscales them all to 4x4. This makes concat44 redundant. Removes redundant null checks for matrices, since freeing(0) in WASM is fine like it is in C++. Change-Id: I44a776ffd0babb81d8a34f9d94ae4d7831d02b55 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281721 Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
16464c3232
commit
c1d0898d0a
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Support for DOMMatrix on all APIs that take SkMatrix (i.e. arrays or Float32Arrays of length 9).
|
||||
- Support for DOMMatrix on all APIs that take SkMatrix (i.e. arrays or Float32Arrays of length 6/9/16).
|
||||
|
||||
### Removed
|
||||
- Previously deprecated functions MakeSkDashPathEffect, MakeLinearGradientShader,
|
||||
@ -22,6 +22,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
always composed of floats.
|
||||
- localmatrix option for `SkShader.Lerp` and `SkShader.Blend`.
|
||||
|
||||
### Deprecated
|
||||
- `SkCanvas.concat44` has been folded into concat (which now takes 3x2, 3x3, or 4x4 matrices). It will
|
||||
be removed soon.
|
||||
|
||||
## [0.14.0] - 2020-03-18
|
||||
|
||||
|
@ -734,7 +734,7 @@ const curves = {
|
||||
|
||||
function drawCubeFace(canvas, m, color) {
|
||||
const trans = new CanvasKit.SkM44.translated([vSphereRadius/2, vSphereRadius/2, 0]);
|
||||
canvas.concat44(CanvasKit.SkM44.multiply(trans, m, mustInvert(trans)));
|
||||
canvas.concat(CanvasKit.SkM44.multiply(trans, m, mustInvert(trans)));
|
||||
const znormal = front(canvas.getLocalToDevice());
|
||||
if (znormal < 0) {
|
||||
return; // skip faces facing backwards
|
||||
|
@ -96,33 +96,6 @@ struct OptionalMatrix : SkMatrix {
|
||||
}
|
||||
};
|
||||
|
||||
// Experimental 4x4 matrices, also represented in JS with arrays.
|
||||
struct SimpleM44 {
|
||||
SkScalar m0, m1, m2, m3;
|
||||
SkScalar m4, m5, m6, m7;
|
||||
SkScalar m8, m9, m10, m11;
|
||||
SkScalar m12, m13, m14, m15;
|
||||
};
|
||||
|
||||
SkM44 toSkM44(const SimpleM44& sm) {
|
||||
SkM44 result(
|
||||
sm.m0, sm.m1, sm.m2, sm.m3,
|
||||
sm.m4, sm.m5, sm.m6, sm.m7,
|
||||
sm.m8, sm.m9, sm.m10, sm.m11,
|
||||
sm.m12, sm.m13, sm.m14, sm.m15);
|
||||
return result;
|
||||
}
|
||||
|
||||
SimpleM44 toSimpleM44(const SkM44& sm) {
|
||||
SimpleM44 m {
|
||||
sm.rc(0,0), sm.rc(0,1), sm.rc(0,2), sm.rc(0,3),
|
||||
sm.rc(1,0), sm.rc(1,1), sm.rc(1,2), sm.rc(1,3),
|
||||
sm.rc(2,0), sm.rc(2,1), sm.rc(2,2), sm.rc(2,3),
|
||||
sm.rc(3,0), sm.rc(3,1), sm.rc(3,2), sm.rc(3,3),
|
||||
};
|
||||
return m;
|
||||
}
|
||||
|
||||
SimpleColor4f toSimpleColor4f(const SkColor4f c) {
|
||||
SimpleColor4f color {
|
||||
c.fR, c.fG, c.fB, c.fA,
|
||||
@ -903,8 +876,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("clipRect", select_overload<void (const SkRect&, SkClipOp, bool)>(&SkCanvas::clipRect))
|
||||
.function("_concat", optional_override([](SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
|
||||
// See comment above for uintptr_t explanation
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
self.concat(localMatrix);
|
||||
//TODO(skbug.com/10108): make the JS side be column major.
|
||||
const SkScalar* sixteenMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
|
||||
SkM44 m = SkM44::RowMajor(sixteenMatrixValues);
|
||||
self.concat(m);
|
||||
}))
|
||||
.function("drawArc", &SkCanvas::drawArc)
|
||||
// _drawAtlas takes an SkColor, unlike most private functions handling color.
|
||||
@ -1043,30 +1018,47 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("_writePixels", optional_override([](SkCanvas& self, SimpleImageInfo di,
|
||||
uintptr_t /* uint8_t* */ pPtr,
|
||||
size_t srcRowBytes, int dstX, int dstY) {
|
||||
// See comment above for uintptr_t explanation
|
||||
uint8_t* pixels = reinterpret_cast<uint8_t*>(pPtr);
|
||||
SkImageInfo dstInfo = toSkImageInfo(di);
|
||||
|
||||
return self.writePixels(dstInfo, pixels, srcRowBytes, dstX, dstY);
|
||||
}))
|
||||
// 4x4 matrix functions
|
||||
.function("saveCamera", optional_override([](SkCanvas& self,
|
||||
const SimpleM44& projection, const SimpleM44& camera) {
|
||||
self.saveCamera(toSkM44(projection), toSkM44(camera));
|
||||
.function("_saveCamera", optional_override([](SkCanvas& self,
|
||||
uintptr_t /* SkScalar* */ pPtr, uintptr_t /* SkScalar* */ cPtr) {
|
||||
// See comment above for uintptr_t explanation
|
||||
const SkScalar* projectionMatrixValues = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
const SkScalar* cameraMatrixValues = reinterpret_cast<const SkScalar*>(cPtr);
|
||||
SkM44 projection = SkM44::RowMajor(projectionMatrixValues);
|
||||
SkM44 camera = SkM44::RowMajor(cameraMatrixValues);
|
||||
self.saveCamera(projection, camera);
|
||||
}))
|
||||
.function("concat44", optional_override([](SkCanvas& self, const SimpleM44& m) {
|
||||
self.concat(toSkM44(m));
|
||||
}))
|
||||
.function("getLocalToDevice", optional_override([](const SkCanvas& self)->SimpleM44 {
|
||||
// Just like with getTotalMatrix, we allocate the buffer for the 16 floats to go in from
|
||||
// interface.js, so it can also free them when its done.
|
||||
.function("_getLocalToDevice", optional_override([](const SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
|
||||
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
|
||||
if (!sixteenMatrixValues) {
|
||||
return; // matrix cannot be null
|
||||
}
|
||||
SkM44 m = self.getLocalToDevice();
|
||||
return toSimpleM44(m);
|
||||
m.getRowMajor(sixteenMatrixValues);
|
||||
}))
|
||||
.function("getLocalToWorld", optional_override([](const SkCanvas& self)->SimpleM44 {
|
||||
.function("_getLocalToWorld", optional_override([](const SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
|
||||
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
|
||||
if (!sixteenMatrixValues) {
|
||||
return; // matrix cannot be null
|
||||
}
|
||||
SkM44 m = self.experimental_getLocalToWorld();
|
||||
return toSimpleM44(m);
|
||||
m.getRowMajor(sixteenMatrixValues);
|
||||
}))
|
||||
.function("getLocalToCamera", optional_override([](const SkCanvas& self)->SimpleM44 {
|
||||
.function("_getLocalToCamera", optional_override([](const SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
|
||||
SkScalar* sixteenMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
|
||||
if (!sixteenMatrixValues) {
|
||||
return; // matrix cannot be null
|
||||
}
|
||||
SkM44 m = self.experimental_getLocalToCamera();
|
||||
return toSimpleM44(m);
|
||||
m.getRowMajor(sixteenMatrixValues);
|
||||
}));
|
||||
|
||||
class_<SkColorFilter>("SkColorFilter")
|
||||
@ -1741,12 +1733,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.field("cap", &StrokeOpts::cap)
|
||||
.field("precision", &StrokeOpts::precision);
|
||||
|
||||
value_array<SimpleM44>("SkM44")
|
||||
.element(&SimpleM44::m0).element(&SimpleM44::m1).element(&SimpleM44::m2).element(&SimpleM44::m3)
|
||||
.element(&SimpleM44::m4).element(&SimpleM44::m5).element(&SimpleM44::m6).element(&SimpleM44::m7)
|
||||
.element(&SimpleM44::m8).element(&SimpleM44::m9).element(&SimpleM44::m10).element(&SimpleM44::m11)
|
||||
.element(&SimpleM44::m12).element(&SimpleM44::m13).element(&SimpleM44::m14).element(&SimpleM44::m15);
|
||||
|
||||
value_array<SimpleColor4f>("SkColor4f")
|
||||
.element(&SimpleColor4f::r)
|
||||
.element(&SimpleColor4f::g)
|
||||
|
@ -196,6 +196,9 @@ var CanvasKit = {
|
||||
_drawAtlas: function() {},
|
||||
_drawPoints: function() {},
|
||||
_drawSimpleText: function() {},
|
||||
_getLocalToCamera: function() {},
|
||||
_getLocalToDevice: function() {},
|
||||
_getLocalToWorld: function() {},
|
||||
_getTotalMatrix: function() {},
|
||||
_readPixels: function() {},
|
||||
_writePixels: function() {},
|
||||
@ -838,9 +841,13 @@ CanvasKit.SkImage.prototype.encodeToData = function() {};
|
||||
CanvasKit.SkImage.prototype.makeShader = function() {};
|
||||
|
||||
CanvasKit.SkCanvas.prototype.concat = function() {};
|
||||
CanvasKit.SkCanvas.prototype.concat44 = function() {}; // deprecated
|
||||
CanvasKit.SkCanvas.prototype.drawAtlas = function() {};
|
||||
CanvasKit.SkCanvas.prototype.drawPoints = function() {};
|
||||
CanvasKit.SkCanvas.prototype.drawText = function() {};
|
||||
CanvasKit.SkCanvas.prototype.getLocalToCamera = function() {};
|
||||
CanvasKit.SkCanvas.prototype.getLocalToDevice = function() {};
|
||||
CanvasKit.SkCanvas.prototype.getLocalToWorld = function() {};
|
||||
CanvasKit.SkCanvas.prototype.getTotalMatrix = function() {};
|
||||
/** @return {Uint8Array} */
|
||||
CanvasKit.SkCanvas.prototype.readPixels = function() {};
|
||||
|
@ -284,8 +284,7 @@ function copy3x3MatrixToWasm(matr) {
|
||||
CanvasKit.HEAPF32.set(defaultPerspective, 6 + mPtr / 4);
|
||||
}
|
||||
} else {
|
||||
// Try as if it's a DOMMatrix. Reminder that DOMMatrix lists their
|
||||
// column first, then row.
|
||||
// Try as if it's a DOMMatrix. Reminder that DOMMatrix is column-major.
|
||||
var floats = Float32Array.of(
|
||||
matr.m11, matr.m21, matr.m41,
|
||||
matr.m12, matr.m22, matr.m42,
|
||||
@ -296,6 +295,62 @@ function copy3x3MatrixToWasm(matr) {
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
function copy4x4MatrixToWasm(matr) {
|
||||
if (!matr) {
|
||||
return nullptr;
|
||||
}
|
||||
var mPtr = CanvasKit._malloc(16 * 4); // 9 matrix scalars, each at 4 bytes.
|
||||
if (matr.length) {
|
||||
if (matr.length !== 16 && matr.length !== 6 && matr.length !== 9) {
|
||||
throw 'invalid matrix size';
|
||||
}
|
||||
if (matr.length === 16) {
|
||||
// This should be an array or typed array.
|
||||
// have to divide the pointer by 4 to "cast" it from bytes to float.
|
||||
CanvasKit.HEAPF32.set(matr, mPtr / 4);
|
||||
} else {
|
||||
// Upscale the row-major 3x3 or 3x2 matrix into a 4x4 row-major matrix
|
||||
// TODO(skbug.com/10108) This will need to change when we convert our
|
||||
// JS 4x4 to be column-major.
|
||||
var floats = Float32Array.of(
|
||||
matr[0], matr[1], 0, matr[2],
|
||||
matr[3], matr[4], 0, matr[5],
|
||||
0, 0, 0, 0,
|
||||
matr[6], matr[7], 0, matr[8]);
|
||||
if (matr.length === 6) {
|
||||
// fix perspective for the 3x2 case (from above, they will be undefined).
|
||||
floats[4*3+0]=0;
|
||||
floats[4*3+1]=0;
|
||||
floats[4*3+3]=1;
|
||||
}
|
||||
CanvasKit.HEAPF32.set(floats, mPtr / 4);
|
||||
}
|
||||
} else {
|
||||
// Try as if it's a DOMMatrix. Reminder that DOMMatrix is column-major.
|
||||
// TODO(skbug.com/10108) use toFloat32Array().
|
||||
var floats = Float32Array.of(
|
||||
matr.m11, matr.m21, matr.m31, matr.m41,
|
||||
matr.m12, matr.m22, matr.m32, matr.m42,
|
||||
matr.m13, matr.m23, matr.m33, matr.m43,
|
||||
matr.m14, matr.m24, matr.m34, matr.m44);
|
||||
// have to divide the pointer by 4 to "cast" it from bytes to float.
|
||||
CanvasKit.HEAPF32.set(floats, mPtr / 4);
|
||||
}
|
||||
return mPtr;
|
||||
}
|
||||
|
||||
// copies a 4x4 matrix at the given pointer into a JS array.
|
||||
function copy4x4MatrixFromWasm(matrPtr) {
|
||||
// read them out into an array. TODO(kjlubick): If we change SkMatrix to be
|
||||
// typedArrays, then we should return a typed array here too.
|
||||
var rv = new Array(16);
|
||||
for (var i = 0; i < 16; i++) {
|
||||
rv[i] = CanvasKit.HEAPF32[matrPtr/4 + i]; // divide by 4 to "cast" to float.
|
||||
}
|
||||
CanvasKit._free(matrPtr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Caching the Float32Arrays can save having to reallocate them
|
||||
// over and over again.
|
||||
var Float32ArrayCache = {};
|
||||
|
@ -231,8 +231,8 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
];
|
||||
}
|
||||
|
||||
// Functions for creating and manipulating 4x4 matrices. Accepted in place of SkM44 in canvas
|
||||
// methods, for the same reasons as the 3x3 matrices above.
|
||||
// Functions for creating and manipulating (row-major) 4x4 matrices. Accepted in place of
|
||||
// SkM44 in canvas methods, for the same reasons as the 3x3 matrices above.
|
||||
// ported from C++ code in SkM44.cpp
|
||||
CanvasKit.SkM44 = {};
|
||||
// Create a 4x4 identity matrix
|
||||
@ -283,10 +283,10 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
|
||||
var m = CanvasKit.SkM44.identity();
|
||||
// set each column's top three numbers
|
||||
stride(s, m, 4, 0, 0);
|
||||
stride(s, m, 4, 0, 0);
|
||||
stride(CanvasKit.SkVector.cross(s, f), m, 4, 1, 0);
|
||||
stride(CanvasKit.SkVector.mulScalar(f, -1), m, 4, 2, 0);
|
||||
stride(eyeVec, m, 4, 3, 0);
|
||||
stride(eyeVec, m, 4, 3, 0);
|
||||
|
||||
var m2 = CanvasKit.SkM44.invert(m);
|
||||
if (m2 === null) {
|
||||
@ -808,7 +808,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
CanvasKit.SkImage.prototype.makeShader = function(xTileMode, yTileMode, localMatrix) {
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
var shader = this._makeShader(xTileMode, yTileMode, localMatrixPtr);
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
return shader;
|
||||
}
|
||||
|
||||
@ -852,12 +852,17 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
// concat takes a 3x2, a 3x3, or a 4x4 matrix and upscales it (if needed) to 4x4. This is because
|
||||
// under the hood, SkCanvas uses a 4x4 matrix.
|
||||
CanvasKit.SkCanvas.prototype.concat = function(matr) {
|
||||
var matrPtr = copy3x3MatrixToWasm(matr);
|
||||
var matrPtr = copy4x4MatrixToWasm(matr);
|
||||
this._concat(matrPtr);
|
||||
matrPtr && CanvasKit._free(matrPtr);
|
||||
CanvasKit._free(matrPtr);
|
||||
}
|
||||
|
||||
// Deprecated - just use concat
|
||||
CanvasKit.SkCanvas.prototype.concat44 = CanvasKit.SkCanvas.prototype.concat;
|
||||
|
||||
// atlas is an SkImage, e.g. from CanvasKit.MakeImageFromEncoded
|
||||
// srcRects and dstXforms should be CanvasKit.SkRectBuilder and CanvasKit.RSXFormBuilder
|
||||
// or just arrays of floats in groups of 4.
|
||||
@ -940,6 +945,31 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
CanvasKit._free(ptr);
|
||||
}
|
||||
|
||||
// getLocalToCamera returns a 4x4 matrix.
|
||||
CanvasKit.SkCanvas.prototype.getLocalToCamera = function() {
|
||||
var matrPtr = CanvasKit._malloc(16 * 4); // allocate space for the matrix
|
||||
// _getLocalToCamera will copy the values into the pointer.
|
||||
this._getLocalToCamera(matrPtr);
|
||||
return copy4x4MatrixFromWasm(matrPtr);
|
||||
}
|
||||
|
||||
// getLocalToDevice returns a 4x4 matrix.
|
||||
CanvasKit.SkCanvas.prototype.getLocalToDevice = function() {
|
||||
var matrPtr = CanvasKit._malloc(16 * 4); // allocate space for the matrix
|
||||
// _getLocalToDevice will copy the values into the pointer.
|
||||
this._getLocalToDevice(matrPtr);
|
||||
return copy4x4MatrixFromWasm(matrPtr);
|
||||
}
|
||||
|
||||
// getLocalToWorld returns a 4x4 matrix.
|
||||
CanvasKit.SkCanvas.prototype.getLocalToWorld = function() {
|
||||
var matrPtr = CanvasKit._malloc(16 * 4); // allocate space for the matrix
|
||||
// _getLocalToWorld will copy the values into the pointer.
|
||||
this._getLocalToWorld(matrPtr);
|
||||
return copy4x4MatrixFromWasm(matrPtr);
|
||||
}
|
||||
|
||||
// getTotalMatrix returns the current matrix as a 3x3 matrix.
|
||||
CanvasKit.SkCanvas.prototype.getTotalMatrix = function() {
|
||||
var matrPtr = CanvasKit._malloc(9 * 4); // allocate space for the matrix
|
||||
// _getTotalMatrix will copy the values into the pointer.
|
||||
@ -982,6 +1012,14 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
CanvasKit.SkCanvas.prototype.saveCamera = function(projection, camera) {
|
||||
var pPtr = copy4x4MatrixToWasm(projection);
|
||||
var cPtr = copy4x4MatrixToWasm(camera);
|
||||
this._saveCamera(pPtr, cPtr);
|
||||
CanvasKit._free(pPtr)
|
||||
CanvasKit._free(cPtr);
|
||||
}
|
||||
|
||||
// pixels is a TypedArray. No matter the input size, it will be treated as
|
||||
// a Uint8Array (essentially, a byte array).
|
||||
CanvasKit.SkCanvas.prototype.writePixels = function(pixels, srcWidth, srcHeight,
|
||||
@ -1025,7 +1063,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
var matrPtr = copy3x3MatrixToWasm(matr);
|
||||
var imgF = CanvasKit.SkImageFilter._MakeMatrixTransform(matrPtr, filterQuality, input);
|
||||
|
||||
matrPtr && CanvasKit._free(matrPtr);
|
||||
CanvasKit._free(matrPtr);
|
||||
return imgF;
|
||||
}
|
||||
|
||||
@ -1099,7 +1137,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
var lgs = CanvasKit._MakeLinearGradientShader(start, end, colorPtr, posPtr,
|
||||
colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
CanvasKit._free(posPtr);
|
||||
return lgs;
|
||||
@ -1114,7 +1152,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
var rgs = CanvasKit._MakeRadialGradientShader(center, radius, colorPtr, posPtr,
|
||||
colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
CanvasKit._free(posPtr);
|
||||
return rgs;
|
||||
@ -1133,7 +1171,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
startAngle, endAngle, flags,
|
||||
localMatrixPtr);
|
||||
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
CanvasKit._free(posPtr);
|
||||
return sgs;
|
||||
@ -1150,7 +1188,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
start, startRadius, end, endRadius,
|
||||
colorPtr, posPtr, colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
CanvasKit._free(posPtr);
|
||||
return rgs;
|
||||
|
@ -137,7 +137,7 @@ describe('SkM44 (4x4 matrix)', () => {
|
||||
}
|
||||
|
||||
function test(ctx) {
|
||||
ctx.canvas.concat44(matr);
|
||||
ctx.canvas.concat(matr);
|
||||
}
|
||||
|
||||
function teardown(ctx) {
|
||||
|
@ -7,7 +7,7 @@ CanvasKit._extraInitializations.push(function() {
|
||||
// Our array has 4 bytes per float, so be sure to account for that before
|
||||
// sending it over the wire.
|
||||
var rts = this._makeShader(fptr, floats.length * 4, !!isOpaque, localMatrixPtr);
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
return rts;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ CanvasKit._extraInitializations.push(function() {
|
||||
// sending it over the wire.
|
||||
var rts = this._makeShaderWithChildren(fptr, floats.length * 4, !!isOpaque, childrenPointers,
|
||||
barePointers.length, localMatrixPtr);
|
||||
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
return rts;
|
||||
}
|
||||
});
|
@ -591,8 +591,8 @@ describe('Canvas Behavior', () => {
|
||||
matr = canvas.getLocalToCamera();
|
||||
expect(matr).toEqual(CanvasKit.SkM44.identity());
|
||||
|
||||
canvas.concat44(CanvasKit.SkM44.rotated([0, 1, 0], Math.PI/4));
|
||||
canvas.concat44(CanvasKit.SkM44.rotated([1, 0, 1], Math.PI/8));
|
||||
canvas.concat(CanvasKit.SkM44.rotated([0, 1, 0], Math.PI/4));
|
||||
canvas.concat(CanvasKit.SkM44.rotated([1, 0, 1], Math.PI/8));
|
||||
|
||||
const expected = CanvasKit.SkM44.multiply(
|
||||
CanvasKit.SkM44.rotated([0, 1, 0], Math.PI/4),
|
||||
@ -621,7 +621,7 @@ describe('Canvas Behavior', () => {
|
||||
CanvasKit.SkM44.rotated([0, 0, 1], Math.PI/16),
|
||||
CanvasKit.SkM44.translated([-CANVAS_WIDTH/2, 0, 0]),
|
||||
);
|
||||
canvas.concat44(turn);
|
||||
canvas.concat(turn);
|
||||
|
||||
// Draw some stripes to help the eye detect the turn
|
||||
const stripeWidth = 10;
|
||||
|
@ -606,6 +606,35 @@ describe('Core canvas behavior', () => {
|
||||
paint.delete();
|
||||
shader.delete();
|
||||
});
|
||||
|
||||
const radiansToDegrees = (rad) => {
|
||||
return (rad / Math.PI) * 180;
|
||||
}
|
||||
|
||||
// this should draw the same as concat_with4x4_canvas
|
||||
gm('concat_dommatrix', (canvas) => {
|
||||
const path = starPath(CanvasKit, CANVAS_WIDTH/2, CANVAS_HEIGHT/2);
|
||||
const paint = new CanvasKit.SkPaint();
|
||||
paint.setAntiAlias(true);
|
||||
canvas.clear(CanvasKit.WHITE);
|
||||
canvas.concat(new DOMMatrix().translate(CANVAS_WIDTH/2, 0, 0));
|
||||
canvas.concat(new DOMMatrix().rotateAxisAngle(1, 0, 0, radiansToDegrees(Math.PI/3)));
|
||||
canvas.concat(new DOMMatrix().rotateAxisAngle(0, 1, 0, radiansToDegrees(Math.PI/4)));
|
||||
canvas.concat(new DOMMatrix().rotateAxisAngle(0, 0, 1, radiansToDegrees(Math.PI/16)));
|
||||
canvas.concat(new DOMMatrix().translate(-CANVAS_WIDTH/2, 0, 0));
|
||||
|
||||
// Draw some stripes to help the eye detect the turn
|
||||
const stripeWidth = 10;
|
||||
paint.setColor(CanvasKit.BLACK);
|
||||
for (let i = 0; i < CANVAS_WIDTH; i += 2*stripeWidth) {
|
||||
canvas.drawRect(CanvasKit.LTRBRect(i, 0, i + stripeWidth, CANVAS_HEIGHT), paint);
|
||||
}
|
||||
|
||||
paint.setColor(CanvasKit.YELLOW);
|
||||
canvas.drawPath(path, paint);
|
||||
paint.delete();
|
||||
path.delete();
|
||||
});
|
||||
}); // end describe('DOMMatrix support')
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user