From ecd8762e1f867a4f095dec3eb599330d368176a0 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Sat, 22 Feb 2020 07:37:33 -0500 Subject: [PATCH] [canvaskit] Support children shaders into runtime shaders Change-Id: I88106babe35f6e5b3ee764e7fbaf82c7f43d136d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272646 Reviewed-by: Nathaniel Nifong --- modules/canvaskit/CHANGELOG.md | 5 +- .../canvaskit/canvaskit/Roboto-Regular.woff | Bin 61736 -> 0 bytes modules/canvaskit/canvaskit/extra.html | 172 +++++++++++++++--- modules/canvaskit/canvaskit_bindings.cpp | 48 ++++- modules/canvaskit/externs.js | 2 + modules/canvaskit/rt_shader.js | 18 ++ 6 files changed, 210 insertions(+), 35 deletions(-) delete mode 100644 modules/canvaskit/canvaskit/Roboto-Regular.woff diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md index d7c2a19f29cc9..5fd4a660cab02 100644 --- a/modules/canvaskit/CHANGELOG.md +++ b/modules/canvaskit/CHANGELOG.md @@ -17,8 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `SkSurface.requestAnimationFrame` for animation logic). - `CanvasKit.parseColorString` which processes color strings like "#2288FF" - Particles module now exposes effect uniforms, which can be modified for live-updating. - - Experimental 4x4 matrices added in `SkM44` - - Vector math functions added in `SkVector` + - Experimental 4x4 matrices added in `SkM44`. + - Vector math functions added in `SkVector`. + - `SkRuntimeEffect.makeShaderWithChildren`, which can take in other shaders as fragmentProcessors. ### Changed - We now compile/ship with Emscripten v1.39.6. diff --git a/modules/canvaskit/canvaskit/Roboto-Regular.woff b/modules/canvaskit/canvaskit/Roboto-Regular.woff deleted file mode 100644 index f823258a4e6e66ff781f4446303823f36201a2eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61736 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 z zdLOR8f2t(9?@DXZifpg=m1oK(D$cHq=WK&aKei3d=u5}58h1t>9V^*ZDGBSo)K<8s zHSD5uWWEGtq!cQflB=11(5hcP^i(Blx>-DwrS+wb+uVX`X>~%yHOy1sI})D23GU3D z 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 diff --git a/modules/canvaskit/canvaskit/extra.html b/modules/canvaskit/canvaskit/extra.html index b0d9c08c3c60c..6f393e28a0446 100644 --- a/modules/canvaskit/canvaskit/extra.html +++ b/modules/canvaskit/canvaskit/extra.html @@ -18,12 +18,10 @@

Skottie

-

RT Shader

- +

Particles

@@ -48,7 +46,6 @@

3D perspective transformations

var confettiJSON = null; var onboardingJSON = null; var multiFrameJSON = null; - var webfontJSON = null; var fullBounds = {fLeft: 0, fTop: 0, fRight: 500, fBottom: 500}; var robotoData = null; @@ -57,9 +54,10 @@

3D perspective transformations

var bonesImageData = null; var flightAnimGif = null; var skpData = null; - CanvasKitInit({ + const ckLoaded = CanvasKitInit({ locateFile: (file) => '/node_modules/canvaskit/bin/'+file, - }).ready().then((CK) => { + }).ready(); + ckLoaded.then((CK) => { CanvasKit = CK; // Set bounds to fix the 4:3 resolution of the legos SkottieExample(CanvasKit, 'sk_legos', legoJSON, @@ -71,10 +69,6 @@

3D perspective transformations

SkottieExample(CanvasKit, 'sk_animated_gif', multiFrameJSON, fullBounds, { 'image_0.png': flightAnimGif, }); - SkottieExample(CanvasKit, 'sk_webfont', webfontJSON, fullBounds, { - 'Roboto-Regular': robotoData, - }); - ParticlesAPI1(CanvasKit); ParagraphAPI1(CanvasKit, robotoData); @@ -132,12 +126,9 @@

3D perspective transformations

}); }); - fetch('./Roboto-Regular.woff').then((resp) => { + fetch('./Roboto-Regular.ttf').then((resp) => { resp.arrayBuffer().then((buffer) => { robotoData = buffer; - SkottieExample(CanvasKit, 'sk_webfont', webfontJSON, fullBounds, { - 'Roboto-Regular': robotoData, - }); ParagraphAPI1(CanvasKit, robotoData); }); }); @@ -147,6 +138,9 @@

3D perspective transformations

SkpExample(CanvasKit, skpData); }); + const loadDog = fetch('https://storage.googleapis.com/skia-cdn/misc/dog.jpg').then((response) => response.arrayBuffer()); + const loadMandrill = fetch('https://storage.googleapis.com/skia-cdn/misc/mandrill_256.png').then((response) => response.arrayBuffer()); + function SkottieExample(CanvasKit, id, jsonStr, bounds, assets) { if (!CanvasKit || !jsonStr) { return; @@ -370,19 +364,28 @@

3D perspective transformations

return surface; } + const spiralSkSL = ` + uniform float rad_scale; + uniform float2 in_center; + uniform float4 in_colors0; + uniform float4 in_colors1; + + void main(float2 p, inout half4 color) { + float2 pp = p - in_center; + float radius = sqrt(dot(pp, pp)); + radius = sqrt(radius); + float angle = atan(pp.y / pp.x); + float t = (angle + 3.1415926/2) / (3.1415926); + t += radius * rad_scale; + t = fract(t); + color = half4(mix(in_colors0, in_colors1, t)); + }`; + function RTShaderAPI1(CanvasKit) { - return; // TODO(kjlubick): Fix this example. if (!CanvasKit) { return; } - const prog = ` - uniform half4 gColor; - - void main(float2 p, inout half4 color) { - color = half4(half2(p)*(1.0/255), gColor.b, 1); - } -`; const surface = CanvasKit.MakeCanvasSurface('rtshader'); if (!surface) { console.error('Could not make surface'); @@ -391,13 +394,15 @@

3D perspective transformations

const canvas = surface.getCanvas(); - const effect = CanvasKit._SkRuntimeEffect.Make(prog); - const rot = CanvasKit.SkMatrix.rotated(90, 128, 128); - const shader = effect.makeShader([1, 0, 0, 1], true, rot); - + const effect = CanvasKit.SkRuntimeEffect.Make(spiralSkSL); + const shader = effect.makeShader([ + 0.5, + 150, 150, + 0, 1, 0, 1, + 1, 0, 0, 1], true); const paint = new CanvasKit.SkPaint(); paint.setShader(shader); - canvas.drawRect(CanvasKit.LTRBRect(0, 0, 256, 256), paint); + canvas.drawRect(CanvasKit.LTRBRect(0, 0, 300, 300), paint); surface.flush(); shader.delete(); @@ -405,6 +410,119 @@

3D perspective transformations

effect.delete(); } + // RTShader2 demo + Promise.all([ckLoaded, loadDog, loadMandrill]).then((values) => { + const [CanvasKit, dogData, mandrillData] = values; + const dogImg = CanvasKit.MakeImageFromEncoded(dogData); + if (!dogImg) { + console.error('could not decode dog'); + return; + } + const mandrillImg = CanvasKit.MakeImageFromEncoded(mandrillData); + if (!mandrillImg) { + console.error('could not decode mandrill'); + return; + } + const quadrantSize = 150; + + const dogShader = dogImg.makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp, + CanvasKit.SkMatrix.scaled(quadrantSize/dogImg.width(), + quadrantSize/dogImg.height())); + const mandrillShader = mandrillImg.makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp, + CanvasKit.SkMatrix.scaled( + quadrantSize/mandrillImg.width(), + quadrantSize/mandrillImg.height())); + + const surface = CanvasKit.MakeCanvasSurface('rtshader2'); + if (!surface) { + console.error('Could not make surface'); + return; + } + + const prog = ` + in fragmentProcessor before_map; + in fragmentProcessor after_map; + in fragmentProcessor threshold_map; + + uniform float cutoff; + uniform float slope; + + float smooth_cutoff(float x) { + x = x * slope + (0.5 - slope * cutoff); + return clamp(x, 0, 1); + } + + void main(float2 xy, inout half4 color) { + half4 before = sample(before_map, xy); + half4 after = sample(after_map, xy); + + float m = smooth_cutoff(sample(threshold_map, xy).r); + color = mix(before, after, half(m)); + }`; + + const canvas = surface.getCanvas(); + + const thresholdEffect = CanvasKit.SkRuntimeEffect.Make(prog); + const spiralEffect = CanvasKit.SkRuntimeEffect.Make(spiralSkSL); + + const draw = (x, y, shader) => { + const paint = new CanvasKit.SkPaint(); + paint.setShader(shader); + canvas.save(); + canvas.translate(x, y); + canvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint); + canvas.restore(); + paint.delete(); + }; + + const offscreenSurface = CanvasKit.MakeSurface(quadrantSize, quadrantSize); + const getBlurrySpiralShader = (rad_scale) => { + const oCanvas = offscreenSurface.getCanvas(); + + const spiralShader = spiralEffect.makeShader([ + rad_scale, + quadrantSize/2, quadrantSize/2, + 1, 1, 1, 1, + 0, 0, 0, 1], true); + + return spiralShader; + // TODO(kjlubick): The raster backend does not like atan or fract, so we can't + // draw the shader into the offscreen canvas and mess with it. When we can, that + // would be cool to show off. + + const blur = CanvasKit.SkImageFilter.MakeBlur(0.1, 0.1, CanvasKit.TileMode.Clamp, null); + + const paint = new CanvasKit.SkPaint(); + paint.setShader(spiralShader); + paint.setImageFilter(blur); + oCanvas.drawRect(CanvasKit.LTRBRect(0, 0, quadrantSize, quadrantSize), paint); + + paint.delete(); + blur.delete(); + spiralShader.delete(); + return offscreenSurface.makeImageSnapshot() + .makeShader(CanvasKit.TileMode.Clamp, CanvasKit.TileMode.Clamp); + + }; + + const drawFrame = () => { + surface.requestAnimationFrame(drawFrame); + const thresholdShader = getBlurrySpiralShader(Math.sin(Date.now() / 5000) / 2); + + const blendShader = thresholdEffect.makeShaderWithChildren( + [0.5, 10], + true, [dogShader, mandrillShader, thresholdShader]); + draw(0, 0, blendShader); + draw(quadrantSize, 0, thresholdShader); + draw(0, quadrantSize, dogShader); + draw(quadrantSize, quadrantSize, mandrillShader); + + blendShader.delete(); + }; + + surface.requestAnimationFrame(drawFrame); + }); + function SkpExample(CanvasKit, skpData) { if (!skpData || !CanvasKit) { return; diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp index 96523a0f86da3..cb2cbdc44751f 100644 --- a/modules/canvaskit/canvaskit_bindings.cpp +++ b/modules/canvaskit/canvaskit_bindings.cpp @@ -1447,21 +1447,57 @@ EMSCRIPTEN_BINDINGS(Skia) { auto [effect, errorText] = SkRuntimeEffect::Make(s); if (!effect) { SkDebugf("Runtime effect failed to compile:\n%s\n", errorText.c_str()); + return nullptr; } return effect; })) - .function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fptr, size_t len, bool isOpaque)->sk_sp { + .function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque)->sk_sp { // See comment above for uintptr_t explanation - void* inputData = reinterpret_cast(fptr); - sk_sp inputs = SkData::MakeFromMalloc(inputData, len); + void* inputData = reinterpret_cast(fPtr); + sk_sp inputs = SkData::MakeFromMalloc(inputData, fLen); return self.makeShader(inputs, nullptr, 0, nullptr, isOpaque); })) - .function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fptr, size_t len, bool isOpaque, SimpleMatrix sm)->sk_sp { + .function("_makeShader", optional_override([](SkRuntimeEffect& self, uintptr_t fPtr, size_t fLen, bool isOpaque, SimpleMatrix sm)->sk_sp { // See comment above for uintptr_t explanation - void* inputData = reinterpret_cast(fptr); - sk_sp inputs = SkData::MakeFromMalloc(inputData, len); + void* inputData = reinterpret_cast(fPtr); + sk_sp 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, + uintptr_t /** SkShader*[] */cPtrs, size_t cLen)->sk_sp { + // See comment above for uintptr_t explanation + void* inputData = reinterpret_cast(fPtr); + sk_sp inputs = SkData::MakeFromMalloc(inputData, fLen); + + sk_sp* children = new sk_sp[cLen]; + SkShader** childrenPtrs = reinterpret_cast(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(childrenPtrs[i]); + } + auto s = self.makeShader(inputs, children, cLen, nullptr, isOpaque); + delete[] children; + 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 { + // See comment above for uintptr_t explanation + void* inputData = reinterpret_cast(fPtr); + sk_sp inputs = SkData::MakeFromMalloc(inputData, fLen); + + sk_sp* children = new sk_sp[cLen]; + SkShader** childrenPtrs = reinterpret_cast(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(childrenPtrs[i]); + } + auto m = toSkMatrix(sm); + auto s = self.makeShader(inputs, children, cLen, &m, isOpaque); + delete[] children; + return s; })); #endif diff --git a/modules/canvaskit/externs.js b/modules/canvaskit/externs.js index 5c9bdd2e6826d..62245d02b510f 100644 --- a/modules/canvaskit/externs.js +++ b/modules/canvaskit/externs.js @@ -133,6 +133,7 @@ var CanvasKit = { // private API _makeShader: function() {}, + _makeShaderWithChildren: function() {}, }, ParagraphStyle: function() {}, @@ -855,6 +856,7 @@ CanvasKit.SkColorBuilder.prototype.push = function() {}; CanvasKit.SkColorBuilder.prototype.set = function() {}; CanvasKit.SkRuntimeEffect.prototype.makeShader = function() {}; +CanvasKit.SkRuntimeEffect.prototype.makeShaderWithChildren = function() {}; CanvasKit.SkParticleEffect.prototype.effectUniforms = function() {}; CanvasKit.SkParticleEffect.prototype.particleUniforms = function() {}; diff --git a/modules/canvaskit/rt_shader.js b/modules/canvaskit/rt_shader.js index ab30728b93f41..83ef479a48e5e 100644 --- a/modules/canvaskit/rt_shader.js +++ b/modules/canvaskit/rt_shader.js @@ -9,4 +9,22 @@ CanvasKit._extraInitializations.push(function() { } return this._makeShader(fptr, floats.length * 4, !!isOpaque, matrix); } + + // childrenWithShaders is an array of other shaders (e.g. SkImage.makeShader()) + CanvasKit.SkRuntimeEffect.prototype.makeShaderWithChildren = function(floats, isOpaque, childrenShaders, matrix) { + var fptr = copy1dArray(floats, CanvasKit.HEAPF32); + var barePointers = []; + for (var i = 0; i