[canvaskit] Replace Point value_array with Float32Array
Using value_array (and value_object), while convenient, adds a measurable overhead. This removes the Point value_object and replaces it as a return value with Float32Array (similar to rects). For inputs of a single point, I just split it into x and y. For inputs with two points, I used a _scratchFourFloats (formerly _scratchRect) bit of memory. Two subtle decisions here: - Why not use scratch memory for a single point? The cost of having one extra param is a small/negligible price to pay for less complex code. - Why not accept Malloc objects? Again, simplicity. Accommodating Malloc would make the code harder to read and require more checks. I don't know if anyone wants to have malloced points; if they do, we can probably accommodate that. Change-Id: I1b1c29f62e01c2f1c8c1218f58e3bad642214322 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/362097 Reviewed-by: Nathaniel Nifong <nifong@google.com>
This commit is contained in:
parent
b97a9de755
commit
ed96264ad7
@ -13,18 +13,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
SkColorMatrix (in case clients have logic to deal with that themselves).
|
||||
|
||||
### Breaking
|
||||
- `MakeImprovedNoise` is removed.
|
||||
- Particles now use a single code string containing both Effect and Particle code. Uniform APIs are
|
||||
now shared between Effect and Particle programs, and are no longer prefixed with `Effect` or
|
||||
`Particle`. For example, instead of `ParticleEffect.getEffectUniform` and
|
||||
`ParticleEffect.getParticleUniform`, there is now just: `ParticleEffect.getUniform`.
|
||||
- `MakeImprovedNoise` is removed.
|
||||
- Particles now use a single code string containing both Effect and Particle code. Uniform APIs are
|
||||
now shared between Effect and Particle programs, and are no longer prefixed with `Effect` or
|
||||
`Particle`. For example, instead of `ParticleEffect.getEffectUniform` and
|
||||
`ParticleEffect.getParticleUniform`, there is now just: `ParticleEffect.getUniform`.
|
||||
|
||||
### Changed
|
||||
- `Path.getPoint()` and `SkottieAnimation.size()` now return a TypedArray instead of a normal
|
||||
array. Additionally, they take an optional parameter to allow the result to be copied into
|
||||
that provided TypedArray instead of a new one being allocated.
|
||||
- APIs that passed in points should have less overhead (and now can accept a TypedArray).
|
||||
|
||||
### Fixed
|
||||
- Improper error returned when a WebGL context could not be used.
|
||||
- 4x4 matrices are "downsampled" properly if necessary to 3x3 matrices by removing the third
|
||||
column and the third row.
|
||||
|
||||
## [0.23.0] - 2021-1-29
|
||||
- `SkottieAnimation.size()` was incorrectly returning an object. It now returns a TypedArray of
|
||||
length 2 (w, h).
|
||||
|
||||
### Deprecated
|
||||
- `Canvas.drawImageRect`, `Canvas.drawImage`, `Canvas.drawAtlas`,
|
||||
|
@ -448,7 +448,8 @@ function pathTests(CK: CanvasKit) {
|
||||
bounds = path.getBounds(); // $ExpectType Float32Array
|
||||
path.getBounds(bounds);
|
||||
const ft = path.getFillType();
|
||||
const pt = path.getPoint(7); // $ExpectType Point
|
||||
const pt = path.getPoint(7); // $ExpectType Float32Array
|
||||
path.getPoint(8, pt);
|
||||
ok = path.isEmpty();
|
||||
ok = path.isVolatile();
|
||||
path.lineTo(10, -20);
|
||||
@ -663,7 +664,8 @@ function skottieTests(CK: CanvasKit, canvas?: Canvas) {
|
||||
const a = anim.duration(); // $ExpectType number
|
||||
const b = anim.fps(); // $ExpectType number
|
||||
const c = anim.version(); // $ExpectType string
|
||||
const d = anim.size(); // $ExpectType Point
|
||||
const d = anim.size(); // $ExpectType Float32Array
|
||||
anim.size(d);
|
||||
const rect = anim.seek(0.5);
|
||||
anim.seek(0.6, rect);
|
||||
const rect2 = anim.seekFrame(12.3);
|
||||
|
30
modules/canvaskit/canvaskit/types/index.d.ts
vendored
30
modules/canvaskit/canvaskit/types/index.d.ts
vendored
@ -837,7 +837,7 @@ export interface Particles extends EmbindObject<Particles> {
|
||||
* Sets the base position of the effect.
|
||||
* @param point
|
||||
*/
|
||||
setPosition(point: Point): void;
|
||||
setPosition(point: InputPoint): void;
|
||||
|
||||
/**
|
||||
* Sets the base rate of the effect.
|
||||
@ -2123,8 +2123,10 @@ export interface Path extends EmbindObject<Path> {
|
||||
* Returns the Point at index in Point array. Valid range for index is
|
||||
* 0 to countPoints() - 1.
|
||||
* @param index
|
||||
* @param outputArray - if provided, the point will be copied into this array instead of
|
||||
* allocating a new one.
|
||||
*/
|
||||
getPoint(index: number): Point;
|
||||
getPoint(index: number, outputArray?: Point): Point;
|
||||
|
||||
/**
|
||||
* Returns true if there are no verbs in the path.
|
||||
@ -2504,7 +2506,11 @@ export interface SkottieAnimation extends EmbindObject<SkottieAnimation> {
|
||||
*/
|
||||
seekFrame(frame: number, damageRect?: Rect): Rect;
|
||||
|
||||
size(): Point;
|
||||
/**
|
||||
* Return the size of this animation.
|
||||
* @param outputSize - If provided, the size will be copied into here as width, height.
|
||||
*/
|
||||
size(outputSize?: Point): Point;
|
||||
version(): string;
|
||||
}
|
||||
|
||||
@ -3153,7 +3159,7 @@ export interface ShaderFactory {
|
||||
* between them.
|
||||
* @param colorSpace
|
||||
*/
|
||||
MakeLinearGradient(start: Point, end: Point, colors: InputFlexibleColorArray,
|
||||
MakeLinearGradient(start: InputPoint, end: InputPoint, colors: InputFlexibleColorArray,
|
||||
pos: number[] | null, mode: TileMode, localMatrix?: InputMatrix,
|
||||
flags?: number, colorSpace?: ColorSpace): Shader;
|
||||
|
||||
@ -3170,7 +3176,7 @@ export interface ShaderFactory {
|
||||
* @param flags - 0 to interpolate colors in unpremul, 1 to interpolate colors in premul.
|
||||
* @param colorSpace
|
||||
*/
|
||||
MakeRadialGradient(center: Point, radius: number, colors: InputFlexibleColorArray,
|
||||
MakeRadialGradient(center: InputPoint, radius: number, colors: InputFlexibleColorArray,
|
||||
pos: number[] | null, mode: TileMode, localMatrix?: InputMatrix,
|
||||
flags?: number, colorSpace?: ColorSpace): Shader;
|
||||
|
||||
@ -3223,10 +3229,10 @@ export interface ShaderFactory {
|
||||
* @param flags
|
||||
* @param colorSpace
|
||||
*/
|
||||
MakeTwoPointConicalGradient(start: Point, startRadius: number, end: Point, endRadius: number,
|
||||
colors: InputFlexibleColorArray, pos: number[] | null,
|
||||
mode: TileMode, localMatrix?: InputMatrix, flags?: number,
|
||||
colorSpace?: ColorSpace): Shader;
|
||||
MakeTwoPointConicalGradient(start: InputPoint, startRadius: number, end: InputPoint,
|
||||
endRadius: number, colors: InputFlexibleColorArray,
|
||||
pos: number[] | null, mode: TileMode, localMatrix?: InputMatrix,
|
||||
flags?: number, colorSpace?: ColorSpace): Shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3400,7 +3406,7 @@ export type IRect = Int32Array;
|
||||
/**
|
||||
* An Point is represented by 2 floats: (x, y).
|
||||
*/
|
||||
export type Point = number[];
|
||||
export type Point = Float32Array;
|
||||
/**
|
||||
* An Rect is represented by 4 floats. In order, the floats correspond to left, top,
|
||||
* right, bottom. See Rect.h for more
|
||||
@ -3502,6 +3508,10 @@ export type InputFlattenedRectangleArray = MallocObj | FlattenedRectangleArray |
|
||||
* (e.g. Color). This is convenient for things like gradients when matching up colors to stops.
|
||||
*/
|
||||
export type InputFlexibleColorArray = Float32Array | Uint32Array | Float32Array[];
|
||||
/**
|
||||
* CanvasKit APIs accept a Float32Array or a normal array (of length 2) as a Point.
|
||||
*/
|
||||
export type InputPoint = Point | number[];
|
||||
/**
|
||||
* CanvasKit APIs accept all of these matrix types. Under the hood, we generally use 4x4 matrices.
|
||||
*/
|
||||
|
@ -1463,7 +1463,11 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("countPoints", &SkPath::countPoints)
|
||||
.function("contains", &SkPath::contains)
|
||||
.function("_cubicTo", &ApplyCubicTo)
|
||||
.function("getPoint", &SkPath::getPoint)
|
||||
.function("_getPoint", optional_override([](SkPath& self, int index,
|
||||
uintptr_t /* float* */ oPtr)->void {
|
||||
SkPoint* output = reinterpret_cast<SkPoint*>(oPtr);
|
||||
*output = self.getPoint(index);
|
||||
}))
|
||||
.function("isEmpty", &SkPath::isEmpty)
|
||||
.function("isVolatile", &SkPath::isVolatile)
|
||||
.function("_lineTo", &ApplyLineTo)
|
||||
@ -1586,13 +1590,14 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
// Here and in other gradient functions, cPtr is a pointer to an array of data
|
||||
// representing colors. whether this is an array of SkColor or SkColor4f is indicated
|
||||
// by the colorType argument. Only RGBA_8888 and RGBA_F32 are accepted.
|
||||
.class_function("_MakeLinearGradient", optional_override([](SkPoint start, SkPoint end,
|
||||
.class_function("_MakeLinearGradient", optional_override([](
|
||||
uintptr_t /* SkPoint* */ fourFloatsPtr,
|
||||
uintptr_t cPtr, SkColorType colorType,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
SkPoint points[] = { start, end };
|
||||
const SkPoint* points = reinterpret_cast<const SkPoint*>(fourFloatsPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
|
||||
@ -1608,7 +1613,8 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
SkDebugf("%d is not an accepted colorType\n", colorType);
|
||||
return nullptr;
|
||||
}), allow_raw_pointers())
|
||||
.class_function("_MakeRadialGradient", optional_override([](SkPoint center, SkScalar radius,
|
||||
.class_function("_MakeRadialGradient", optional_override([](
|
||||
SkScalar cx, SkScalar cy, SkScalar radius,
|
||||
uintptr_t cPtr, SkColorType colorType,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
@ -1618,12 +1624,12 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
if (colorType == SkColorType::kRGBA_F32_SkColorType) {
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||
return SkGradientShader::MakeRadial(center, radius, colors, colorSpace, positions, count,
|
||||
mode, flags, &localMatrix);
|
||||
return SkGradientShader::MakeRadial({cx, cy}, radius, colors, colorSpace,
|
||||
positions, count, mode, flags, &localMatrix);
|
||||
} else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
|
||||
const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
|
||||
return SkGradientShader::MakeRadial(center, radius, colors, positions, count,
|
||||
mode, flags, &localMatrix);
|
||||
return SkGradientShader::MakeRadial({cx, cy}, radius, colors, positions,
|
||||
count, mode, flags, &localMatrix);
|
||||
}
|
||||
SkDebugf("%d is not an accepted colorType\n", colorType);
|
||||
return nullptr;
|
||||
@ -1662,24 +1668,27 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
numOctaves, seed, &tileSize);
|
||||
}))
|
||||
.class_function("_MakeTwoPointConicalGradient", optional_override([](
|
||||
SkPoint start, SkScalar startRadius,
|
||||
SkPoint end, SkScalar endRadius,
|
||||
uintptr_t /* SkPoint* */ fourFloatsPtr,
|
||||
SkScalar startRadius, SkScalar endRadius,
|
||||
uintptr_t cPtr, SkColorType colorType,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
const SkPoint* startAndEnd = reinterpret_cast<const SkPoint*>(fourFloatsPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
|
||||
if (colorType == SkColorType::kRGBA_F32_SkColorType) {
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
||||
return SkGradientShader::MakeTwoPointConical(startAndEnd[0], startRadius,
|
||||
startAndEnd[1], endRadius,
|
||||
colors, colorSpace, positions, count, mode,
|
||||
flags, &localMatrix);
|
||||
} else if (colorType == SkColorType::kRGBA_8888_SkColorType) {
|
||||
const SkColor* colors = reinterpret_cast<const SkColor*>(cPtr);
|
||||
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
||||
return SkGradientShader::MakeTwoPointConical(startAndEnd[0], startRadius,
|
||||
startAndEnd[1], endRadius,
|
||||
colors, positions, count, mode,
|
||||
flags, &localMatrix);
|
||||
}
|
||||
@ -1992,11 +2001,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.field("alphaType", &SimpleImageInfo::alphaType)
|
||||
.field("colorSpace", &SimpleImageInfo::colorSpace);
|
||||
|
||||
// SkPoints can be represented by [x, y]
|
||||
value_array<SkPoint>("Point")
|
||||
.element(&SkPoint::fX)
|
||||
.element(&SkPoint::fY);
|
||||
|
||||
// SkPoint3s can be represented by [x, y, z]
|
||||
value_array<SkPoint3>("Point3")
|
||||
.element(&SkPoint3::fX)
|
||||
|
@ -95,8 +95,10 @@ var CanvasKit = {
|
||||
Animation: {
|
||||
prototype: {
|
||||
render: function() {},
|
||||
size: function() {},
|
||||
},
|
||||
_render: function() {},
|
||||
_size: function() {},
|
||||
},
|
||||
|
||||
GrContext: {
|
||||
@ -113,10 +115,12 @@ var CanvasKit = {
|
||||
seek: function() {},
|
||||
seekFrame: function() {},
|
||||
setColor: function() {},
|
||||
size: function() {},
|
||||
},
|
||||
_render: function() {},
|
||||
_seek: function() {},
|
||||
_seekFrame: function() {},
|
||||
_size: function() {},
|
||||
},
|
||||
|
||||
Paragraph: {
|
||||
@ -440,7 +444,6 @@ var CanvasKit = {
|
||||
/** @return {CanvasKit.Paint} */
|
||||
copy: function() {},
|
||||
getBlendMode: function() {},
|
||||
getColor: function() {},
|
||||
getFilterQuality: function() {},
|
||||
getStrokeCap: function() {},
|
||||
getStrokeJoin: function() {},
|
||||
@ -461,6 +464,7 @@ var CanvasKit = {
|
||||
setStyle: function() {},
|
||||
|
||||
prototype: {
|
||||
getColor: function() {},
|
||||
setColor: function() {},
|
||||
setColorComponents: function() {},
|
||||
setColorInt: function() {},
|
||||
@ -488,13 +492,18 @@ var CanvasKit = {
|
||||
getUniformCount: function() {},
|
||||
getUniformFloatCount: function() {},
|
||||
getUniformName: function() {},
|
||||
setPosition: function() {},
|
||||
setRate: function() {},
|
||||
start: function() {},
|
||||
update: function() {},
|
||||
|
||||
prototype: {
|
||||
setPosition: function() {},
|
||||
uniforms: function() {},
|
||||
},
|
||||
|
||||
// private API (from C++ bindings)
|
||||
_uniformPtr: function() {},
|
||||
_setPosition: function() {},
|
||||
},
|
||||
|
||||
Path: {
|
||||
@ -510,7 +519,6 @@ var CanvasKit = {
|
||||
equals: function() {},
|
||||
getBounds: function() {},
|
||||
getFillType: function() {},
|
||||
getPoint: function() {},
|
||||
isEmpty: function() {},
|
||||
isVolatile: function() {},
|
||||
reset: function() {},
|
||||
@ -537,6 +545,7 @@ var CanvasKit = {
|
||||
computeTightBounds: function() {},
|
||||
cubicTo: function() {},
|
||||
dash: function() {},
|
||||
getPoint: function() {},
|
||||
lineTo: function() {},
|
||||
moveTo: function() {},
|
||||
offset: function() {},
|
||||
@ -572,6 +581,7 @@ var CanvasKit = {
|
||||
_computeTightBounds: function() {},
|
||||
_cubicTo: function() {},
|
||||
_dash: function() {},
|
||||
_getPoint: function() {},
|
||||
_lineTo: function() {},
|
||||
_moveTo: function() {},
|
||||
_op: function() {},
|
||||
@ -1029,8 +1039,6 @@ CanvasKit.ColorBuilder.prototype.set = function() {};
|
||||
CanvasKit.RuntimeEffect.prototype.makeShader = function() {};
|
||||
CanvasKit.RuntimeEffect.prototype.makeShaderWithChildren = function() {};
|
||||
|
||||
CanvasKit.ParticleEffect.prototype.uniforms = function() {};
|
||||
|
||||
// Define StrokeOpts object
|
||||
var StrokeOpts = {};
|
||||
StrokeOpts.prototype.width;
|
||||
|
@ -175,8 +175,8 @@ CanvasKit._extraInitializations.push(function() {
|
||||
// will be copied into that array. Otherwise, a new TypedArray will be allocated
|
||||
// and returned.
|
||||
CanvasKit.ShapedText.prototype.getBounds = function(optionalOutputArray) {
|
||||
this._getBounds(_scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._getBounds(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optionalOutputArray) {
|
||||
optionalOutputArray.set(ta);
|
||||
return optionalOutputArray;
|
||||
|
@ -23,11 +23,11 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
_scratchRRect2 = CanvasKit.Malloc(Float32Array, 12); // 4 scalars for rrect, 8 for radii.
|
||||
_scratchRRect2Ptr = _scratchRRect2['byteOffset'];
|
||||
|
||||
_scratchRect = CanvasKit.Malloc(Float32Array, 4);
|
||||
_scratchRectPtr = _scratchRect['byteOffset'];
|
||||
_scratchFourFloatsA = CanvasKit.Malloc(Float32Array, 4);
|
||||
_scratchFourFloatsAPtr = _scratchFourFloatsA['byteOffset'];
|
||||
|
||||
_scratchRect2 = CanvasKit.Malloc(Float32Array, 4);
|
||||
_scratchRect2Ptr = _scratchRect2['byteOffset'];
|
||||
_scratchFourFloatsB = CanvasKit.Malloc(Float32Array, 4);
|
||||
_scratchFourFloatsBPtr = _scratchFourFloatsB['byteOffset'];
|
||||
|
||||
_scratchIRect = CanvasKit.Malloc(Int32Array, 4);
|
||||
_scratchIRectPtr = _scratchIRect['byteOffset'];
|
||||
@ -227,8 +227,8 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
// will be copied into that array. Otherwise, a new TypedArray will be allocated
|
||||
// and returned.
|
||||
CanvasKit.Path.prototype.computeTightBounds = function(optionalOutputArray) {
|
||||
this._computeTightBounds(_scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._computeTightBounds(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optionalOutputArray) {
|
||||
optionalOutputArray.set(ta);
|
||||
return optionalOutputArray;
|
||||
@ -252,8 +252,8 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
// will be copied into that array. Otherwise, a new TypedArray will be allocated
|
||||
// and returned.
|
||||
CanvasKit.Path.prototype.getBounds = function(optionalOutputArray) {
|
||||
this._getBounds(_scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._getBounds(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optionalOutputArray) {
|
||||
optionalOutputArray.set(ta);
|
||||
return optionalOutputArray;
|
||||
@ -574,21 +574,23 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
};
|
||||
|
||||
CanvasKit.Canvas.prototype.drawImageRect = function(img, src, dest, paint, fastSample) {
|
||||
var sPtr = copyRectToWasm(src, _scratchRectPtr);
|
||||
var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
|
||||
this._drawImageRect(img, sPtr, dPtr, paint, !!fastSample);
|
||||
copyRectToWasm(src, _scratchFourFloatsAPtr);
|
||||
copyRectToWasm(dest, _scratchFourFloatsBPtr);
|
||||
this._drawImageRect(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, paint, !!fastSample);
|
||||
};
|
||||
|
||||
CanvasKit.Canvas.prototype.drawImageRectCubic = function(img, src, dest, B, C, paint) {
|
||||
var sPtr = copyRectToWasm(src, _scratchRectPtr);
|
||||
var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
|
||||
this._drawImageRectCubic(img, sPtr, dPtr, B, C, paint || null);
|
||||
copyRectToWasm(src, _scratchFourFloatsAPtr);
|
||||
copyRectToWasm(dest, _scratchFourFloatsBPtr);
|
||||
this._drawImageRectCubic(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, B, C,
|
||||
paint || null);
|
||||
};
|
||||
|
||||
CanvasKit.Canvas.prototype.drawImageRectOptions = function(img, src, dest, filter, mipmap, paint) {
|
||||
var sPtr = copyRectToWasm(src, _scratchRectPtr);
|
||||
var dPtr = copyRectToWasm(dest, _scratchRect2Ptr);
|
||||
this._drawImageRectOptions(img, sPtr, dPtr, filter, mipmap, paint || null);
|
||||
copyRectToWasm(src, _scratchFourFloatsAPtr);
|
||||
copyRectToWasm(dest, _scratchFourFloatsBPtr);
|
||||
this._drawImageRectOptions(img, _scratchFourFloatsAPtr, _scratchFourFloatsBPtr, filter, mipmap,
|
||||
paint || null);
|
||||
};
|
||||
|
||||
CanvasKit.Canvas.prototype.drawOval = function(oval, paint) {
|
||||
@ -628,11 +630,11 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
flags, optOutputRect) {
|
||||
var ctmPtr = copy3x3MatrixToWasm(ctm);
|
||||
var ok = this._getShadowLocalBounds(ctmPtr, path, zPlaneParams, lightPos, lightRadius,
|
||||
flags, _scratchRectPtr);
|
||||
flags, _scratchFourFloatsAPtr);
|
||||
if (!ok) {
|
||||
return null;
|
||||
}
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optOutputRect) {
|
||||
optOutputRect.set(ta);
|
||||
return optOutputRect;
|
||||
@ -753,6 +755,21 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
this._setColor(cPtr, colorSpace);
|
||||
};
|
||||
|
||||
CanvasKit.Path.prototype.getPoint = function(idx, optionalOutput) {
|
||||
// This will copy 2 floats into a space for 4 floats
|
||||
this._getPoint(idx, _scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optionalOutput) {
|
||||
// We cannot call optionalOutput.set() because it is an error to call .set() with
|
||||
// a source bigger than the destination.
|
||||
optionalOutput[0] = ta[0];
|
||||
optionalOutput[1] = ta[1];
|
||||
return optionalOutput;
|
||||
}
|
||||
// Be sure to return a copy of just the first 2 values.
|
||||
return ta.slice(0, 2);
|
||||
};
|
||||
|
||||
CanvasKit.PictureRecorder.prototype.beginRecording = function(bounds) {
|
||||
var bPtr = copyRectToWasm(bounds);
|
||||
return this._beginRecording(bPtr);
|
||||
@ -812,7 +829,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
};
|
||||
|
||||
CanvasKit.Shader.MakeColor = function(color4f, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
colorSpace = colorSpace || null;
|
||||
var cPtr = copyColorToWasm(color4f);
|
||||
return CanvasKit.Shader._MakeColor(cPtr, colorSpace);
|
||||
};
|
||||
@ -829,7 +846,12 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
flags = flags || 0;
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
|
||||
var lgs = CanvasKit.Shader._MakeLinearGradient(start, end, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
|
||||
// Copy start and end to _scratchFourFloatsAPtr.
|
||||
var startEndPts = _scratchFourFloatsA['toTypedArray']();
|
||||
startEndPts.set(start);
|
||||
startEndPts.set(end, 2);
|
||||
|
||||
var lgs = CanvasKit.Shader._MakeLinearGradient(_scratchFourFloatsAPtr, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
|
||||
cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
|
||||
|
||||
freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
|
||||
@ -838,14 +860,15 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
};
|
||||
|
||||
CanvasKit.Shader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
colorSpace = colorSpace || null;
|
||||
var cPtrInfo = copyFlexibleColorArray(colors);
|
||||
var posPtr = copy1dArray(pos, 'HEAPF32');
|
||||
flags = flags || 0;
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
|
||||
var rgs = CanvasKit.Shader._MakeRadialGradient(center, radius, cPtrInfo.colorPtr, cPtrInfo.colorType, posPtr,
|
||||
cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
|
||||
var rgs = CanvasKit.Shader._MakeRadialGradient(center[0], center[1], radius, cPtrInfo.colorPtr,
|
||||
cPtrInfo.colorType, posPtr, cPtrInfo.count, mode,
|
||||
flags, localMatrixPtr, colorSpace);
|
||||
|
||||
freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
|
||||
pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
|
||||
@ -853,7 +876,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
};
|
||||
|
||||
CanvasKit.Shader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
colorSpace = colorSpace || null;
|
||||
var cPtrInfo = copyFlexibleColorArray(colors);
|
||||
var posPtr = copy1dArray(pos, 'HEAPF32');
|
||||
flags = flags || 0;
|
||||
@ -873,14 +896,19 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
|
||||
CanvasKit.Shader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
|
||||
colors, pos, mode, localMatrix, flags, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
colorSpace = colorSpace || null;
|
||||
var cPtrInfo = copyFlexibleColorArray(colors);
|
||||
var posPtr = copy1dArray(pos, 'HEAPF32');
|
||||
flags = flags || 0;
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
|
||||
var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(
|
||||
start, startRadius, end, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType,
|
||||
// Copy start and end to _scratchFourFloatsAPtr.
|
||||
var startEndPts = _scratchFourFloatsA['toTypedArray']();
|
||||
startEndPts.set(start);
|
||||
startEndPts.set(end, 2);
|
||||
|
||||
var rgs = CanvasKit.Shader._MakeTwoPointConicalGradient(_scratchFourFloatsAPtr,
|
||||
startRadius, endRadius, cPtrInfo.colorPtr, cPtrInfo.colorType,
|
||||
posPtr, cPtrInfo.count, mode, flags, localMatrixPtr, colorSpace);
|
||||
|
||||
freeArraysThatAreNotMallocedByUsers(cPtrInfo.colorPtr, colors);
|
||||
@ -892,8 +920,8 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
// will be copied into that array. Otherwise, a new TypedArray will be allocated
|
||||
// and returned.
|
||||
CanvasKit.Vertices.prototype.bounds = function(optionalOutputArray) {
|
||||
this._bounds(_scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._bounds(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optionalOutputArray) {
|
||||
optionalOutputArray.set(ta);
|
||||
return optionalOutputArray;
|
||||
|
@ -84,11 +84,11 @@ var _scratch4x4Matrix; // the result from CanvasKit.Malloc
|
||||
var _scratchColorPtr = nullptr;
|
||||
var _scratchColor; // the result from CanvasKit.Malloc
|
||||
|
||||
var _scratchRect;
|
||||
var _scratchRectPtr = nullptr;
|
||||
var _scratchFourFloatsA;
|
||||
var _scratchFourFloatsAPtr = nullptr;
|
||||
|
||||
var _scratchRect2;
|
||||
var _scratchRect2Ptr = nullptr;
|
||||
var _scratchFourFloatsB;
|
||||
var _scratchFourFloatsBPtr = nullptr;
|
||||
|
||||
var _scratchIRect;
|
||||
var _scratchIRectPtr = nullptr;
|
||||
@ -354,7 +354,7 @@ function copyColorFromWasm(colorPtr) {
|
||||
// copies the given floats into the wasm heap as an SkRect. Unless a non-scratch pointer is
|
||||
// passed into ptr, callers do NOT need to free the returned pointer.
|
||||
function copyRectToWasm(fourFloats, ptr) {
|
||||
return copy1dArray(fourFloats, 'HEAPF32', ptr || _scratchRectPtr);
|
||||
return copy1dArray(fourFloats, 'HEAPF32', ptr || _scratchFourFloatsAPtr);
|
||||
}
|
||||
|
||||
// copies the given ints into the wasm heap as an SkIRect. Unless a non-scratch pointer is
|
||||
|
@ -63,6 +63,9 @@ CanvasKit._extraInitializations.push(function() {
|
||||
return new Float32Array();
|
||||
}
|
||||
return new Float32Array(CanvasKit.HEAPU8.buffer, fptr, numFloats);
|
||||
}
|
||||
};
|
||||
|
||||
CanvasKit.ParticleEffect.setPosition = function(pos) {
|
||||
this._setPosition(pos[0], pos[1]);
|
||||
};
|
||||
});
|
||||
|
@ -128,7 +128,10 @@ EMSCRIPTEN_BINDINGS(Particles) {
|
||||
su = fromUniform(info->fUniforms[i]);
|
||||
return su;
|
||||
}))
|
||||
.function("setPosition", select_overload<void (SkPoint)>(&SkParticleEffect::setPosition))
|
||||
.function("_setPosition", optional_override([](SkParticleEffect& self,
|
||||
SkScalar x, SkScalar y)->void {
|
||||
self.setPosition({x, y});
|
||||
}))
|
||||
.function("setRate", select_overload<void (float)>(&SkParticleEffect::setRate))
|
||||
.function("start", select_overload<void (double, bool)>(&SkParticleEffect::start))
|
||||
.function("update", select_overload<void (double)>(&SkParticleEffect::update));
|
||||
|
@ -64,40 +64,70 @@ CanvasKit.MakeManagedAnimation = function(json, assets, prop_filter_prefix) {
|
||||
CanvasKit._extraInitializations.push(function() {
|
||||
|
||||
CanvasKit.Animation.prototype.render = function(canvas, dstRect) {
|
||||
var dPtr = copyRectToWasm(dstRect);
|
||||
this._render(canvas, dPtr);
|
||||
}
|
||||
copyRectToWasm(dstRect, _scratchFourFloatsAPtr);
|
||||
this._render(canvas, _scratchFourFloatsAPtr);
|
||||
};
|
||||
|
||||
CanvasKit.Animation.prototype.size = function(optSize) {
|
||||
// This will copy 2 floats into a space for 4 floats
|
||||
this._size(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optSize) {
|
||||
// We cannot call optSize.set() because it is an error to call .set() with
|
||||
// a source bigger than the destination.
|
||||
optSize[0] = ta[0];
|
||||
optSize[1] = ta[1];
|
||||
return optSize;
|
||||
}
|
||||
// Be sure to return a copy of just the first 2 values.
|
||||
return ta.slice(0, 2);
|
||||
};
|
||||
|
||||
if (CanvasKit.ManagedAnimation) {
|
||||
CanvasKit.ManagedAnimation.prototype.render = function(canvas, dstRect) {
|
||||
var dPtr = copyRectToWasm(dstRect);
|
||||
this._render(canvas, dPtr);
|
||||
}
|
||||
copyRectToWasm(dstRect, _scratchFourFloatsAPtr);
|
||||
this._render(canvas, _scratchFourFloatsAPtr);
|
||||
};
|
||||
|
||||
CanvasKit.ManagedAnimation.prototype.seek = function(t, optDamageRect) {
|
||||
this._seek(t, _scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._seek(t, _scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optDamageRect) {
|
||||
optDamageRect.set(ta);
|
||||
return optDamageRect;
|
||||
}
|
||||
return ta.slice();
|
||||
}
|
||||
};
|
||||
|
||||
CanvasKit.ManagedAnimation.prototype.seekFrame = function(frame, optDamageRect) {
|
||||
this._seekFrame(frame, _scratchRectPtr);
|
||||
var ta = _scratchRect['toTypedArray']();
|
||||
this._seekFrame(frame, _scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optDamageRect) {
|
||||
optDamageRect.set(ta);
|
||||
return optDamageRect;
|
||||
}
|
||||
return ta.slice();
|
||||
}
|
||||
};
|
||||
|
||||
CanvasKit.ManagedAnimation.prototype.setColor = function(key, color) {
|
||||
var cPtr = copyColorToWasm(color);
|
||||
this._setColor(key, cPtr);
|
||||
}
|
||||
};
|
||||
|
||||
CanvasKit.ManagedAnimation.prototype.size = function(optSize) {
|
||||
// This will copy 2 floats into a space for 4 floats
|
||||
this._size(_scratchFourFloatsAPtr);
|
||||
var ta = _scratchFourFloatsA['toTypedArray']();
|
||||
if (optSize) {
|
||||
// We cannot call optSize.set() because it is an error to call .set() with
|
||||
// a source bigger than the destination.
|
||||
optSize[0] = ta[0];
|
||||
optSize[1] = ta[1];
|
||||
return optSize;
|
||||
}
|
||||
// Be sure to return a copy of just the first 2 values.
|
||||
return ta.slice(0, 2);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,7 +197,11 @@ EMSCRIPTEN_BINDINGS(Skottie) {
|
||||
.function("version", optional_override([](skottie::Animation& self)->std::string {
|
||||
return std::string(self.version().c_str());
|
||||
}))
|
||||
.function("size" , &skottie::Animation::size)
|
||||
.function("_size", optional_override([](skottie::Animation& self,
|
||||
uintptr_t /* float* */ oPtr)->void {
|
||||
SkSize* output = reinterpret_cast<SkSize*>(oPtr);
|
||||
*output = self.size();
|
||||
}))
|
||||
.function("duration", &skottie::Animation::duration)
|
||||
.function("fps" , &skottie::Animation::fps)
|
||||
.function("seek", optional_override([](skottie::Animation& self, SkScalar t)->void {
|
||||
@ -221,7 +225,11 @@ EMSCRIPTEN_BINDINGS(Skottie) {
|
||||
class_<ManagedAnimation>("ManagedAnimation")
|
||||
.smart_ptr<sk_sp<ManagedAnimation>>("sk_sp<ManagedAnimation>")
|
||||
.function("version" , &ManagedAnimation::version)
|
||||
.function("size" , &ManagedAnimation::size)
|
||||
.function("_size", optional_override([](ManagedAnimation& self,
|
||||
uintptr_t /* float* */ oPtr)->void {
|
||||
SkSize* output = reinterpret_cast<SkSize*>(oPtr);
|
||||
*output = self.size();
|
||||
}))
|
||||
.function("duration" , &ManagedAnimation::duration)
|
||||
.function("fps" , &ManagedAnimation::fps)
|
||||
.function("_render", optional_override([](ManagedAnimation& self, SkCanvas* canvas,
|
||||
|
@ -233,6 +233,25 @@ describe('Path Behavior', () => {
|
||||
CanvasKit.Free(mWeights);
|
||||
});
|
||||
|
||||
it('can retrieve points from a path', () => {
|
||||
const path = new CanvasKit.Path();
|
||||
path.addRect([10, 15, 20, 25]);
|
||||
|
||||
let pt = path.getPoint(0);
|
||||
expect(pt[0]).toEqual(10);
|
||||
expect(pt[1]).toEqual(15);
|
||||
|
||||
path.getPoint(2, pt);
|
||||
expect(pt[0]).toEqual(20);
|
||||
expect(pt[1]).toEqual(25);
|
||||
|
||||
path.getPoint(1000, pt); // off the end returns (0, 0) as per the docs.
|
||||
expect(pt[0]).toEqual(0);
|
||||
expect(pt[1]).toEqual(0);
|
||||
|
||||
path.delete();
|
||||
});
|
||||
|
||||
gm('offset_path', (canvas) => {
|
||||
const path = starPath(CanvasKit);
|
||||
|
||||
|
@ -15,7 +15,7 @@ describe('Skottie behavior', () => {
|
||||
});
|
||||
|
||||
const expectArrayCloseTo = (a, b, precision) => {
|
||||
precision = precision || 14 // digits of precision in base 10
|
||||
precision = precision || 14; // digits of precision in base 10
|
||||
expect(a.length).toEqual(b.length);
|
||||
for (let i=0; i<a.length; i++) {
|
||||
expect(a[i]).toBeCloseTo(b[i], precision);
|
||||
@ -41,6 +41,9 @@ describe('Skottie behavior', () => {
|
||||
expect(animation).toBeTruthy();
|
||||
const bounds = CanvasKit.LTRBRect(0, 0, 500, 500);
|
||||
|
||||
const size = animation.size();
|
||||
expectArrayCloseTo(size, Float32Array.of(800, 600), 4);
|
||||
|
||||
canvas.clear(CanvasKit.WHITE);
|
||||
animation.render(canvas, bounds);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user