Unit test of drawAtlas and fixes for bugs uncovered by it

Change-Id: I3583a5b3930aba03ae843daade50223e87c4ac6f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294338
Commit-Queue: Nathaniel Nifong <nifong@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Nathaniel Nifong 2020-06-05 11:17:43 -04:00 committed by Skia Commit-Bot
parent 43f443f086
commit cd75b17943
3 changed files with 91 additions and 15 deletions

View File

@ -1180,8 +1180,8 @@
dsts.push(0, .8, 200, 100);
const colors = new CanvasKit.SkColorBuilder();
colors.push(CanvasKit.Color(85, 170, 10, 0.5)); // light green
colors.push(CanvasKit.Color(51, 51, 191, 0.5)); // light blue
colors.push(CanvasKit.ColorAsInt(85, 170, 10, 128)); // light green
colors.push(CanvasKit.ColorAsInt(51, 51, 191, 128)); // light blue
let i = 0;

View File

@ -877,16 +877,24 @@ CanvasKit.onRuntimeInitialized = function() {
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.
// colors, if provided, should be a CanvasKit.SkColorBuilder or array of float colors (arrays of 4 floats)
// srcRects, dstXforms, and colors should be CanvasKit.SkRectBuilder, CanvasKit.RSXFormBuilder,
// and CanvasKit.SkColorBuilder (fastest)
// Or they can be an array of floats of length 4*number of destinations.
// colors are optional and used to tint the drawn images using the optional blend mode
// drawAtlas ONLY accepts uint colors such as those created with CanvasKit.ColorAsInt(r, g, b, a)
// whether they are provided as an array or a builder.
CanvasKit.SkCanvas.prototype.drawAtlas = function(atlas, srcRects, dstXforms, paint,
/*optional*/ blendMode, colors) {
if (!atlas || !paint || !srcRects || !dstXforms) {
SkDebug('Doing nothing since missing a required input');
return;
}
if (srcRects.length !== dstXforms.length || (colors && colors.length !== dstXforms.length)) {
// builder arguments report the length as the number of rects, but when passed as arrays
// their.length attribute is 4x higher because it's the number of total components of all rects.
// colors is always going to report the same length, at least until floats colors are supported
// by this function.
if (srcRects.length !== dstXforms.length) {
SkDebug('Doing nothing since input arrays length mismatches');
return;
}
@ -901,11 +909,14 @@ CanvasKit.onRuntimeInitialized = function() {
srcRectPtr = copy1dArray(srcRects, "HEAPF32");
}
var count = 1;
var dstXformPtr;
if (dstXforms.build) {
dstXformPtr = dstXforms.build();
count = dstXforms.length;
} else {
dstXformPtr = copy1dArray(dstXforms, "HEAPF32");
count = dstXforms.length / 4;
}
var colorPtr = nullptr;
@ -913,19 +924,11 @@ CanvasKit.onRuntimeInitialized = function() {
if (colors.build) {
colorPtr = colors.build();
} else {
if (!isCanvasKitColor(colors[0])) {
SkDebug('DrawAtlas color argument expected to be CanvasKit.SkRectBuilder or array of ' +
'float arrays, but got '+colors);
return;
}
// convert here
colors = colors.map(toUint32Color);
colorPtr = copy1dArray(colors, "HEAPU32");
}
}
this._drawAtlas(atlas, dstXformPtr, srcRectPtr, colorPtr, dstXforms.length,
blendMode, paint);
this._drawAtlas(atlas, dstXformPtr, srcRectPtr, colorPtr, count, blendMode, paint);
if (srcRectPtr && !srcRects.build) {
freeArraysThatAreNotMallocedByUsers(srcRectPtr, srcRects);

View File

@ -184,8 +184,81 @@ describe('Core canvas behavior', () => {
CanvasKit.SkColorSpace.SRGB);
canvas.drawImage(img, 1, 1, paint);
img.delete();
paint.delete();
});
gm('draw_atlas_with_builders', (canvas, fetchedByteBuffers) => {
const atlas = CanvasKit.MakeImageFromEncoded(fetchedByteBuffers[0]);
expect(atlas).toBeTruthy();
canvas.clear(CanvasKit.WHITE);
const paint = new CanvasKit.SkPaint();
paint.setColor(CanvasKit.Color(0, 0, 0, 0.8));
const srcs = new CanvasKit.SkRectBuilder();
// left top right bottom
srcs.push( 0, 0, 256, 256);
srcs.push(256, 0, 512, 256);
srcs.push( 0, 256, 256, 512);
srcs.push(256, 256, 512, 512);
const dsts = new CanvasKit.RSXFormBuilder();
// scos, ssin, tx, ty
dsts.push(0.5, 0, 20, 20);
dsts.push(0.5, 0, 300, 20);
dsts.push(0.5, 0, 20, 300);
dsts.push(0.5, 0, 300, 300);
const colors = new CanvasKit.SkColorBuilder();
// note that the SkColorBuilder expects int colors to be pushed.
// pushing float colors to it only causes weird problems way downstream.
// It does no type checking.
colors.push(CanvasKit.ColorAsInt( 85, 170, 10, 128)); // light green
colors.push(CanvasKit.ColorAsInt( 51, 51, 191, 128)); // light blue
colors.push(CanvasKit.ColorAsInt( 0, 0, 0, 128));
colors.push(CanvasKit.ColorAsInt(256, 256, 256, 128));
canvas.drawAtlas(atlas, srcs, dsts, paint, CanvasKit.BlendMode.Modulate, colors);
atlas.delete();
paint.delete();
}, '/assets/mandrill_512.png')
gm('draw_atlas_with_arrays', (canvas, fetchedByteBuffers) => {
const atlas = CanvasKit.MakeImageFromEncoded(fetchedByteBuffers[0]);
expect(atlas).toBeTruthy();
canvas.clear(CanvasKit.WHITE);
const paint = new CanvasKit.SkPaint();
paint.setColor(CanvasKit.Color(0, 0, 0, 0.8));
const srcs = [
0, 0, 256, 256,
256, 0, 512, 256,
0, 256, 256, 512,
256, 256, 512, 512,
];
const dsts = [
0.5, 0, 20, 20,
0.5, 0, 300, 20,
0.5, 0, 20, 300,
0.5, 0, 300, 300,
];
const colors = [
CanvasKit.ColorAsInt( 85, 170, 10, 128), // light green
CanvasKit.ColorAsInt( 51, 51, 191, 128), // light blue
CanvasKit.ColorAsInt( 0, 0, 0, 128),
CanvasKit.ColorAsInt(256, 256, 256, 128),
];
canvas.drawAtlas(atlas, srcs, dsts, paint, CanvasKit.BlendMode.Modulate, colors);
atlas.delete();
paint.delete();
}, '/assets/mandrill_512.png')
gm('sweep_gradient', (canvas) => {
const paint = new CanvasKit.SkPaint();
const shader = CanvasKit.SkShader.MakeSweepGradient(