Add CanvasKit bindings for RuntimeShader.MakeTraced.
To save space, debug trace bindings can be disabled by turning off SK_INCLUDE_SKSL_TRACE. Most clients shouldn't need them. Change-Id: Ifadc05b3eeed95def334fa7e0755f61caeef27f0 Bug: skia:12818 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/494244 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Kevin Lubick <kjlubick@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
a379b7d4a3
commit
575d0c5e1d
@ -71,7 +71,7 @@ npm:
|
||||
|
||||
# These features are turned off to keep code size smaller for the
|
||||
# general use case.
|
||||
./compile.sh release no_skottie no_particles no_rt_shader no_alias_font no_effects_deserialization
|
||||
./compile.sh release no_skottie no_particles no_rt_shader no_sksl_trace no_alias_font no_effects_deserialization
|
||||
cp ../../out/canvaskit_wasm/canvaskit.js ./npm_build/bin
|
||||
cp ../../out/canvaskit_wasm/canvaskit.wasm ./npm_build/bin
|
||||
|
||||
@ -155,4 +155,4 @@ bazel_canvaskit_release:
|
||||
mkdir build
|
||||
cp ../../bazel-bin/modules/canvaskit/canvaskit_wasm/canvaskit.js build/canvaskit.js
|
||||
cp ../../bazel-bin/modules/canvaskit/canvaskit_wasm/canvaskit.wasm build/canvaskit.wasm
|
||||
ls -l build
|
||||
ls -l build
|
||||
|
@ -85,6 +85,10 @@
|
||||
#include "include/pathops/SkPathOps.h"
|
||||
#endif
|
||||
|
||||
#if defined(SK_INCLUDE_RUNTIME_EFFECT) && defined(SK_INCLUDE_SKSL_TRACE)
|
||||
#include "include/sksl/SkSLDebugTrace.h"
|
||||
#endif
|
||||
|
||||
#ifndef SK_NO_FONTS
|
||||
sk_sp<SkFontMgr> SkFontMgr_New_Custom_Data(sk_sp<SkData>* datas, int n);
|
||||
#endif
|
||||
@ -1772,6 +1776,21 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
}), allow_raw_pointers());
|
||||
|
||||
#ifdef SK_INCLUDE_RUNTIME_EFFECT
|
||||
#ifdef SK_INCLUDE_SKSL_TRACE
|
||||
class_<SkSL::DebugTrace>("DebugTrace")
|
||||
.smart_ptr<sk_sp<SkSL::DebugTrace>>("sk_sp<DebugTrace>")
|
||||
.function("writeTrace", optional_override([](SkSL::DebugTrace& self) -> std::string {
|
||||
SkDynamicMemoryWStream wstream;
|
||||
self.writeTrace(&wstream);
|
||||
sk_sp<SkData> trace = wstream.detachAsData();
|
||||
return std::string(reinterpret_cast<const char*>(trace->bytes()), trace->size());
|
||||
}));
|
||||
|
||||
value_object<SkRuntimeEffect::TracedShader>("TracedShader")
|
||||
.field("shader", &SkRuntimeEffect::TracedShader::shader)
|
||||
.field("debugTrace", &SkRuntimeEffect::TracedShader::debugTrace);
|
||||
#endif
|
||||
|
||||
class_<SkRuntimeEffect>("RuntimeEffect")
|
||||
.smart_ptr<sk_sp<SkRuntimeEffect>>("sk_sp<RuntimeEffect>")
|
||||
.class_function("_Make", optional_override([](std::string sksl,
|
||||
@ -1785,6 +1804,14 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
}
|
||||
return effect;
|
||||
}))
|
||||
#ifdef SK_INCLUDE_SKSL_TRACE
|
||||
.class_function("MakeTraced", optional_override([](
|
||||
sk_sp<SkShader> shader,
|
||||
int traceCoordX,
|
||||
int traceCoordY) -> SkRuntimeEffect::TracedShader {
|
||||
return SkRuntimeEffect::MakeTraced(shader, SkIPoint::Make(traceCoordX, traceCoordY));
|
||||
}))
|
||||
#endif
|
||||
.function("_makeShader", optional_override([](SkRuntimeEffect& self, WASMPointerF32 fPtr, size_t fLen, bool isOpaque,
|
||||
WASMPointerF32 mPtr)->sk_sp<SkShader> {
|
||||
void* inputData = reinterpret_cast<void*>(fPtr);
|
||||
|
@ -153,6 +153,11 @@ if [[ $@ == *no_rt_shader* ]] ; then
|
||||
RT_SHADER_JS=""
|
||||
fi
|
||||
|
||||
WASM_SKSL_TRACE="-DSK_INCLUDE_SKSL_TRACE"
|
||||
if [[ $@ == *no_sksl_trace* ]] ; then
|
||||
WASM_SKSL_TRACE=""
|
||||
fi
|
||||
|
||||
MATRIX_HELPER_JS="--pre-js $BASE_DIR/matrix.js"
|
||||
if [[ $@ == *no_matrix* ]]; then
|
||||
echo "Omitting matrix helper code"
|
||||
@ -363,6 +368,7 @@ EMCC_DEBUG=1 ${EMCXX} \
|
||||
$WASM_GPU \
|
||||
$WASM_PATHOPS \
|
||||
$WASM_RT_SHADER \
|
||||
$WASM_SKSL_TRACE \
|
||||
$WASM_SKP \
|
||||
$FONT_CFLAGS \
|
||||
-std=c++17 \
|
||||
|
19
modules/canvaskit/npm_build/types/index.d.ts
vendored
19
modules/canvaskit/npm_build/types/index.d.ts
vendored
@ -407,7 +407,7 @@ export interface CanvasKit {
|
||||
readonly PictureRecorder: DefaultConstructor<PictureRecorder>;
|
||||
readonly TextStyle: TextStyleConstructor;
|
||||
|
||||
// Factories, i.e. things made with CanvasKit.Foo.MakeTurboEncapsulator()
|
||||
// Factories, i.e. things made with CanvasKit.Foo.MakeTurboEncabulator()
|
||||
readonly ParagraphBuilder: ParagraphBuilderFactory;
|
||||
readonly ColorFilter: ColorFilterFactory;
|
||||
readonly FontMgr: FontMgrFactory;
|
||||
@ -3332,6 +3332,15 @@ export interface PathEffectFactory {
|
||||
/**
|
||||
* See RuntimeEffect.h for more details.
|
||||
*/
|
||||
export interface DebugTrace extends EmbindObject<DebugTrace> {
|
||||
writeTrace(): string;
|
||||
}
|
||||
|
||||
export interface TracedShader {
|
||||
shader: RuntimeEffect;
|
||||
debugTrace: DebugTrace;
|
||||
}
|
||||
|
||||
export interface RuntimeEffectFactory {
|
||||
/**
|
||||
* Compiles a RuntimeEffect from the given shader code.
|
||||
@ -3340,6 +3349,14 @@ export interface RuntimeEffectFactory {
|
||||
* be printed to console.log().
|
||||
*/
|
||||
Make(sksl: string, callback?: (err: string) => void): RuntimeEffect | null;
|
||||
|
||||
/**
|
||||
* Adds debug tracing to an existing RuntimeEffect.
|
||||
* @param shader - An already-assembled shader, created with RuntimeEffect.makeShader.
|
||||
* @param traceCoordX - the X coordinate of the device-space pixel to trace
|
||||
* @param traceCoordY - the Y coordinate of the device-space pixel to trace
|
||||
*/
|
||||
MakeTraced(shader: RuntimeEffect, traceCoordX: number, traceCoordY: number): TracedShader;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,8 +14,6 @@ describe('Runtime shader effects', () => {
|
||||
document.body.removeChild(container);
|
||||
});
|
||||
|
||||
// On the SW backend, atan is not supported - a shader is returned, but
|
||||
// it will draw blank.
|
||||
const spiralSkSL = `
|
||||
uniform float rad_scale;
|
||||
uniform int2 in_center;
|
||||
@ -96,6 +94,64 @@ half4 main(float2 p) {
|
||||
expect(error).toContain('error');
|
||||
});
|
||||
|
||||
it('can generate a debug trace', () => {
|
||||
// We don't support debug tracing on GPU, so we always request a software canvas here.
|
||||
const surface = CanvasKit.MakeSWCanvasSurface('test');
|
||||
expect(surface).toBeTruthy('Could not make surface');
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
const spiral = CanvasKit.RuntimeEffect.Make(spiralSkSL);
|
||||
expect(spiral).toBeTruthy('could not compile program');
|
||||
|
||||
const canvas = surface.getCanvas();
|
||||
const paint = new CanvasKit.Paint();
|
||||
const shader = spiral.makeShader([
|
||||
0.3,
|
||||
CANVAS_WIDTH/2, CANVAS_HEIGHT/2,
|
||||
1, 0, 0, 1, // solid red
|
||||
0, 1, 0, 1], // solid green
|
||||
true /*=opaque*/);
|
||||
|
||||
const traced = CanvasKit.RuntimeEffect.MakeTraced(shader, CANVAS_WIDTH/2, CANVAS_HEIGHT/2);
|
||||
paint.setShader(traced.shader);
|
||||
canvas.drawRect(CanvasKit.LTRBRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), paint);
|
||||
|
||||
const traceData = traced.debugTrace.writeTrace();
|
||||
paint.delete();
|
||||
shader.delete();
|
||||
spiral.delete();
|
||||
traced.shader.delete();
|
||||
traced.debugTrace.delete();
|
||||
surface.delete();
|
||||
|
||||
const parsedTrace = JSON.parse(traceData);
|
||||
expect(parsedTrace).toBeTruthy('could not parse trace JSON');
|
||||
expect(parsedTrace.functions).toBeTruthy('debug trace does not include function list');
|
||||
expect(parsedTrace.slots).toBeTruthy('debug trace does not include slot list');
|
||||
expect(parsedTrace.trace).toBeTruthy('debug trace does not include trace data');
|
||||
expect(parsedTrace.nonsense).toBeFalsy('debug trace includes a nonsense key');
|
||||
expect(parsedTrace.mystery).toBeFalsy('debug trace includes a mystery key');
|
||||
expect(parsedTrace.source).toEqual([
|
||||
"",
|
||||
"uniform float rad_scale;",
|
||||
"uniform int2 in_center;",
|
||||
"uniform float4 in_colors0;",
|
||||
"uniform float4 in_colors1;",
|
||||
"",
|
||||
"half4 main(float2 p) {",
|
||||
" float2 pp = p - float2(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);",
|
||||
" return half4(mix(in_colors0, in_colors1, t));",
|
||||
"}"
|
||||
]);
|
||||
});
|
||||
|
||||
const loadBrick = fetch(
|
||||
'/assets/brickwork-texture.jpg')
|
||||
.then((response) => response.arrayBuffer());
|
||||
@ -143,12 +199,12 @@ half4 main(float2 xy) {
|
||||
CanvasKit.TileMode.Decal, CanvasKit.TileMode.Decal,
|
||||
1/3 /*B*/, 1/3 /*C*/,
|
||||
CanvasKit.Matrix.scaled(CANVAS_WIDTH/brickImg.width(),
|
||||
CANVAS_HEIGHT/brickImg.height()));
|
||||
CANVAS_HEIGHT/brickImg.height()));
|
||||
const mandrillShader = mandrillImg.makeShaderCubic(
|
||||
CanvasKit.TileMode.Decal, CanvasKit.TileMode.Decal,
|
||||
1/3 /*B*/, 1/3 /*C*/,
|
||||
CanvasKit.Matrix.scaled(CANVAS_WIDTH/mandrillImg.width(),
|
||||
CANVAS_HEIGHT/mandrillImg.height()));
|
||||
CANVAS_HEIGHT/mandrillImg.height()));
|
||||
const spiralShader = spiralEffect.makeShader([
|
||||
0.8,
|
||||
CANVAS_WIDTH/2, CANVAS_HEIGHT/2,
|
||||
|
Loading…
Reference in New Issue
Block a user