Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 3d99b1e

Browse files
committed
Add Correctness tests for CanvasKit
Also make a CPU only and GPU only build (although the latter still has a lot of CPU logic). Bug: skia: Change-Id: I857c2300021c2adb5344865c28e4ad3e8d332954 Reviewed-on: https://skia-review.googlesource.com/c/162022 Reviewed-by: Kevin Lubick <[email protected]>
1 parent 1bfcbb5 commit 3d99b1e

37 files changed

+3711
-1465
lines changed

experimental/canvaskit/Makefile

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
clean:
22
rm -rf ../../out/canvaskit_wasm
3-
rm -rf ./canvas-kit/bin
3+
rm -rf ./canvaskit/bin
44
$(MAKE) release
55

66
release:
77
# Does an incremental build where possible.
88
./compile.sh
9-
mkdir -p ./canvas-kit/bin
10-
cp ../../out/canvaskit_wasm/canvaskit.js ./canvas-kit/bin
11-
cp ../../out/canvaskit_wasm/canvaskit.wasm ./canvas-kit/bin
9+
mkdir -p ./canvaskit/bin
10+
cp ../../out/canvaskit_wasm/canvaskit.js ./canvaskit/bin
11+
cp ../../out/canvaskit_wasm/canvaskit.wasm ./canvaskit/bin
1212

1313
debug:
1414
# Does an incremental build where possible.
1515
./compile.sh debug
16-
mkdir -p ./canvas-kit/bin
17-
cp ../../out/canvaskit_wasm/canvaskit.js ./canvas-kit/bin
18-
cp ../../out/canvaskit_wasm/canvaskit.wasm ./canvas-kit/bin
16+
mkdir -p ./canvaskit/bin
17+
cp ../../out/canvaskit_wasm_debug/canvaskit.js ./canvaskit/bin
18+
cp ../../out/canvaskit_wasm_debug/canvaskit.wasm ./canvaskit/bin
1919

2020
local-example:
21-
rm -rf node_modules/canvas-kit
21+
rm -rf node_modules/canvaskit
2222
mkdir -p node_modules
23-
ln -s -T ../canvas-kit node_modules/canvas-kit
24-
echo "Go check out http://localhost:8000/canvas-kit/example.html"
23+
ln -s -T ../canvaskit node_modules/canvaskit
24+
echo "Go check out http://localhost:8000/canvaskit/example.html"
2525
python serve.py
26+
27+
test-continuous:
28+
echo "Assuming npm install has been run by user"
29+
echo "Also assuming make debug or release has also been run by a user (if needed)"
30+
npx karma start ./karma.conf.js --no-single-run --watch-poll

experimental/canvaskit/canvas-kit/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
bin/
2+
package-lock.json
3+
node_modules/
File renamed without changes.
File renamed without changes.
File renamed without changes.

experimental/canvaskit/canvaskit_bindings.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "GrGLTypes.h"
1313
#endif
1414

15-
#include "SkCanvas.h"
1615
#include "SkCanvas.h"
1716
#include "SkDashPathEffect.h"
1817
#include "SkCornerPathEffect.h"
@@ -211,10 +210,12 @@ EMSCRIPTEN_BINDINGS(Skia) {
211210
function("_getWebGLSurface", &getWebGLSurface, allow_raw_pointers());
212211
function("currentContext", &emscripten_webgl_get_current_context);
213212
function("setCurrentContext", &emscripten_webgl_make_context_current);
214-
#endif
213+
constant("gpu", true);
214+
#else
215215
function("_getRasterN32PremulSurface", optional_override([](int width, int height)->sk_sp<SkSurface> {
216216
return SkSurface::MakeRasterN32Premul(width, height, nullptr);
217217
}), allow_raw_pointers());
218+
#endif
218219
function("MakeSkCornerPathEffect", &SkCornerPathEffect::Make, allow_raw_pointers());
219220
function("MakeSkDiscretePathEffect", &SkDiscretePathEffect::Make, allow_raw_pointers());
220221
// Won't be called directly, there's a JS helper to deal with typed arrays.
@@ -236,6 +237,9 @@ EMSCRIPTEN_BINDINGS(Skia) {
236237
.function("drawPath", &SkCanvas::drawPath)
237238
.function("drawRect", &SkCanvas::drawRect)
238239
.function("drawText", optional_override([](SkCanvas& self, std::string text, SkScalar x, SkScalar y, const SkPaint& p) {
240+
// TODO(kjlubick): This does not work well for non-ascii
241+
// Need to maybe add a helper in interface.js that supports UTF-8
242+
// Otherwise, go with std::wstring and set UTF-32 encoding.
239243
self.drawText(text.c_str(), text.length(), x, y, p);
240244
}))
241245
.function("flush", &SkCanvas::flush)
@@ -271,7 +275,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
271275
class_<SkPathEffect>("SkPathEffect")
272276
.smart_ptr<sk_sp<SkPathEffect>>("sk_sp<SkPathEffect>");
273277

274-
//TODO make these chainable like PathKit
275278
class_<SkPath>("SkPath")
276279
.constructor<>()
277280
.constructor<const SkPath&>()
@@ -297,6 +300,7 @@ EMSCRIPTEN_BINDINGS(Skia) {
297300
.smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>")
298301
.function("width", &SkSurface::width)
299302
.function("height", &SkSurface::height)
303+
.function("_flush", &SkSurface::flush)
300304
.function("makeImageSnapshot", &SkSurface::makeImageSnapshot)
301305
.function("_readPixels", optional_override([](SkSurface& self, int width, int height, uintptr_t /* uint8_t* */ cptr)->bool {
302306
auto* dst = reinterpret_cast<uint8_t*>(cptr);
@@ -358,5 +362,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
358362
}), allow_raw_pointers());
359363

360364
function("MakeAnimation", &MakeAnimation);
365+
constant("skottie", true);
361366
#endif
362367
}

experimental/canvaskit/compile.sh

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ if [[ ! -d $EMSDK ]]; then
1313
exit 1
1414
fi
1515

16-
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm"}
17-
mkdir -p $BUILD_DIR
1816
# Navigate to SKIA_HOME from where this file is located.
1917
pushd $BASE_DIR/../..
2018

@@ -24,17 +22,24 @@ EMCXX=`which em++`
2422

2523
RELEASE_CONF="-Oz --closure 1 --llvm-lto 3 -DSK_RELEASE"
2624
EXTRA_CFLAGS="\"-DSK_RELEASE\""
25+
2726
if [[ $@ == *debug* ]]; then
2827
echo "Building a Debug build"
2928
EXTRA_CFLAGS="\"-DSK_DEBUG\""
30-
RELEASE_CONF="-O0 --js-opts 0 -s SAFE_HEAP=1 -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -g3 -DPATHKIT_TESTING -DSK_DEBUG"
29+
RELEASE_CONF="-O0 --js-opts 0 -s DEMANGLE_SUPPORT=1 -s SAFE_HEAP=1 -s ASSERTIONS=1 -s GL_ASSERTIONS=1 -g3 -DPATHKIT_TESTING -DSK_DEBUG"
30+
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_debug"}
31+
else
32+
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm"}
3133
fi
3234

35+
mkdir -p $BUILD_DIR
36+
3337
GN_GPU="skia_enable_gpu=true"
3438
WASM_GPU="-lEGL -lGLESv2 -DSK_SUPPORT_GPU=1"
35-
if [[ $@ == *no_gpu* ]]; then
36-
echo "Omitting the GPU backend"
39+
if [[ $@ == *cpu* ]]; then
40+
echo "Using the CPU backend instead of the GPU backend"
3741
GN_GPU="skia_enable_gpu=false"
42+
GN_GPU_FLAGS=""
3843
WASM_GPU="-DSK_SUPPORT_GPU=0"
3944
fi
4045

experimental/canvaskit/externs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ var CanvasKit = {
3131
MakeSkDashPathEffect: function(intervals, phase) {},
3232
setCurrentContext: function() {},
3333
LTRBRect: function(l, t, r, b) {},
34+
gpu: {},
35+
skottie: {},
3436

3537
// private API (i.e. things declared in the bindings that we use
3638
// in the pre-js file)
@@ -78,9 +80,11 @@ var CanvasKit = {
7880
SkSurface: {
7981
// public API should go below because closure still will
8082
// remove things declared here and not on the prototype.
83+
flush: function() {},
8184

8285
// private API
8386
_readPixels: function(w, h, ptr) {},
87+
_flush: function() {},
8488
}
8589
}
8690

experimental/canvaskit/interface.js

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -107,49 +107,55 @@
107107
return this;
108108
};
109109

110-
CanvasKit.SkSurface.prototype.flush = function() {
111-
var success = this._readPixels(this._width, this._height, this._pixelPtr);
112-
if (!success) {
113-
console.err('could not read pixels');
114-
return;
110+
if (CanvasKit.gpu) {
111+
CanvasKit.getWebGLSurface = function(htmlID) {
112+
var canvas = document.getElementById(htmlID);
113+
if (!canvas) {
114+
throw 'Canvas with id ' + htmlID + ' was not found';
115+
}
116+
// Maybe better to use clientWidth/height. See:
117+
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
118+
return this._getWebGLSurface(htmlID, canvas.width, canvas.height);
119+
};
120+
121+
CanvasKit.SkSurface.prototype.flush = function() {
122+
this._flush();
115123
}
116-
117-
var pixels = new Uint8ClampedArray(CanvasKit.buffer, this._pixelPtr, this._pixelLen);
118-
var imageData = new ImageData(pixels, this._width, this._height);
119-
120-
this.canvas.getContext('2d').putImageData(imageData, 0, 0);
121-
122-
};
123-
}
124-
125-
CanvasKit.getWebGLSurface = function(htmlID) {
126-
var canvas = document.getElementById(htmlID);
127-
if (!canvas) {
128-
throw 'Canvas with id ' + htmlID + ' was not found';
124+
} else {
125+
CanvasKit.getRasterN32PremulSurface = function(htmlID) {
126+
var canvas = document.getElementById(htmlID);
127+
if (!canvas) {
128+
throw 'Canvas with id ' + htmlID + ' was not found';
129+
}
130+
// Maybe better to use clientWidth/height. See:
131+
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
132+
var surface = this._getRasterN32PremulSurface(canvas.width, canvas.height);
133+
if (surface) {
134+
surface.canvas = canvas;
135+
surface._width = canvas.width;
136+
surface._height = canvas.height;
137+
surface._pixelLen = surface._width * surface._height * 4; // it's 8888
138+
// Allocate the buffer of pixels to be used to draw back and forth.
139+
surface._pixelPtr = CanvasKit._malloc(surface._pixelLen);
140+
}
141+
return surface;
142+
};
143+
144+
CanvasKit.SkSurface.prototype.flush = function() {
145+
this._flush();
146+
var success = this._readPixels(this._width, this._height, this._pixelPtr);
147+
if (!success) {
148+
console.err('could not read pixels');
149+
return;
150+
}
151+
152+
var pixels = new Uint8ClampedArray(CanvasKit.buffer, this._pixelPtr, this._pixelLen);
153+
var imageData = new ImageData(pixels, this._width, this._height);
154+
155+
this.canvas.getContext('2d').putImageData(imageData, 0, 0);
156+
};
129157
}
130-
// Maybe better to use clientWidth/height. See:
131-
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
132-
return this._getWebGLSurface(htmlID, canvas.width, canvas.height);
133-
}
134-
135-
CanvasKit.getRasterN32PremulSurface = function(htmlID) {
136-
var canvas = document.getElementById(htmlID);
137-
if (!canvas) {
138-
throw 'Canvas with id ' + htmlID + ' was not found';
139-
}
140-
// Maybe better to use clientWidth/height. See:
141-
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
142-
var surface = this._getRasterN32PremulSurface(canvas.width, canvas.height);
143-
if (surface) {
144-
surface.canvas = canvas;
145-
surface._width = canvas.width;
146-
surface._height = canvas.height;
147-
surface._pixelLen = surface._width * surface._height * 4; // it's 8888
148-
// Allocate the buffer of pixels to be used to draw back and forth.
149-
surface._pixelPtr = CanvasKit._malloc(surface._pixelLen);
150-
}
151-
return surface;
152-
}
158+
} // end CanvasKit.onRuntimeInitialized, that is, anything changing prototypes or dynamic.
153159

154160
// Likely only used for tests.
155161
CanvasKit.LTRBRect = function(l, t, r, b) {

0 commit comments

Comments
 (0)