Add software backend to gpu build
Bug: skia:8548
Change-Id: If3853711f4b183f3b0437ae2b31525b0e6c88213
Reviewed-on: https://skia-review.googlesource.com/c/172120
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/experimental/canvaskit/Makefile b/experimental/canvaskit/Makefile
index cc9f332..3673fbf 100644
--- a/experimental/canvaskit/Makefile
+++ b/experimental/canvaskit/Makefile
@@ -12,7 +12,7 @@
release_cpu:
# Does an incremental build where possible.
- ./compile.sh cpu
+ ./compile.sh cpu_only
mkdir -p ./canvaskit/bin
cp ../../out/canvaskit_wasm/canvaskit.js ./canvaskit/bin
cp ../../out/canvaskit_wasm/canvaskit.wasm ./canvaskit/bin
@@ -26,7 +26,7 @@
debug_cpu:
# Does an incremental build where possible.
- ./compile.sh debug cpu
+ ./compile.sh debug cpu_only
mkdir -p ./canvaskit/bin
cp ../../out/canvaskit_wasm_debug/canvaskit.js ./canvaskit/bin
cp ../../out/canvaskit_wasm_debug/canvaskit.wasm ./canvaskit/bin
diff --git a/experimental/canvaskit/canvaskit/example.html b/experimental/canvaskit/canvaskit/example.html
index fc387ad..8b22bf4 100644
--- a/experimental/canvaskit/canvaskit/example.html
+++ b/experimental/canvaskit/canvaskit/example.html
@@ -9,7 +9,7 @@
border: 1px dashed #AAA;
}
- #patheffect,#paths,#sk_drinks,#sk_party, #sk_legos, #sk_onboarding
+ #patheffect,#paths,#sk_drinks,#sk_party, #sk_legos, #sk_onboarding,
#api1_c, #api2_c {
width: 300px;
height: 300px;
@@ -428,10 +428,6 @@
}
function CanvasAPI1(CanvasKit) {
- if (CanvasKit.gpu) {
- console.warn("Skipping canvas example because its GPU build");
- return;
- }
let skcanvas = CanvasKit.MakeCanvas(300, 300);
let realCanvas = document.getElementById('api1_c');
@@ -457,10 +453,6 @@
}
function CanvasAPI2(CanvasKit) {
- if (CanvasKit.gpu) {
- console.warn("Skipping canvas example because its GPU build");
- return;
- }
let skcanvas = CanvasKit.MakeCanvas(200, 200);
let realCanvas = document.getElementById('api2_c');
realCanvas.width = 200;
diff --git a/experimental/canvaskit/canvaskit_bindings.cpp b/experimental/canvaskit/canvaskit_bindings.cpp
index a7fb875..4d9b73f 100644
--- a/experimental/canvaskit/canvaskit_bindings.cpp
+++ b/experimental/canvaskit/canvaskit_bindings.cpp
@@ -341,11 +341,11 @@
function("currentContext", &emscripten_webgl_get_current_context);
function("setCurrentContext", &emscripten_webgl_make_context_current);
constant("gpu", true);
-#else
+#endif
function("_getRasterN32PremulSurface", optional_override([](int width, int height)->sk_sp<SkSurface> {
return SkSurface::MakeRasterN32Premul(width, height, nullptr);
}), allow_raw_pointers());
-#endif
+
function("getSkDataBytes", &getSkDataBytes, allow_raw_pointers());
function("MakeSkCornerPathEffect", &SkCornerPathEffect::Make, allow_raw_pointers());
function("MakeSkDiscretePathEffect", &SkDiscretePathEffect::Make, allow_raw_pointers());
diff --git a/experimental/canvaskit/compile.sh b/experimental/canvaskit/compile.sh
index 5979f98..881f7f4 100755
--- a/experimental/canvaskit/compile.sh
+++ b/experimental/canvaskit/compile.sh
@@ -36,7 +36,7 @@
GN_GPU="skia_enable_gpu=true"
GN_GPU_FLAGS="\"-DIS_WEBGL=1\", \"-DSK_DISABLE_LEGACY_SHADERCONTEXT\","
WASM_GPU="-lEGL -lGLESv2 -DSK_SUPPORT_GPU=1 \
- -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/gpu.js"
+ -DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/gpu.js"
if [[ $@ == *cpu* ]]; then
echo "Using the CPU backend instead of the GPU backend"
GN_GPU="skia_enable_gpu=false"
diff --git a/experimental/canvaskit/cpu.js b/experimental/canvaskit/cpu.js
index d144664..a0282d5 100644
--- a/experimental/canvaskit/cpu.js
+++ b/experimental/canvaskit/cpu.js
@@ -3,7 +3,7 @@
(function(CanvasKit){
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
CanvasKit._extraInitializations.push(function() {
- CanvasKit.MakeCanvasSurface = function(htmlID) {
+ CanvasKit.MakeSWCanvasSurface = function(htmlID) {
var canvas = document.getElementById(htmlID);
if (!canvas) {
throw 'Canvas with id ' + htmlID + ' was not found';
@@ -22,6 +22,11 @@
return surface;
};
+ // Don't over-write the MakeCanvasSurface set by gpu.js if it exists.
+ if (!CanvasKit.MakeCanvasSurface) {
+ CanvasKit.MakeCanvasSurface = CanvasKit.MakeSWCanvasSurface;
+ }
+
CanvasKit.MakeSurface = function(width, height) {
var surface = this._getRasterN32PremulSurface(width, height);
if (surface) {
@@ -38,6 +43,7 @@
CanvasKit.SkSurface.prototype.flush = function() {
this._flush();
// Do we have an HTML canvas to write the pixels to?
+ // We will not if this a GPU build or a raster surface, for example.
if (this._canvas) {
var success = this._readPixels(this._width, this._height, this._pixelPtr);
if (!success) {
@@ -60,12 +66,12 @@
this.delete();
}
- CanvasKit.currentContext = function() {
- // no op. aka return undefined.
+ CanvasKit.currentContext = CanvasKit.currentContext || function() {
+ // no op if this is a cpu-only build.
};
- CanvasKit.setCurrentContext = function() {
- // no op. aka return undefined.
+ CanvasKit.setCurrentContext = CanvasKit.setCurrentContext || function() {
+ // no op if this is a cpu-only build.
};
});
}(Module)); // When this file is loaded in, the high level object is "Module";
diff --git a/experimental/canvaskit/externs.js b/experimental/canvaskit/externs.js
index 7c5159f..1f1be54 100644
--- a/experimental/canvaskit/externs.js
+++ b/experimental/canvaskit/externs.js
@@ -29,6 +29,8 @@
LTRBRect: function() {},
MakeCanvas: function() {},
MakeCanvasSurface: function() {},
+ MakeSWCanvasSurface: function() {},
+ MakeWebGLCanvasSurface: function() {},
MakeImageShader: function() {},
MakeLinearGradientShader: function() {},
MakeRadialGradientShader: function() {},
diff --git a/experimental/canvaskit/gpu.js b/experimental/canvaskit/gpu.js
index 3a26842..348ea29 100644
--- a/experimental/canvaskit/gpu.js
+++ b/experimental/canvaskit/gpu.js
@@ -3,22 +3,21 @@
(function(CanvasKit){
CanvasKit._extraInitializations = CanvasKit._extraInitializations || [];
CanvasKit._extraInitializations.push(function() {
- CanvasKit.MakeCanvasSurface = function(htmlID) {
+ CanvasKit.MakeWebGLCanvasSurface = function(htmlID) {
var canvas = document.getElementById(htmlID);
if (!canvas) {
throw 'Canvas with id ' + htmlID + ' was not found';
}
// Maybe better to use clientWidth/height. See:
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
- return this._getWebGLSurface(htmlID, canvas.width, canvas.height);
+ var surface = this._getWebGLSurface(htmlID, canvas.width, canvas.height);
+ if (!surface) {
+ console.log('falling back from GPU implementation to a SW based one');
+ return CanvasKit.MakeSWCanvasSurface(htmlID);
+ }
+ return surface;
};
-
- CanvasKit.SkSurface.prototype.flush = function() {
- this._flush();
- }
-
- CanvasKit.SkSurface.prototype.dispose = function() {
- this.delete();
- }
+ // Default to trying WebGL first.
+ CanvasKit.MakeCanvasSurface = CanvasKit.MakeWebGLCanvasSurface;
});
}(Module)); // When this file is loaded in, the high level object is "Module";
diff --git a/experimental/canvaskit/tests/canvas2d.spec.js b/experimental/canvaskit/tests/canvas2d.spec.js
index c763362..d2b3f66 100644
--- a/experimental/canvaskit/tests/canvas2d.spec.js
+++ b/experimental/canvaskit/tests/canvas2d.spec.js
@@ -81,12 +81,6 @@
}); // end describe('color string parsing')
function multipleCanvasTest(testname, done, test) {
- if (CanvasKit.gpu) {
- // TODO(kjlubick): add Software backend to GPU build skia:8548
- console.log(`SKIPPING ${testname} on GPU`);
- done();
- return;
- }
const skcanvas = CanvasKit.MakeCanvas(CANVAS_WIDTH, CANVAS_HEIGHT);
skcanvas._config = 'software_canvas';
const realCanvas = document.getElementById('test');