[canvaskit] Handle passing matrix values into CK ourselves.
This means we take DOMMatrix everywhere now. This reduced the *_makeShader benchmark by ~25% (4 us -> 3 us) and cleaned up several callsites. Trimming this down saves ~3kb in uncompressed code size. Change-Id: Ie677c7ebb7bc97ed8cd4d4851a039b78b6f8079d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281018 Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
5384f4036f
commit
6bffe39c98
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Support for DOMMatrix in addition to the SkMatrix currently supported by some APIs. [WIP]
|
- Support for DOMMatrix on all APIs that take SkMatrix (i.e. arrays or Float32Arrays of length 9).
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Previously deprecated functions MakeSkDashPathEffect, MakeLinearGradientShader,
|
- Previously deprecated functions MakeSkDashPathEffect, MakeLinearGradientShader,
|
||||||
|
@ -87,26 +87,15 @@
|
|||||||
sk_sp<SkFontMgr> SkFontMgr_New_Custom_Data(const uint8_t** datas, const size_t* sizes, int n);
|
sk_sp<SkFontMgr> SkFontMgr_New_Custom_Data(const uint8_t** datas, const size_t* sizes, int n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 3x3 Matrices
|
struct OptionalMatrix : SkMatrix {
|
||||||
struct SimpleMatrix {
|
OptionalMatrix(uintptr_t mPtr) {
|
||||||
SkScalar scaleX, skewX, transX;
|
if (mPtr) {
|
||||||
SkScalar skewY, scaleY, transY;
|
const SkScalar* nineMatrixValues = reinterpret_cast<const SkScalar*>(mPtr);
|
||||||
SkScalar pers0, pers1, pers2;
|
this->set9(nineMatrixValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SkMatrix toSkMatrix(const SimpleMatrix& sm) {
|
|
||||||
return SkMatrix::MakeAll(sm.scaleX, sm.skewX , sm.transX,
|
|
||||||
sm.skewY , sm.scaleY, sm.transY,
|
|
||||||
sm.pers0 , sm.pers1 , sm.pers2);
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleMatrix toSimpleSkMatrix(const SkMatrix& sm) {
|
|
||||||
SimpleMatrix m {sm[0], sm[1], sm[2],
|
|
||||||
sm[3], sm[4], sm[5],
|
|
||||||
sm[6], sm[7], sm[8]};
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Experimental 4x4 matrices, also represented in JS with arrays.
|
// Experimental 4x4 matrices, also represented in JS with arrays.
|
||||||
struct SimpleM44 {
|
struct SimpleM44 {
|
||||||
SkScalar m0, m1, m2, m3;
|
SkScalar m0, m1, m2, m3;
|
||||||
@ -803,29 +792,16 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
}), allow_raw_pointers());
|
}), allow_raw_pointers());
|
||||||
function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
|
function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||||
int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
|
int count, SkTileMode mode, uint32_t flags,
|
||||||
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
SkPoint points[] = { start, end };
|
SkPoint points[] = { start, end };
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||||
|
OptionalMatrix localMatrix(mPtr);
|
||||||
// TODO(nifong): do not assume color space. Support and test wide gamut color gradients
|
// TODO(nifong): do not assume color space. Support and test wide gamut color gradients
|
||||||
return SkGradientShader::MakeLinear(points, colors, SkColorSpace::MakeSRGB(), positions, count,
|
return SkGradientShader::MakeLinear(points, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||||
mode, flags, nullptr);
|
mode, flags, &localMatrix);
|
||||||
}), allow_raw_pointers());
|
|
||||||
function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
|
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
|
||||||
int count, SkTileMode mode, uint32_t flags,
|
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
|
||||||
SkPoint points[] = { start, end };
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
|
||||||
|
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
|
||||||
|
|
||||||
return SkGradientShader::MakeLinear(points, colors, SkColorSpace::MakeSRGB(), positions, count,
|
|
||||||
mode, flags, &localMatrix);
|
|
||||||
}), allow_raw_pointers());
|
}), allow_raw_pointers());
|
||||||
#ifdef SK_SERIALIZE_SKP
|
#ifdef SK_SERIALIZE_SKP
|
||||||
function("_MakeSkPicture", optional_override([](uintptr_t /* unint8_t* */ dPtr,
|
function("_MakeSkPicture", optional_override([](uintptr_t /* unint8_t* */ dPtr,
|
||||||
@ -837,25 +813,14 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
return SkPicture::MakeFromData(data.get(), nullptr);
|
return SkPicture::MakeFromData(data.get(), nullptr);
|
||||||
}), allow_raw_pointers());
|
}), allow_raw_pointers());
|
||||||
#endif
|
#endif
|
||||||
function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
|
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
|
||||||
int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
|
||||||
|
|
||||||
return SkGradientShader::MakeRadial(center, radius, colors, SkColorSpace::MakeSRGB(), positions, count,
|
|
||||||
mode, flags, nullptr);
|
|
||||||
}), allow_raw_pointers());
|
|
||||||
function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
|
function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||||
int count, SkTileMode mode, uint32_t flags,
|
int count, SkTileMode mode, uint32_t flags,
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||||
|
OptionalMatrix localMatrix(mPtr);
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
|
||||||
return SkGradientShader::MakeRadial(center, radius, colors, SkColorSpace::MakeSRGB(), positions, count,
|
return SkGradientShader::MakeRadial(center, radius, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||||
mode, flags, &localMatrix);
|
mode, flags, &localMatrix);
|
||||||
}), allow_raw_pointers());
|
}), allow_raw_pointers());
|
||||||
@ -864,61 +829,25 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
int count, SkTileMode mode,
|
int count, SkTileMode mode,
|
||||||
SkScalar startAngle, SkScalar endAngle,
|
SkScalar startAngle, SkScalar endAngle,
|
||||||
uint32_t flags,
|
uint32_t flags,
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||||
|
OptionalMatrix localMatrix(mPtr);
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
|
||||||
return SkGradientShader::MakeSweep(cx, cy, colors, SkColorSpace::MakeSRGB(), positions, count,
|
return SkGradientShader::MakeSweep(cx, cy, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||||
mode, startAngle, endAngle, flags,
|
mode, startAngle, endAngle, flags,
|
||||||
&localMatrix);
|
&localMatrix);
|
||||||
}), allow_raw_pointers());
|
}), allow_raw_pointers());
|
||||||
function("_MakeSweepGradientShader", optional_override([](SkScalar cx, SkScalar cy,
|
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
|
||||||
int count, uint32_t flags,
|
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
|
||||||
|
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
|
||||||
return SkGradientShader::MakeSweep(cx, cy, colors, SkColorSpace::MakeSRGB(), positions, count,
|
|
||||||
flags, &localMatrix);
|
|
||||||
}), allow_raw_pointers());
|
|
||||||
function("_MakeSweepGradientShader", optional_override([](SkScalar cx, SkScalar cy,
|
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
|
||||||
int count)->sk_sp<SkShader> {
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
|
||||||
|
|
||||||
return SkGradientShader::MakeSweep(cx, cy, colors, SkColorSpace::MakeSRGB(), positions, count);
|
|
||||||
}), allow_raw_pointers());
|
|
||||||
function("_MakeTwoPointConicalGradientShader", optional_override([](
|
function("_MakeTwoPointConicalGradientShader", optional_override([](
|
||||||
SkPoint start, SkScalar startRadius,
|
SkPoint start, SkScalar startRadius,
|
||||||
SkPoint end, SkScalar endRadius,
|
SkPoint end, SkScalar endRadius,
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||||
int count, SkTileMode mode, uint32_t flags)->sk_sp<SkShader> {
|
int count, SkTileMode mode, uint32_t flags,
|
||||||
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||||
|
OptionalMatrix localMatrix(mPtr);
|
||||||
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
|
||||||
colors, SkColorSpace::MakeSRGB(), positions, count, mode,
|
|
||||||
flags, nullptr);
|
|
||||||
}), allow_raw_pointers());
|
|
||||||
function("_MakeTwoPointConicalGradientShader", optional_override([](
|
|
||||||
SkPoint start, SkScalar startRadius,
|
|
||||||
SkPoint end, SkScalar endRadius,
|
|
||||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
|
||||||
int count, SkTileMode mode, uint32_t flags,
|
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
|
||||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
|
||||||
|
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
|
||||||
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
||||||
colors, SkColorSpace::MakeSRGB(), positions, count, mode,
|
colors, SkColorSpace::MakeSRGB(), positions, count, mode,
|
||||||
flags, &localMatrix);
|
flags, &localMatrix);
|
||||||
@ -972,8 +901,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
self.clipRRect(toRRect(r), op, doAntiAlias);
|
self.clipRRect(toRRect(r), op, doAntiAlias);
|
||||||
}))
|
}))
|
||||||
.function("clipRect", select_overload<void (const SkRect&, SkClipOp, bool)>(&SkCanvas::clipRect))
|
.function("clipRect", select_overload<void (const SkRect&, SkClipOp, bool)>(&SkCanvas::clipRect))
|
||||||
.function("concat", optional_override([](SkCanvas& self, const SimpleMatrix& m) {
|
.function("_concat", optional_override([](SkCanvas& self, uintptr_t /* SkScalar* */ mPtr) {
|
||||||
self.concat(toSkMatrix(m));
|
// See comment above for uintptr_t explanation
|
||||||
|
OptionalMatrix localMatrix(mPtr);
|
||||||
|
self.concat(localMatrix);
|
||||||
}))
|
}))
|
||||||
.function("drawArc", &SkCanvas::drawArc)
|
.function("drawArc", &SkCanvas::drawArc)
|
||||||
// _drawAtlas takes an SkColor, unlike most private functions handling color.
|
// _drawAtlas takes an SkColor, unlike most private functions handling color.
|
||||||
@ -1067,9 +998,17 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
.function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
|
.function("drawVertices", select_overload<void (const sk_sp<SkVertices>&, SkBlendMode, const SkPaint&)>(&SkCanvas::drawVertices))
|
||||||
.function("flush", &SkCanvas::flush)
|
.function("flush", &SkCanvas::flush)
|
||||||
.function("getSaveCount", &SkCanvas::getSaveCount)
|
.function("getSaveCount", &SkCanvas::getSaveCount)
|
||||||
.function("getTotalMatrix", optional_override([](const SkCanvas& self)->SimpleMatrix {
|
// We allocate room for the matrix from the JS side and free it there so as to not have
|
||||||
|
// an awkward moment where we malloc something here and "just know" to free it on the
|
||||||
|
// JS side.
|
||||||
|
.function("_getTotalMatrix", optional_override([](const SkCanvas& self, uintptr_t /* uint8_t* */ mPtr) {
|
||||||
|
// See comment above for uintptr_t explanation
|
||||||
|
SkScalar* nineMatrixValues = reinterpret_cast<SkScalar*>(mPtr);
|
||||||
|
if (!nineMatrixValues) {
|
||||||
|
return; // matrix cannot be null
|
||||||
|
}
|
||||||
SkMatrix m = self.getTotalMatrix();
|
SkMatrix m = self.getTotalMatrix();
|
||||||
return toSimpleSkMatrix(m);
|
m.get9(nineMatrixValues);
|
||||||
}))
|
}))
|
||||||
.function("makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
|
.function("makeSurface", optional_override([](SkCanvas& self, SimpleImageInfo sii)->sk_sp<SkSurface> {
|
||||||
return self.makeSurface(toSkImageInfo(sii), nullptr);
|
return self.makeSurface(toSkImageInfo(sii), nullptr);
|
||||||
@ -1274,16 +1213,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
.function("width", &SkImage::width)
|
.function("width", &SkImage::width)
|
||||||
.function("_encodeToData", select_overload<sk_sp<SkData>()const>(&SkImage::encodeToData))
|
.function("_encodeToData", select_overload<sk_sp<SkData>()const>(&SkImage::encodeToData))
|
||||||
.function("_encodeToDataWithFormat", select_overload<sk_sp<SkData>(SkEncodedImageFormat encodedImageFormat, int quality)const>(&SkImage::encodeToData))
|
.function("_encodeToDataWithFormat", select_overload<sk_sp<SkData>(SkEncodedImageFormat encodedImageFormat, int quality)const>(&SkImage::encodeToData))
|
||||||
// Allow localMatrix to be optional, so we have 2 declarations of these shaders
|
|
||||||
.function("_makeShader", optional_override([](sk_sp<SkImage> self,
|
|
||||||
SkTileMode tx, SkTileMode ty)->sk_sp<SkShader> {
|
|
||||||
return self->makeShader(tx, ty, nullptr);
|
|
||||||
}), allow_raw_pointers())
|
|
||||||
.function("_makeShader", optional_override([](sk_sp<SkImage> self,
|
.function("_makeShader", optional_override([](sk_sp<SkImage> self,
|
||||||
SkTileMode tx, SkTileMode ty,
|
SkTileMode tx, SkTileMode ty,
|
||||||
const SimpleMatrix& lm)->sk_sp<SkShader> {
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
SkMatrix localMatrix = toSkMatrix(lm);
|
OptionalMatrix localMatrix(mPtr);
|
||||||
|
|
||||||
return self->makeShader(tx, ty, &localMatrix);
|
return self->makeShader(tx, ty, &localMatrix);
|
||||||
}), allow_raw_pointers())
|
}), allow_raw_pointers())
|
||||||
.function("_readPixels", optional_override([](sk_sp<SkImage> self,
|
.function("_readPixels", optional_override([](sk_sp<SkImage> self,
|
||||||
@ -1309,9 +1242,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
return SkImageFilters::ColorFilter(cf, input);
|
return SkImageFilters::ColorFilter(cf, input);
|
||||||
}))
|
}))
|
||||||
.class_function("MakeCompose", &SkImageFilters::Compose)
|
.class_function("MakeCompose", &SkImageFilters::Compose)
|
||||||
.class_function("MakeMatrixTransform", optional_override([](SimpleMatrix sm, SkFilterQuality fq,
|
.class_function("_MakeMatrixTransform", optional_override([](uintptr_t /* SkScalar* */ mPtr, SkFilterQuality fq,
|
||||||
sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
|
sk_sp<SkImageFilter> input)->sk_sp<SkImageFilter> {
|
||||||
return SkImageFilters::MatrixTransform(toSkMatrix(sm), fq, input);
|
OptionalMatrix matr(mPtr);
|
||||||
|
return SkImageFilters::MatrixTransform(matr, fq, input);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
class_<SkMaskFilter>("SkMaskFilter")
|
class_<SkMaskFilter>("SkMaskFilter")
|
||||||
@ -1507,21 +1441,18 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
}
|
}
|
||||||
return effect;
|
return effect;
|
||||||
}))
|
}))
|
||||||
.function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque)->sk_sp<SkShader> {
|
.function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque,
|
||||||
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
void* inputData = reinterpret_cast<void*>(fPtr);
|
void* inputData = reinterpret_cast<void*>(fPtr);
|
||||||
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
||||||
return self.makeShader(inputs, nullptr, 0, nullptr, isOpaque);
|
|
||||||
}))
|
OptionalMatrix localMatrix(mPtr);
|
||||||
.function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque, SimpleMatrix sm)->sk_sp<SkShader> {
|
return self.makeShader(inputs, nullptr, 0, &localMatrix, isOpaque);
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
void* inputData = reinterpret_cast<void*>(fPtr);
|
|
||||||
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
|
||||||
auto m = toSkMatrix(sm);
|
|
||||||
return self.makeShader(inputs, nullptr, 0, &m, isOpaque);
|
|
||||||
}))
|
}))
|
||||||
.function("_makeShaderWithChildren", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque,
|
.function("_makeShaderWithChildren", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque,
|
||||||
uintptr_t /** SkShader*[] */cPtrs, size_t cLen)->sk_sp<SkShader> {
|
uintptr_t /** SkShader*[] */cPtrs, size_t cLen,
|
||||||
|
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||||
// See comment above for uintptr_t explanation
|
// See comment above for uintptr_t explanation
|
||||||
void* inputData = reinterpret_cast<void*>(fPtr);
|
void* inputData = reinterpret_cast<void*>(fPtr);
|
||||||
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
||||||
@ -1533,25 +1464,8 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
// so we want to ref the new sk_sp so makeShader doesn't clean it up.
|
// so we want to ref the new sk_sp so makeShader doesn't clean it up.
|
||||||
children[i] = sk_ref_sp<SkShader>(childrenPtrs[i]);
|
children[i] = sk_ref_sp<SkShader>(childrenPtrs[i]);
|
||||||
}
|
}
|
||||||
auto s = self.makeShader(inputs, children, cLen, nullptr, isOpaque);
|
OptionalMatrix localMatrix(mPtr);
|
||||||
delete[] children;
|
auto s = self.makeShader(inputs, children, cLen, &localMatrix, isOpaque);
|
||||||
return s;
|
|
||||||
}))
|
|
||||||
.function("_makeShaderWithChildren", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque,
|
|
||||||
uintptr_t /** SkShader*[] */cPtrs, size_t cLen, SimpleMatrix sm)->sk_sp<SkShader> {
|
|
||||||
// See comment above for uintptr_t explanation
|
|
||||||
void* inputData = reinterpret_cast<void*>(fPtr);
|
|
||||||
sk_sp<SkData> inputs = SkData::MakeFromMalloc(inputData, fLen);
|
|
||||||
|
|
||||||
sk_sp<SkShader>* children = new sk_sp<SkShader>[cLen];
|
|
||||||
SkShader** childrenPtrs = reinterpret_cast<SkShader**>(cPtrs);
|
|
||||||
for (size_t i = 0; i < cLen; i++) {
|
|
||||||
// This bare pointer was already part of an sk_sp (owned outside of here),
|
|
||||||
// so we want to ref the new sk_sp so makeShader doesn't clean it up.
|
|
||||||
children[i] = sk_ref_sp<SkShader>(childrenPtrs[i]);
|
|
||||||
}
|
|
||||||
auto m = toSkMatrix(sm);
|
|
||||||
auto s = self.makeShader(inputs, children, cLen, &m, isOpaque);
|
|
||||||
delete[] children;
|
delete[] children;
|
||||||
return s;
|
return s;
|
||||||
}));
|
}));
|
||||||
@ -1827,24 +1741,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
|||||||
.field("cap", &StrokeOpts::cap)
|
.field("cap", &StrokeOpts::cap)
|
||||||
.field("precision", &StrokeOpts::precision);
|
.field("precision", &StrokeOpts::precision);
|
||||||
|
|
||||||
// Allows clients to supply a 1D array of 9 elements and the bindings
|
|
||||||
// will automatically turn it into a 3x3 2D matrix.
|
|
||||||
// e.g. path.transform([0,1,2,3,4,5,6,7,8])
|
|
||||||
// This is likely simpler for the client than exposing SkMatrix
|
|
||||||
// directly and requiring them to do a lot of .delete().
|
|
||||||
value_array<SimpleMatrix>("SkMatrix")
|
|
||||||
.element(&SimpleMatrix::scaleX)
|
|
||||||
.element(&SimpleMatrix::skewX)
|
|
||||||
.element(&SimpleMatrix::transX)
|
|
||||||
|
|
||||||
.element(&SimpleMatrix::skewY)
|
|
||||||
.element(&SimpleMatrix::scaleY)
|
|
||||||
.element(&SimpleMatrix::transY)
|
|
||||||
|
|
||||||
.element(&SimpleMatrix::pers0)
|
|
||||||
.element(&SimpleMatrix::pers1)
|
|
||||||
.element(&SimpleMatrix::pers2);
|
|
||||||
|
|
||||||
value_array<SimpleM44>("SkM44")
|
value_array<SimpleM44>("SkM44")
|
||||||
.element(&SimpleM44::m0).element(&SimpleM44::m1).element(&SimpleM44::m2).element(&SimpleM44::m3)
|
.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::m4).element(&SimpleM44::m5).element(&SimpleM44::m6).element(&SimpleM44::m7)
|
||||||
|
@ -158,7 +158,6 @@ var CanvasKit = {
|
|||||||
clipPath: function() {},
|
clipPath: function() {},
|
||||||
clipRRect: function() {},
|
clipRRect: function() {},
|
||||||
clipRect: function() {},
|
clipRect: function() {},
|
||||||
concat: function() {},
|
|
||||||
drawAnimatedImage: function() {},
|
drawAnimatedImage: function() {},
|
||||||
drawArc: function() {},
|
drawArc: function() {},
|
||||||
drawCircle: function() {},
|
drawCircle: function() {},
|
||||||
@ -182,7 +181,6 @@ var CanvasKit = {
|
|||||||
drawVertices: function() {},
|
drawVertices: function() {},
|
||||||
flush: function() {},
|
flush: function() {},
|
||||||
getSaveCount: function() {},
|
getSaveCount: function() {},
|
||||||
getTotalMatrix: function() {},
|
|
||||||
makeSurface: function() {},
|
makeSurface: function() {},
|
||||||
restore: function() {},
|
restore: function() {},
|
||||||
restoreToCount: function() {},
|
restoreToCount: function() {},
|
||||||
@ -194,9 +192,11 @@ var CanvasKit = {
|
|||||||
translate: function() {},
|
translate: function() {},
|
||||||
|
|
||||||
// private API
|
// private API
|
||||||
|
_concat: function() {},
|
||||||
_drawAtlas: function() {},
|
_drawAtlas: function() {},
|
||||||
_drawPoints: function() {},
|
_drawPoints: function() {},
|
||||||
_drawSimpleText: function() {},
|
_drawSimpleText: function() {},
|
||||||
|
_getTotalMatrix: function() {},
|
||||||
_readPixels: function() {},
|
_readPixels: function() {},
|
||||||
_writePixels: function() {},
|
_writePixels: function() {},
|
||||||
delete: function() {},
|
delete: function() {},
|
||||||
@ -278,6 +278,9 @@ var CanvasKit = {
|
|||||||
MakeColorFilter: function() {},
|
MakeColorFilter: function() {},
|
||||||
MakeCompose: function() {},
|
MakeCompose: function() {},
|
||||||
MakeMatrixTransform: function() {},
|
MakeMatrixTransform: function() {},
|
||||||
|
|
||||||
|
// private API
|
||||||
|
_MakeMatrixTransform: function() {},
|
||||||
},
|
},
|
||||||
|
|
||||||
// These are defined in interface.js
|
// These are defined in interface.js
|
||||||
@ -834,9 +837,11 @@ CanvasKit.SkSurface.prototype.captureFrameAsSkPicture = function() {};
|
|||||||
CanvasKit.SkImage.prototype.encodeToData = function() {};
|
CanvasKit.SkImage.prototype.encodeToData = function() {};
|
||||||
CanvasKit.SkImage.prototype.makeShader = function() {};
|
CanvasKit.SkImage.prototype.makeShader = function() {};
|
||||||
|
|
||||||
|
CanvasKit.SkCanvas.prototype.concat = function() {};
|
||||||
CanvasKit.SkCanvas.prototype.drawAtlas = function() {};
|
CanvasKit.SkCanvas.prototype.drawAtlas = function() {};
|
||||||
CanvasKit.SkCanvas.prototype.drawPoints = function() {};
|
CanvasKit.SkCanvas.prototype.drawPoints = function() {};
|
||||||
CanvasKit.SkCanvas.prototype.drawText = function() {};
|
CanvasKit.SkCanvas.prototype.drawText = function() {};
|
||||||
|
CanvasKit.SkCanvas.prototype.getTotalMatrix = function() {};
|
||||||
/** @return {Uint8Array} */
|
/** @return {Uint8Array} */
|
||||||
CanvasKit.SkCanvas.prototype.readPixels = function() {};
|
CanvasKit.SkCanvas.prototype.readPixels = function() {};
|
||||||
CanvasKit.SkCanvas.prototype.writePixels = function() {};
|
CanvasKit.SkCanvas.prototype.writePixels = function() {};
|
||||||
|
@ -259,6 +259,43 @@ function copy3dArray(arr, dest, ptr) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultPerspective = Float32Array.of(0, 0, 1);
|
||||||
|
|
||||||
|
// Copies the given DOMMatrix/Array/TypedArray to the CanvasKit heap and
|
||||||
|
// returns a pointer to the memory. This memory is a float* of length 9.
|
||||||
|
// If the passed in matrix is null/undefined, we return 0 (nullptr). All calls
|
||||||
|
// on the C++ side should check for nullptr where appropriate. It is generally
|
||||||
|
// the responsibility of the JS side code to call CanvasKit._free on the
|
||||||
|
// allocated memory before returning to the user code.
|
||||||
|
function copy3x3MatrixToWasm(matr) {
|
||||||
|
if (!matr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
var mPtr = CanvasKit._malloc(9 * 4); // 9 matrix scalars, each at 4 bytes.
|
||||||
|
if (matr.length) {
|
||||||
|
// TODO(kjlubick): Downsample a 16 length (4x4 matrix)
|
||||||
|
if (matr.length !== 6 && matr.length !== 9) {
|
||||||
|
throw 'invalid matrix size';
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
|
if (matr.length === 6) {
|
||||||
|
CanvasKit.HEAPF32.set(defaultPerspective, 6 + mPtr / 4);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Try as if it's a DOMMatrix. Reminder that DOMMatrix lists their
|
||||||
|
// column first, then row.
|
||||||
|
var floats = Float32Array.of(
|
||||||
|
matr.m11, matr.m21, matr.m41,
|
||||||
|
matr.m12, matr.m22, matr.m42,
|
||||||
|
matr.m14, matr.m24, matr.m44);
|
||||||
|
// have to divide the pointer by 4 to "cast" it from bytes to float.
|
||||||
|
CanvasKit.HEAPF32.set(floats, mPtr / 4);
|
||||||
|
}
|
||||||
|
return mPtr;
|
||||||
|
}
|
||||||
|
|
||||||
// Caching the Float32Arrays can save having to reallocate them
|
// Caching the Float32Arrays can save having to reallocate them
|
||||||
// over and over again.
|
// over and over again.
|
||||||
var Float32ArrayCache = {};
|
var Float32ArrayCache = {};
|
||||||
|
@ -806,12 +806,10 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CanvasKit.SkImage.prototype.makeShader = function(xTileMode, yTileMode, localMatrix) {
|
CanvasKit.SkImage.prototype.makeShader = function(xTileMode, yTileMode, localMatrix) {
|
||||||
if (localMatrix) {
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
localMatrix = prepare3x3MatrixForGoingToWasm(localMatrix);
|
var shader = this._makeShader(xTileMode, yTileMode, localMatrixPtr);
|
||||||
return this._makeShader(xTileMode, yTileMode, localMatrix);
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
} else {
|
return shader;
|
||||||
return this._makeShader(xTileMode, yTileMode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasKit.SkImage.prototype.readPixels = function(imageInfo, srcX, srcY) {
|
CanvasKit.SkImage.prototype.readPixels = function(imageInfo, srcX, srcY) {
|
||||||
@ -852,13 +850,18 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
// Free the allocated pixels in the WASM memory
|
// Free the allocated pixels in the WASM memory
|
||||||
CanvasKit._free(pPtr);
|
CanvasKit._free(pPtr);
|
||||||
return retVal;
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasKit.SkCanvas.prototype.concat = function(matr) {
|
||||||
|
var matrPtr = copy3x3MatrixToWasm(matr);
|
||||||
|
this._concat(matrPtr);
|
||||||
|
matrPtr && CanvasKit._free(matrPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// atlas is an SkImage, e.g. from CanvasKit.MakeImageFromEncoded
|
// atlas is an SkImage, e.g. from CanvasKit.MakeImageFromEncoded
|
||||||
// srcRects and dstXforms should be CanvasKit.SkRectBuilder and CanvasKit.RSXFormBuilder
|
// srcRects and dstXforms should be CanvasKit.SkRectBuilder and CanvasKit.RSXFormBuilder
|
||||||
// or just arrays of floats in groups of 4.
|
// or just arrays of floats in groups of 4.
|
||||||
// colors, if provided, should be a CanvasKit.SkColorBuilder or array of Canvaskit.SimpleColor4f
|
// colors, if provided, should be a CanvasKit.SkColorBuilder or array of CanvasKit.SimpleColor4f
|
||||||
CanvasKit.SkCanvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
|
CanvasKit.SkCanvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
|
||||||
/*optional*/ blendMode, colors) {
|
/*optional*/ blendMode, colors) {
|
||||||
if (!atlas || !paint || !srcRects || !dstXforms) {
|
if (!atlas || !paint || !srcRects || !dstXforms) {
|
||||||
@ -887,14 +890,14 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
dstXformPtr = copy1dArray(dstXforms, CanvasKit.HEAPF32);
|
dstXformPtr = copy1dArray(dstXforms, CanvasKit.HEAPF32);
|
||||||
}
|
}
|
||||||
|
|
||||||
var colorPtr = 0; // enscriptem doesn't like undefined for nullptr
|
var colorPtr = nullptr;
|
||||||
if (colors) {
|
if (colors) {
|
||||||
if (colors.build) {
|
if (colors.build) {
|
||||||
colorPtr = colors.build();
|
colorPtr = colors.build();
|
||||||
} else {
|
} else {
|
||||||
if (!isCanvasKitColor(colors[0])) {
|
if (!isCanvasKitColor(colors[0])) {
|
||||||
SkDebug('DrawAtlas color argument expected to be CanvasKit.SkRectBuilder or array of ' +
|
SkDebug('DrawAtlas color argument expected to be CanvasKit.SkRectBuilder or array of ' +
|
||||||
'Canvaskit.SimpleColor4f, but got '+colors);
|
'CanvasKit.SimpleColor4f, but got '+colors);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// convert here
|
// convert here
|
||||||
@ -937,6 +940,20 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
CanvasKit._free(ptr);
|
CanvasKit._free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CanvasKit.SkCanvas.prototype.getTotalMatrix = function() {
|
||||||
|
var matrPtr = CanvasKit._malloc(9 * 4); // allocate space for the matrix
|
||||||
|
// _getTotalMatrix will copy the values into the pointer.
|
||||||
|
this._getTotalMatrix(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(9);
|
||||||
|
for (var i = 0; i < 9; i++) {
|
||||||
|
rv[i] = CanvasKit.HEAPF32[matrPtr/4 + i]; // divide by 4 to "cast" to float.
|
||||||
|
}
|
||||||
|
CanvasKit._free(matrPtr);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
// returns Uint8Array
|
// returns Uint8Array
|
||||||
CanvasKit.SkCanvas.prototype.readPixels = function(x, y, w, h, alphaType,
|
CanvasKit.SkCanvas.prototype.readPixels = function(x, y, w, h, alphaType,
|
||||||
colorType, dstRowBytes) {
|
colorType, dstRowBytes) {
|
||||||
@ -995,8 +1012,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
// colorMatrix is an SkColorMatrix (e.g. Float32Array of length 20)
|
// colorMatrix is an SkColorMatrix (e.g. Float32Array of length 20)
|
||||||
CanvasKit.SkColorFilter.MakeMatrix = function(colorMatrix) {
|
CanvasKit.SkColorFilter.MakeMatrix = function(colorMatrix) {
|
||||||
if (!colorMatrix || colorMatrix.length !== 20) {
|
if (!colorMatrix || colorMatrix.length !== 20) {
|
||||||
SkDebug('ignoring invalid color matrix');
|
throw 'invalid color matrix';
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
var fptr = copy1dArray(colorMatrix, CanvasKit.HEAPF32);
|
var fptr = copy1dArray(colorMatrix, CanvasKit.HEAPF32);
|
||||||
// We know skia memcopies the floats, so we can free our memory after the call returns.
|
// We know skia memcopies the floats, so we can free our memory after the call returns.
|
||||||
@ -1005,6 +1021,14 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CanvasKit.SkImageFilter.MakeMatrixTransform = function(matr, filterQuality, input) {
|
||||||
|
var matrPtr = copy3x3MatrixToWasm(matr);
|
||||||
|
var imgF = CanvasKit.SkImageFilter._MakeMatrixTransform(matrPtr, filterQuality, input);
|
||||||
|
|
||||||
|
matrPtr && CanvasKit._free(matrPtr);
|
||||||
|
return imgF;
|
||||||
|
}
|
||||||
|
|
||||||
CanvasKit.SkSurface.prototype.captureFrameAsSkPicture = function(drawFrame) {
|
CanvasKit.SkSurface.prototype.captureFrameAsSkPicture = function(drawFrame) {
|
||||||
// Set up SkPictureRecorder
|
// Set up SkPictureRecorder
|
||||||
var spr = new CanvasKit.SkPictureRecorder();
|
var spr = new CanvasKit.SkPictureRecorder();
|
||||||
@ -1066,43 +1090,16 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
return dpe;
|
return dpe;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepare3x3MatrixForGoingToWasm(matr) {
|
|
||||||
if (!matr) {
|
|
||||||
return [
|
|
||||||
1, 0, 0,
|
|
||||||
0, 1, 0,
|
|
||||||
0, 0, 1,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (Array.isArray(matr)) {
|
|
||||||
// Add perspective args if not provided.
|
|
||||||
if (matr.length === 6) {
|
|
||||||
matr.push(0, 0, 1);
|
|
||||||
}
|
|
||||||
return matr;
|
|
||||||
}
|
|
||||||
// DOMMatrix, which has their values in column major order.
|
|
||||||
return [
|
|
||||||
matr.a, matr.c, matr.e,
|
|
||||||
matr.b, matr.d, matr.f,
|
|
||||||
0, 0, 1,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
CanvasKit.SkShader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags) {
|
CanvasKit.SkShader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags) {
|
||||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||||
flags = flags || 0;
|
flags = flags || 0;
|
||||||
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
|
|
||||||
if (localMatrix) {
|
var lgs = CanvasKit._MakeLinearGradientShader(start, end, colorPtr, posPtr,
|
||||||
localMatrix = prepare3x3MatrixForGoingToWasm(localMatrix);
|
colors.length, mode, flags, localMatrixPtr);
|
||||||
var lgs = CanvasKit._MakeLinearGradientShader(start, end, colorPtr, posPtr,
|
|
||||||
colors.length, mode, flags, localMatrix);
|
|
||||||
} else {
|
|
||||||
var lgs = CanvasKit._MakeLinearGradientShader(start, end, colorPtr, posPtr,
|
|
||||||
colors.length, mode, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
CanvasKit._free(colorPtr);
|
CanvasKit._free(colorPtr);
|
||||||
CanvasKit._free(posPtr);
|
CanvasKit._free(posPtr);
|
||||||
return lgs;
|
return lgs;
|
||||||
@ -1112,16 +1109,12 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||||
flags = flags || 0;
|
flags = flags || 0;
|
||||||
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
|
|
||||||
if (localMatrix) {
|
var rgs = CanvasKit._MakeRadialGradientShader(center, radius, colorPtr, posPtr,
|
||||||
localMatrix = prepare3x3MatrixForGoingToWasm(localMatrix);
|
colors.length, mode, flags, localMatrixPtr);
|
||||||
var rgs = CanvasKit._MakeRadialGradientShader(center, radius, colorPtr, posPtr,
|
|
||||||
colors.length, mode, flags, localMatrix);
|
|
||||||
} else {
|
|
||||||
var rgs = CanvasKit._MakeRadialGradientShader(center, radius, colorPtr, posPtr,
|
|
||||||
colors.length, mode, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
CanvasKit._free(colorPtr);
|
CanvasKit._free(colorPtr);
|
||||||
CanvasKit._free(posPtr);
|
CanvasKit._free(posPtr);
|
||||||
return rgs;
|
return rgs;
|
||||||
@ -1133,35 +1126,31 @@ CanvasKit.onRuntimeInitialized = function() {
|
|||||||
flags = flags || 0;
|
flags = flags || 0;
|
||||||
startAngle = startAngle || 0;
|
startAngle = startAngle || 0;
|
||||||
endAngle = endAngle || 360;
|
endAngle = endAngle || 360;
|
||||||
localMatrix = prepare3x3MatrixForGoingToWasm(localMatrix);
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
|
|
||||||
var sgs = CanvasKit._MakeSweepGradientShader(cx, cy, colorPtr, posPtr,
|
var sgs = CanvasKit._MakeSweepGradientShader(cx, cy, colorPtr, posPtr,
|
||||||
colors.length, mode,
|
colors.length, mode,
|
||||||
startAngle, endAngle, flags,
|
startAngle, endAngle, flags,
|
||||||
localMatrix);
|
localMatrixPtr);
|
||||||
|
|
||||||
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
CanvasKit._free(colorPtr);
|
CanvasKit._free(colorPtr);
|
||||||
CanvasKit._free(posPtr);
|
CanvasKit._free(posPtr);
|
||||||
return sgs;
|
return sgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasKit.SkShader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
|
CanvasKit.SkShader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
|
||||||
colors, pos, mode, localMatrix, flags) {
|
colors, pos, mode, localMatrix, flags) {
|
||||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||||
flags = flags || 0;
|
flags = flags || 0;
|
||||||
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
|
|
||||||
if (localMatrix) {
|
var rgs = CanvasKit._MakeTwoPointConicalGradientShader(
|
||||||
localMatrix = prepare3x3MatrixForGoingToWasm(localMatrix);
|
|
||||||
var rgs = CanvasKit._MakeTwoPointConicalGradientShader(
|
|
||||||
start, startRadius, end, endRadius,
|
start, startRadius, end, endRadius,
|
||||||
colorPtr, posPtr, colors.length, mode, flags, localMatrix);
|
colorPtr, posPtr, colors.length, mode, flags, localMatrixPtr);
|
||||||
} else {
|
|
||||||
var rgs = CanvasKit._MakeTwoPointConicalGradientShader(
|
|
||||||
start, startRadius, end, endRadius,
|
|
||||||
colorPtr, posPtr, colors.length, mode, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
CanvasKit._free(colorPtr);
|
CanvasKit._free(colorPtr);
|
||||||
CanvasKit._free(posPtr);
|
CanvasKit._free(posPtr);
|
||||||
return rgs;
|
return rgs;
|
||||||
|
@ -128,4 +128,4 @@ describe('DOMMatrix', () => {
|
|||||||
|
|
||||||
benchmarkAndReport('dommatrix_makeShader', setup, test, teardown);
|
benchmarkAndReport('dommatrix_makeShader', setup, test, teardown);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
|
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
|
||||||
CanvasKit._extraInitializations.push(function() {
|
CanvasKit._extraInitializations.push(function() {
|
||||||
CanvasKit.SkRuntimeEffect.prototype.makeShader = function(floats, isOpaque, matrix) {
|
CanvasKit.SkRuntimeEffect.prototype.makeShader = function(floats, isOpaque, localMatrix) {
|
||||||
|
// We don't need to free these floats because they will become owned by the shader.
|
||||||
var fptr = copy1dArray(floats, CanvasKit.HEAPF32);
|
var fptr = copy1dArray(floats, CanvasKit.HEAPF32);
|
||||||
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
// Our array has 4 bytes per float, so be sure to account for that before
|
// Our array has 4 bytes per float, so be sure to account for that before
|
||||||
// sending it over the wire.
|
// sending it over the wire.
|
||||||
if (!matrix) {
|
var rts = this._makeShader(fptr, floats.length * 4, !!isOpaque, localMatrixPtr);
|
||||||
return this._makeShader(fptr, floats.length * 4, !!isOpaque);
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
}
|
return rts;
|
||||||
return this._makeShader(fptr, floats.length * 4, !!isOpaque, matrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// childrenWithShaders is an array of other shaders (e.g. SkImage.makeShader())
|
// childrenWithShaders is an array of other shaders (e.g. SkImage.makeShader())
|
||||||
CanvasKit.SkRuntimeEffect.prototype.makeShaderWithChildren = function(floats, isOpaque, childrenShaders, matrix) {
|
CanvasKit.SkRuntimeEffect.prototype.makeShaderWithChildren = function(floats, isOpaque, childrenShaders, localMatrix) {
|
||||||
|
// We don't need to free these floats because they will become owned by the shader.
|
||||||
var fptr = copy1dArray(floats, CanvasKit.HEAPF32);
|
var fptr = copy1dArray(floats, CanvasKit.HEAPF32);
|
||||||
|
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||||
var barePointers = [];
|
var barePointers = [];
|
||||||
for (var i = 0; i<childrenShaders.length;i++) {
|
for (var i = 0; i < childrenShaders.length; i++) {
|
||||||
// childrenShaders are emscriptens smart pointer type. We want to get the bare pointer
|
// childrenShaders are emscriptens smart pointer type. We want to get the bare pointer
|
||||||
// and send that over the wire, so it can be re-wrapped as an sk_sp.
|
// and send that over the wire, so it can be re-wrapped as an sk_sp.
|
||||||
barePointers.push(childrenShaders[i].$$.ptr);
|
barePointers.push(childrenShaders[i].$$.ptr);
|
||||||
@ -22,9 +25,9 @@ CanvasKit._extraInitializations.push(function() {
|
|||||||
var childrenPointers = copy1dArray(barePointers, CanvasKit.HEAPU32);
|
var childrenPointers = copy1dArray(barePointers, CanvasKit.HEAPU32);
|
||||||
// Our array has 4 bytes per float, so be sure to account for that before
|
// Our array has 4 bytes per float, so be sure to account for that before
|
||||||
// sending it over the wire.
|
// sending it over the wire.
|
||||||
if (!matrix) {
|
var rts = this._makeShaderWithChildren(fptr, floats.length * 4, !!isOpaque, childrenPointers,
|
||||||
return this._makeShaderWithChildren(fptr, floats.length * 4, !!isOpaque, childrenPointers, barePointers.length);
|
barePointers.length, localMatrixPtr);
|
||||||
}
|
localMatrixPtr && CanvasKit._free(localMatrixPtr);
|
||||||
return this._makeShaderWithChildren(fptr, floats.length * 4, !!isOpaque, childrenPointers, barePointers.length, matrix);
|
return rts;
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -761,4 +761,28 @@ describe('CanvasKit\'s Canvas Behavior', function() {
|
|||||||
reportSurface(surface, 'drawvertices_texture_canvas', done);
|
reportSurface(surface, 'drawvertices_texture_canvas', done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can change the matrix on the canvas and read it back', function(done) {
|
||||||
|
LoadCanvasKit.then(catchException(done, () => {
|
||||||
|
const canvas = new CanvasKit.SkCanvas();
|
||||||
|
|
||||||
|
let matr = canvas.getTotalMatrix();
|
||||||
|
expect(matr).toEqual(CanvasKit.SkMatrix.identity());
|
||||||
|
|
||||||
|
canvas.concat(CanvasKit.SkMatrix.rotated(Math.PI/4));
|
||||||
|
const d = new DOMMatrix().translate(20, 10);
|
||||||
|
canvas.concat(d);
|
||||||
|
|
||||||
|
matr = canvas.getTotalMatrix();
|
||||||
|
const expected = CanvasKit.SkMatrix.multiply(
|
||||||
|
CanvasKit.SkMatrix.rotated(Math.PI/4),
|
||||||
|
CanvasKit.SkMatrix.translated(20, 10)
|
||||||
|
);
|
||||||
|
expect(matr.length).toEqual(expected.length);
|
||||||
|
for (let i = 0; i < matr.length; i++) {
|
||||||
|
expect(matr[i]).toBeCloseTo(expected[i], 5);
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
@ -161,4 +161,4 @@ void main(float2 xy, inout half4 color) {
|
|||||||
it('apply a local matrix to the children-based shader', (done) => {
|
it('apply a local matrix to the children-based shader', (done) => {
|
||||||
testChildrenShader('rtshader_children_rotated', done, CanvasKit.SkMatrix.rotated(Math.PI/12));
|
testChildrenShader('rtshader_children_rotated', done, CanvasKit.SkMatrix.rotated(Math.PI/12));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user