Convert internal SkSL to use .eval()

Also update RELEASE_NOTES to describe new syntax.

Change-Id: I2666551b98f80b61ae3a48c92a9e306cdc7242b0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/444735
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index edb3552..382cdbd 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -19,10 +19,18 @@
 
   * There is a new syntax for invoking (sampling) child effects in SkSL. Previously, children
     (shaders, colorFilters, blenders) were invoked using different overloads of `sample`. That
-    syntax is deprecated (but still supported). Now, the name of the intrinsic used is dependent on
-    the type of the child: 'shade' for shaders, 'filter' for colorFilters, and 'blend' for blenders.
-    The arguments to these invocations are the same as the arguments in the old overloads of sample.
-    https://review.skia.org/441457
+    syntax is deprecated (but still supported). Now, the child behaves like an object, with a method
+    name `eval`. The arguments to these `eval` methods are the same as the arguments in the old
+    `sample` intrinsics. For example:
+      // Old syntax:
+        sample(shader, xy)
+        sample(colorFilter, color)
+        sample(blender, srcColor, dstColor)
+      // New syntax:
+        shader.eval(xy)
+        colorFilter.eval(color)
+        blender.eval(srcColor, dstColor)
+    https://review.skia.org/444735
 
 * * *
 
diff --git a/demos.skia.org/demos/image_sampling/index.html b/demos.skia.org/demos/image_sampling/index.html
index 80b7979..919bb34 100644
--- a/demos.skia.org/demos/image_sampling/index.html
+++ b/demos.skia.org/demos/image_sampling/index.html
@@ -66,10 +66,10 @@
     }
 
     half4 main(float2 p) {
-        half4 pa = shade(image, float2(p.x-0.5, p.y-0.5));
-        half4 pb = shade(image, float2(p.x+0.5, p.y-0.5));
-        half4 pc = shade(image, float2(p.x-0.5, p.y+0.5));
-        half4 pd = shade(image, float2(p.x+0.5, p.y+0.5));
+        half4 pa = image.eval(float2(p.x-0.5, p.y-0.5));
+        half4 pb = image.eval(float2(p.x+0.5, p.y-0.5));
+        half4 pc = image.eval(float2(p.x-0.5, p.y+0.5));
+        half4 pd = image.eval(float2(p.x+0.5, p.y+0.5));
         float2 w = sharpen(fract(p + 0.5));
         if (do_smooth > 0) {
             w = smooth(w);
diff --git a/demos.skia.org/demos/up_scaling/index.html b/demos.skia.org/demos/up_scaling/index.html
index 3a4019f..dd1bbf7 100644
--- a/demos.skia.org/demos/up_scaling/index.html
+++ b/demos.skia.org/demos/up_scaling/index.html
@@ -64,10 +64,10 @@
       float h = nearly_center(p) ? 0.0 : 0.5;
 
       // Manual bilerp logic
-      half4 pa = shade(image, float2(p.x-h, p.y-h));
-      half4 pb = shade(image, float2(p.x+h, p.y-h));
-      half4 pc = shade(image, float2(p.x-h, p.y+h));
-      half4 pd = shade(image, float2(p.x+h, p.y+h));
+      half4 pa = image.eval(float2(p.x-h, p.y-h));
+      half4 pb = image.eval(float2(p.x+h, p.y-h));
+      half4 pc = image.eval(float2(p.x-h, p.y+h));
+      half4 pd = image.eval(float2(p.x+h, p.y+h));
 
       // Now 'sharpen' the weighting. This is the magic sauce where we different
       // from a normal bilerp
diff --git a/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp b/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp
index e321338..137e5f1 100644
--- a/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp
+++ b/fuzz/oss_fuzz/FuzzSKSL2Pipeline.cpp
@@ -38,15 +38,15 @@
         void declareGlobal(const char* /*declaration*/) override {}
 
         String sampleShader(int index, String coords) override {
-            return "shade(" + SkSL::to_string(index) + ", " + coords + ")";
+            return "child_" + SkSL::to_string(index) + ".eval(" + coords + ")";
         }
 
         String sampleColorFilter(int index, String color) override {
-            return "filter(" + SkSL::to_string(index) + ", " + color + ")";
+            return "child_" + SkSL::to_string(index) + ".eval(" + color + ")";
         }
 
         String sampleBlender(int index, String src, String dst) override {
-            return "blend(" + SkSL::to_string(index) + ", " + src + ", " + dst + ")";
+            return "child_" + SkSL::to_string(index) + ".eval(" + src + ", " + dst + ")";
         }
     };
 
diff --git a/gm/composecolorfilter.cpp b/gm/composecolorfilter.cpp
index 9c2847b..b1e41de 100644
--- a/gm/composecolorfilter.cpp
+++ b/gm/composecolorfilter.cpp
@@ -66,7 +66,7 @@
         auto [effect, error] = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
             uniform colorFilter inner;
             uniform colorFilter outer;
-            half4 main(half4 c) { return filter(outer, filter(inner, c)); }
+            half4 main(half4 c) { return outer.eval(inner.eval(c)); }
         )"));
         SkASSERT(effect);
         SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
diff --git a/gm/runtimeeffectimage.cpp b/gm/runtimeeffectimage.cpp
index f3ba590..15009d7 100644
--- a/gm/runtimeeffectimage.cpp
+++ b/gm/runtimeeffectimage.cpp
@@ -35,7 +35,7 @@
                 half b = fract((p.x + 5)/10);
                 half a = min(distance(p, vec2(50, 50))/50 + 0.3, 1);
                 half4 result = half4(r, g, b, a);
-                result *= shade(child, p);
+                result *= child.eval(p);
                 if (gAlphaType == 0) {
                    result.rgb *= a;
                 }
diff --git a/gm/runtimeimagefilter.cpp b/gm/runtimeimagefilter.cpp
index 2fcc371..50b5c20 100644
--- a/gm/runtimeimagefilter.cpp
+++ b/gm/runtimeimagefilter.cpp
@@ -27,7 +27,7 @@
         uniform shader input;
         half4 main(float2 coord) {
             coord.x += sin(coord.y / 3) * 4;
-            return shade(input, coord);
+            return input.eval(coord);
         }
     )")).effect;
     return SkMakeRuntimeImageFilter(std::move(effect),
diff --git a/gm/runtimeshader.cpp b/gm/runtimeshader.cpp
index 8c25aa8..507c37c 100644
--- a/gm/runtimeshader.cpp
+++ b/gm/runtimeshader.cpp
@@ -137,10 +137,10 @@
         }
 
         half4 main(float2 xy) {
-            half4 before = shade(before_map, xy);
-            half4 after = shade(after_map, xy);
+            half4 before = before_map.eval(xy);
+            half4 after = after_map.eval(xy);
 
-            float m = smooth_cutoff(shade(threshold_map, xy).a);
+            float m = smooth_cutoff(threshold_map.eval(xy).a);
             return mix(before, after, m);
         }
     )", kAnimate_RTFlag | kBench_RTFlag) {}
@@ -228,11 +228,11 @@
     UnsharpRT() : RuntimeShaderGM("unsharp_rt", {512, 256}, R"(
         uniform shader input;
         half4 main(float2 xy) {
-            half4 c = shade(input, xy) * 5;
-            c -= shade(input, xy + float2( 1,  0));
-            c -= shade(input, xy + float2(-1,  0));
-            c -= shade(input, xy + float2( 0,  1));
-            c -= shade(input, xy + float2( 0, -1));
+            half4 c = input.eval(xy) * 5;
+            c -= input.eval(xy + float2( 1,  0));
+            c -= input.eval(xy + float2(-1,  0));
+            c -= input.eval(xy + float2( 0,  1));
+            c -= input.eval(xy + float2( 0, -1));
             return c;
         }
     )") {}
@@ -273,7 +273,7 @@
         uniform float inv_size;
 
         half4 main(float2 xy) {
-            float4 c = unpremul(shade(input, xy));
+            float4 c = unpremul(input.eval(xy));
 
             // Map to cube coords:
             float3 cubeCoords = float3(c.rg * rg_scale + rg_bias, c.b * b_scale);
@@ -283,7 +283,7 @@
             float2 coords2 = float2(( ceil(cubeCoords.b) + cubeCoords.r) * inv_size, cubeCoords.g);
 
             // Two bilinear fetches, plus a manual lerp for the third axis:
-            half4 color = mix(shade(color_cube, coords1), shade(color_cube, coords2),
+            half4 color = mix(color_cube.eval(coords1), color_cube.eval(coords2),
                               fract(cubeCoords.b));
 
             // Premul again
@@ -366,7 +366,7 @@
             float2 coords2 = float2(( ceil(cubeCoords.b) + cubeCoords.r) * inv_size, cubeCoords.g);
 
             // Two bilinear fetches, plus a manual lerp for the third axis:
-            half4 color = mix(shade(color_cube, coords1), shade(color_cube, coords2),
+            half4 color = mix(color_cube.eval(coords1), color_cube.eval(coords2),
                               fract(cubeCoords.b));
 
             // Premul again
@@ -429,7 +429,7 @@
     DefaultColorRT() : RuntimeShaderGM("default_color_rt", {512, 256}, R"(
         uniform shader input;
         half4 main(float2 xy) {
-            return shade(input, xy);
+            return input.eval(xy);
         }
     )") {}
 
@@ -624,7 +624,7 @@
     static constexpr char scale[] =
         "uniform shader child;"
         "half4 main(float2 xy) {"
-        "    return shade(child, xy*0.1);"
+        "    return child.eval(xy*0.1);"
         "}";
 
     SkPaint p;
diff --git a/modules/canvaskit/npm_build/extra.html b/modules/canvaskit/npm_build/extra.html
index 8c9c1cc..0299739 100644
--- a/modules/canvaskit/npm_build/extra.html
+++ b/modules/canvaskit/npm_build/extra.html
@@ -462,10 +462,10 @@
       }
 
       half4 main(float2 xy) {
-          half4 before = shade(before_map, xy);
-          half4 after = shade(after_map, xy);
+          half4 before = before_map.eval(xy);
+          half4 after = after_map.eval(xy);
 
-          float m = smooth_cutoff(shade(threshold_map, xy).r);
+          float m = smooth_cutoff(threshold_map.eval(xy).r);
           return mix(before, after, half(m));
       }`;
 
diff --git a/modules/canvaskit/tests/rtshader.spec.js b/modules/canvaskit/tests/rtshader.spec.js
index 5bcf7d2..f54acf8 100644
--- a/modules/canvaskit/tests/rtshader.spec.js
+++ b/modules/canvaskit/tests/rtshader.spec.js
@@ -117,10 +117,10 @@
 }
 
 half4 main(float2 xy) {
-    half4 before = shade(before_map, xy);
-    half4 after = shade(after_map, xy);
+    half4 before = before_map.eval(xy);
+    half4 after = after_map.eval(xy);
 
-    float m = smooth_cutoff(shade(threshold_map, xy).r);
+    float m = smooth_cutoff(threshold_map.eval(xy).r);
     return mix(before, after, half(m));
 }`;
 
diff --git a/modules/skottie/src/effects/DisplacementMapEffect.cpp b/modules/skottie/src/effects/DisplacementMapEffect.cpp
index d8d1b5f..198a715 100644
--- a/modules/skottie/src/effects/DisplacementMapEffect.cpp
+++ b/modules/skottie/src/effects/DisplacementMapEffect.cpp
@@ -48,11 +48,11 @@
     uniform half4   selector_offset;
 
     half4 main(float2 xy) {
-        half4 d = shade(displ, xy);
+        half4 d = displ.eval(xy);
 
         d = selector_matrix*unpremul(d) + selector_offset;
 
-        return shade(child, xy + d.xy*d.zw);
+        return child.eval(xy + d.xy*d.zw);
     }
 )";
 
diff --git a/modules/skottie/src/effects/SphereEffect.cpp b/modules/skottie/src/effects/SphereEffect.cpp
index ae53203..2490b04 100644
--- a/modules/skottie/src/effects/SphereEffect.cpp
+++ b/modules/skottie/src/effects/SphereEffect.cpp
@@ -77,7 +77,7 @@
             0.5 + kRPI * asin(RN.y)
         );
 
-        return apply_light(EYE, N, shade(child, UV*child_scale));
+        return apply_light(EYE, N, child.eval(UV*child_scale));
     }
 )";
 
diff --git a/resources/sksl/runtime/SampleWithExplicitCoord.rts b/resources/sksl/runtime/SampleWithExplicitCoord.rts
index f9fe458..9e6ecb5 100644
--- a/resources/sksl/runtime/SampleWithExplicitCoord.rts
+++ b/resources/sksl/runtime/SampleWithExplicitCoord.rts
@@ -1,4 +1,4 @@
 uniform shader child;
 half4 main(float2 p) {
-    return shade(child, p.yx);
+    return child.eval(p.yx);
 }
diff --git a/resources/sksl/runtime_errors/IllegalShaderSampling.rts b/resources/sksl/runtime_errors/IllegalShaderSampling.rts
index 7e373b5..a448694 100644
--- a/resources/sksl/runtime_errors/IllegalShaderSampling.rts
+++ b/resources/sksl/runtime_errors/IllegalShaderSampling.rts
@@ -7,58 +7,79 @@
 uniform float2 xy;
 uniform half4  color;
 
-half4 shader_xy_color()  { return sample(s, xy, color); }
-half4 shader_color()     { return sample(s, color); }
-half4 shader_color_xy()  { return sample(s, color, xy); }
-half4 shader_empty()     { return sample(s); }
-half4 shader_matrix()    { return sample(s, float3x3(1)); }
+half4 sample_shader_xy_color() { return sample(s, xy, color); }
+half4 sample_shader_color()    { return sample(s, color); }
+half4 sample_shader_color_xy() { return sample(s, color, xy); }
+half4 sample_shader_empty()    { return sample(s); }
+half4 sample_shader_matrix()   { return sample(s, float3x3(1)); }
 
-half4 filter_empty()     { return sample(f); }
-half4 filter_xy()        { return sample(f, xy); }
-half4 filter_xy_color()  { return sample(f, xy, color); }
+half4 sample_colorFilter_empty()    { return sample(f); }
+half4 sample_colorFilter_xy()       { return sample(f, xy); }
+half4 sample_colorFilter_xy_color() { return sample(f, xy, color); }
 
-half4 blender_empty()    { return sample(b); }
-half4 blender_color()    { return sample(b, color); }
-half4 blender_xy()       { return sample(b, xy); }
-half4 blender_xy_color() { return sample(b, xy, color); }
+half4 sample_blender_empty()    { return sample(b); }
+half4 sample_blender_color()    { return sample(b, color); }
+half4 sample_blender_xy()       { return sample(b, xy); }
+half4 sample_blender_xy_color() { return sample(b, xy, color); }
 
 // Same as above, but using the type-specific functions (shade, filter, blend):
 
-half4 shader_xy_color()  { return shade(s, xy, color); }
-half4 shader_color()     { return shade(s, color); }
-half4 shader_color_xy()  { return shade(s, color, xy); }
-half4 shader_empty()     { return shade(s); }
-half4 shader_matrix()    { return shade(s, float3x3(1)); }
+half4 shade_shader_xy_color() { return shade(s, xy, color); }
+half4 shade_shader_color()    { return shade(s, color); }
+half4 shade_shader_color_xy() { return shade(s, color, xy); }
+half4 shade_shader_empty()    { return shade(s); }
+half4 shade_shader_matrix()   { return shade(s, float3x3(1)); }
 
-half4 filter_empty()     { return filter(f); }
-half4 filter_xy()        { return filter(f, xy); }
-half4 filter_xy_color()  { return filter(f, xy, color); }
+half4 filter_colorFilter_empty()    { return filter(f); }
+half4 filter_colorFilter_xy()       { return filter(f, xy); }
+half4 filter_colorFilter_xy_color() { return filter(f, xy, color); }
 
-half4 blender_empty()    { return blend(b); }
-half4 blender_color()    { return blend(b, color); }
-half4 blender_xy()       { return blend(b, xy); }
-half4 blender_xy_color() { return blend(b, xy, color); }
+half4 blend_blender_empty()    { return blend(b); }
+half4 blend_blender_color()    { return blend(b, color); }
+half4 blend_blender_xy()       { return blend(b, xy); }
+half4 blend_blender_xy_color() { return blend(b, xy, color); }
 
 // Try to invoke a child with the wrong type-specific function, with either
 // argument list (aligned to function, or child type):
 
-half4 blend_shader_b()   { return blend(s, color, color); }
-half4 blend_shader_s()   { return blend(s, xy); }
-half4 filter_shader_f()  { return filter(s, color); }
-half4 filter_shader_s()  { return filter(s, xy); }
+half4 blend_shader_b()  { return blend(s, color, color); }
+half4 blend_shader_s()  { return blend(s, xy); }
+half4 filter_shader_f() { return filter(s, color); }
+half4 filter_shader_s() { return filter(s, xy); }
 
-half4 blend_filter_b()   { return blend(f, color, color); }
-half4 blend_filter_f()   { return blend(f, color); }
-half4 shade_filter_s()   { return shade(f, xy); }
-half4 shade_filter_f()   { return shade(f, color); }
+half4 blend_colorFilter_b() { return blend(f, color, color); }
+half4 blend_colorFilter_f() { return blend(f, color); }
+half4 shade_colorFilter_s() { return shade(f, xy); }
+half4 shade_colorFilter_f() { return shade(f, color); }
 
 half4 filter_blender_f() { return filter(b, color); }
 half4 filter_blender_b() { return filter(b, color, color); }
 half4 shade_blender_s()  { return shade(b, xy); }
 half4 shade_blender_b()  { return shade(b, color, color); }
 
+// Using .eval()
+
+half4 eval_shader_xy_color() { return s.eval(xy, color); }
+half4 eval_shader_color()    { return s.eval(color); }
+half4 eval_shader_color_xy() { return s.eval(color, xy); }
+half4 eval_shader_empty()    { return s.eval(); }
+half4 eval_shader_matrix()   { return s.eval(float3x3(1)); }
+
+half4 eval_colorFilter_empty()    { return f.eval(); }
+half4 eval_colorFilter_xy()       { return f.eval(xy); }
+half4 eval_colorFilter_xy_color() { return f.eval(xy, color); }
+
+half4 eval_blender_empty()    { return b.eval(); }
+half4 eval_blender_color()    { return b.eval(color); }
+half4 eval_blender_xy()       { return b.eval(xy); }
+half4 eval_blender_xy_color() { return b.eval(xy, color); }
+
 // Correct usage (EXPECT NO ERRORS)
 
 half4 blend_blender() { return blend(b, color, color); }
-half4 filter_filter() { return filter(f, color); }
-half4 shade_shader()  { return shade(s, xy); }
+half4 filter_colorFilter() { return filter(f, color); }
+half4 shade_shader() { return shade(s, xy); }
+
+half4 eval_blender() { return b.eval(color, color); }
+half4 eval_colorFilter() { return f.eval(color); }
+half4 eval_shader() { return s.eval(xy); }
diff --git a/resources/sksl/runtime_errors/IllegalShaderUse.rts b/resources/sksl/runtime_errors/IllegalShaderUse.rts
index 797ee07..552e9e5 100644
--- a/resources/sksl/runtime_errors/IllegalShaderUse.rts
+++ b/resources/sksl/runtime_errors/IllegalShaderUse.rts
@@ -11,8 +11,8 @@
 in shader s4;
 
 // Various places that shaders should not be allowed:
-half4  local()             { shader s; return shade(s, xy); }
-half4  parameter(shader s) { return shade(s, xy); }
+half4  local()             { shader s; return s.eval(xy); }
+half4  parameter(shader s) { return s.eval(xy); }
 shader returned()          { return s1; }
-half4  constructed()       { return shade(shader(s1), xy); }
-half4  expression(bool b)  { return shade(b ? s1 : s2, xy); }
+half4  constructed()       { return shader(s1).eval(xy); }
+half4  expression(bool b)  { return (b ? s1 : s2).eval(xy); }
diff --git a/samplecode/Sample3D.cpp b/samplecode/Sample3D.cpp
index 2a752e5..4ddc15d 100644
--- a/samplecode/Sample3D.cpp
+++ b/samplecode/Sample3D.cpp
@@ -389,7 +389,7 @@
             }
 
             half4 main(float2 p) {
-                float3 norm = convert_normal_sample(shade(normal_map, p));
+                float3 norm = convert_normal_sample(normal_map.eval(p));
                 float3 plane_norm = normalize(localToWorldAdjInv * norm.xyz0).xyz;
 
                 float3 plane_pos = (localToWorld * p.xy01).xyz;
@@ -399,7 +399,7 @@
                 float dp = dot(plane_norm, light_dir);
                 float scale = min(ambient + max(dp, 0), 1);
 
-                return shade(color_map, p) * scale.xxx1;
+                return color_map.eval(p) * scale.xxx1;
             }
         )";
         auto [effect, error] = SkRuntimeEffect::MakeForShader(SkString(code));
diff --git a/site/docs/user/modules/canvaskit.md b/site/docs/user/modules/canvaskit.md
index 05b5258..a38f0bf 100644
--- a/site/docs/user/modules/canvaskit.md
+++ b/site/docs/user/modules/canvaskit.md
@@ -559,7 +559,7 @@
       }
 
       half4 main(float2 p) {
-        float3 norm = convert_normal_sample(shade(normal_map, p));
+        float3 norm = convert_normal_sample(normal_map.eval(p));
         float3 plane_norm = normalize(localToWorldAdjInv * float4(norm, 0)).xyz;
 
         float3 plane_pos = (localToWorld * float4(p, 0, 1)).xyz;
@@ -569,7 +569,7 @@
         float dp = dot(plane_norm, light_dir);
         float scale = min(ambient + max(dp, 0), 1);
 
-        return shade(color_map, p) * half4(float4(scale, scale, scale, 1));
+        return color_map.eval(p) * half4(float4(scale, scale, scale, 1));
       }
 `;
 
diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp
index 5bdbc38..f516697 100644
--- a/src/core/SkBlurMF.cpp
+++ b/src/core/SkBlurMF.cpp
@@ -850,7 +850,7 @@
             // to rearrange to avoid passing large values to length() that would overflow.
             half2 vec = half2((sk_FragCoord.xy - circleData.xy) * circleData.w);
             half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
-            return inColor * shade(blurProfile, half2(dist, 0.5)).a;
+            return inColor * blurProfile.eval(half2(dist, 0.5)).a;
         }
     )");
 
@@ -994,8 +994,8 @@
                 // computations align the left edge of the integral texture with the inset rect's
                 // edge extending outward 6 * sigma from the inset rect.
                 half2 xy = max(half2(rect.LT - pos), half2(pos - rect.RB));
-                xCoverage = shade(integral, half2(xy.x, 0.5)).a;
-                yCoverage = shade(integral, half2(xy.y, 0.5)).a;
+                xCoverage = integral.eval(half2(xy.x, 0.5)).a;
+                yCoverage = integral.eval(half2(xy.y, 0.5)).a;
             } else {
                 // We just consider just the x direction here. In practice we compute x and y
                 // separately and multiply them together.
@@ -1013,10 +1013,10 @@
                 // Also, our rect uniform was pre-inset by 3 sigma from the actual rect being
                 // blurred, also factored in.
                 half4 rect = half4(half2(rect.LT - pos), half2(pos - rect.RB));
-                xCoverage = 1 - shade(integral, half2(rect.L, 0.5)).a
-                              - shade(integral, half2(rect.R, 0.5)).a;
-                yCoverage = 1 - shade(integral, half2(rect.T, 0.5)).a
-                              - shade(integral, half2(rect.B, 0.5)).a;
+                xCoverage = 1 - integral.eval(half2(rect.L, 0.5)).a
+                              - integral.eval(half2(rect.R, 0.5)).a;
+                yCoverage = 1 - integral.eval(half2(rect.T, 0.5)).a
+                              - integral.eval(half2(rect.B, 0.5)).a;
             }
             return inColor * xCoverage * yCoverage;
         }
@@ -1426,7 +1426,7 @@
             half2 proxyDims = half2(2.0 * edgeSize);
             half2 texCoord = translatedFragPosHalf / proxyDims;
 
-            return inColor * shade(ninePatchFP, texCoord).a;
+            return inColor * ninePatchFP.eval(texCoord).a;
         }
     )");
 
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 3c6ac99..eb1c9c6 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -477,7 +477,7 @@
         "uniform colorFilter cf1;"
         "uniform half   weight;"
         "half4 main(half4 color) {"
-            "return mix(filter(cf0, color), filter(cf1, color), weight);"
+            "return mix(cf0.eval(color), cf1.eval(color), weight);"
         "}"
     );
     SkASSERT(effect);
diff --git a/src/core/SkRuntimeEffectPriv.h b/src/core/SkRuntimeEffectPriv.h
index 80337a3..cec8cae 100644
--- a/src/core/SkRuntimeEffectPriv.h
+++ b/src/core/SkRuntimeEffectPriv.h
@@ -119,10 +119,10 @@
 private:
     struct SampleCall {
         enum class Kind {
-            kInputColor,  // eg filter(child, inputColor)
-            kImmediate,   // eg filter(child, half4(1))
-            kPrevious,    // eg filter(child1, filter(child2, ...))
-            kUniform,     // eg uniform half4 color; ... filter(child, color)
+            kInputColor,  // eg child.eval(inputColor)
+            kImmediate,   // eg child.eval(half4(1))
+            kPrevious,    // eg child1.eval(child2.eval(...))
+            kUniform,     // eg uniform half4 color; ... child.eval(color)
         };
 
         int  fChild;
diff --git a/src/effects/imagefilters/SkAlphaThresholdImageFilter.cpp b/src/effects/imagefilters/SkAlphaThresholdImageFilter.cpp
index 5c82b02..a7c7aa4 100644
--- a/src/effects/imagefilters/SkAlphaThresholdImageFilter.cpp
+++ b/src/effects/imagefilters/SkAlphaThresholdImageFilter.cpp
@@ -145,7 +145,7 @@
         uniform half outerThreshold;
 
         half4 main(float2 xy, half4 color) {
-            half4 mask_color = shade(maskFP, xy);
+            half4 mask_color = maskFP.eval(xy);
             if (mask_color.a < 0.5) {
                 if (color.a > outerThreshold) {
                     half scale = outerThreshold / color.a;
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index 9572d7e..3dcebc4 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -315,8 +315,8 @@
         uniform half4 k;
         uniform half pmClamp;
         half4 main(float2 xy) {
-            half4 src = shade(srcFP, xy);
-            half4 dst = shade(dstFP, xy);
+            half4 src = srcFP.eval(xy);
+            half4 dst = dstFP.eval(xy);
             half4 color = saturate(k.x * src * dst +
                                    k.y * src +
                                    k.z * dst +
diff --git a/src/effects/imagefilters/SkMagnifierImageFilter.cpp b/src/effects/imagefilters/SkMagnifierImageFilter.cpp
index 58dfbd6..136c012 100644
--- a/src/effects/imagefilters/SkMagnifierImageFilter.cpp
+++ b/src/effects/imagefilters/SkMagnifierImageFilter.cpp
@@ -126,7 +126,7 @@
                 weight = min(min(delta_squared.x, delta_squared.y), 1.0);
             }
 
-            return shade(src, mix(coord, zoom_coord, weight));
+            return src.eval(mix(coord, zoom_coord, weight));
         }
     )");
 
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index b7c8b4d..0d5f537 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -405,7 +405,7 @@
         uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
         uniform half4 color;
         half4 main(half4 inColor) {
-            return filter(fp, color);
+            return fp.eval(color);
         }
     )");
     SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect));
@@ -423,7 +423,7 @@
     static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForBlender, R"(
         uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
         half4 main(half4 src, half4 dst) {
-            return filter(fp, dst);
+            return fp.eval(dst);
         }
     )");
     return GrSkSLFP::Make(effect, "UseDestColorAsInput", /*inputFP=*/nullptr,
@@ -440,7 +440,7 @@
     static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
         uniform colorFilter fp;  // Declared as colorFilter so we can pass a color
         half4 main(half4 inColor) {
-            return inColor.a * filter(fp, unpremul(inColor).rgb1);
+            return inColor.a * fp.eval(unpremul(inColor).rgb1);
         }
     )");
     return GrSkSLFP::Make(effect,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 1adb44e..9422c7e 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -394,7 +394,7 @@
         uniform half range;
         uniform shader table;
         half4 main(float2 xy, half4 color) {
-            half value = shade(table, sk_FragCoord.xy).a - 0.5; // undo the bias in the table
+            half value = table.eval(sk_FragCoord.xy).a - 0.5; // undo the bias in the table
             // For each color channel, add the random offset to the channel value and then clamp
             // between 0 and alpha to keep the color premultiplied.
             return half4(clamp(color.rgb + value * range, 0.0, color.a), color.a);
diff --git a/src/gpu/gradients/GrGradientShader.cpp b/src/gpu/gradients/GrGradientShader.cpp
index 2d5b2cb..b3e2fc1 100644
--- a/src/gpu/gradients/GrGradientShader.cpp
+++ b/src/gpu/gradients/GrGradientShader.cpp
@@ -425,7 +425,7 @@
         uniform int layoutPreservesOpacity;  // specialized
 
         half4 main(float2 coord) {
-            half4 t = shade(gradLayout, coord);
+            half4 t = gradLayout.eval(coord);
             half4 outColor;
 
             // If t.x is below 0, use the left border color without invoking the child processor.
@@ -442,7 +442,7 @@
             } else {
                 // Always sample from (x, 0), discarding y, since the layout FP can use y as a
                 // side-channel.
-                outColor = shade(colorizer, t.x0);
+                outColor = colorizer.eval(t.x0);
             }
             if (bool(makePremul)) {
                 outColor.rgb *= outColor.a;
@@ -487,7 +487,7 @@
         uniform int useFloorAbsWorkaround;   // specialized
 
         half4 main(float2 coord) {
-            half4 t = shade(gradLayout, coord);
+            half4 t = gradLayout.eval(coord);
 
             if (!bool(layoutPreservesOpacity) && t.y < 0) {
                 // layout has rejected this fragment (rely on sksl to remove this branch if the
@@ -511,7 +511,7 @@
 
                 // Always sample from (x, 0), discarding y, since the layout FP can use y as a
                 // side-channel.
-                half4 outColor = shade(colorizer, t.x0);
+                half4 outColor = colorizer.eval(t.x0);
                 if (bool(makePremul)) {
                     outColor.rgb *= outColor.a;
                 }
diff --git a/src/sksl/SkSLAnalysis.h b/src/sksl/SkSLAnalysis.h
index ee19213..1772355 100644
--- a/src/sksl/SkSLAnalysis.h
+++ b/src/sksl/SkSLAnalysis.h
@@ -37,7 +37,7 @@
 struct Analysis {
     /**
      * Determines how `program` samples `child`. By default, assumes that the sample coords
-     * (SK_MAIN_COORDS_BUILTIN) might be modified, so `shade(fp, sampleCoords)` is treated as
+     * (SK_MAIN_COORDS_BUILTIN) might be modified, so `child.eval(sampleCoords)` is treated as
      * Explicit. If writesToSampleCoords is false, treats that as PassThrough, instead.
      * If elidedSampleCoordCount is provided, the pointed to value will be incremented by the
      * number of sample calls where the above rewrite was performed.
diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp
index f66b939..17102fa 100644
--- a/src/sksl/SkSLMain.cpp
+++ b/src/sksl/SkSLMain.cpp
@@ -409,15 +409,15 @@
                         }
 
                         String sampleShader(int index, String coords) override {
-                            return "shade(child_" + SkSL::to_string(index) + ", " + coords + ")";
+                            return "child_" + SkSL::to_string(index) + ".eval(" + coords + ")";
                         }
 
                         String sampleColorFilter(int index, String color) override {
-                            return "filter(child_" + SkSL::to_string(index) + ", " + color + ")";
+                            return "child_" + SkSL::to_string(index) + ".eval(" + color + ")";
                         }
 
                         String sampleBlender(int index, String src, String dst) override {
-                            return "blend(child_" + SkSL::to_string(index) + ", " + src + ", " +
+                            return "child_" + SkSL::to_string(index) + ".eval(" + src + ", " +
                                    dst + ")";
                         }
 
diff --git a/src/sksl/ir/SkSLChildCall.cpp b/src/sksl/ir/SkSLChildCall.cpp
index 90ab36e..e2da51c 100644
--- a/src/sksl/ir/SkSLChildCall.cpp
+++ b/src/sksl/ir/SkSLChildCall.cpp
@@ -29,17 +29,12 @@
 }
 
 String ChildCall::description() const {
-    String result;
-    switch (this->child().type().typeKind()) {
-        case Type::TypeKind::kBlender:     result += "blend(";  break;
-        case Type::TypeKind::kColorFilter: result += "filter("; break;
-        case Type::TypeKind::kShader:      result += "shade(";  break;
-        default: SkUNREACHABLE;
-    }
-    result += this->child().name();
+    String result = String(this->child().name()) + ".eval(";
+    String separator;
     for (const std::unique_ptr<Expression>& arg : this->arguments()) {
-        result += ", ";
+        result += separator;
         result += arg->description();
+        separator = ", ";
     }
     result += ")";
     return result;
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index e80ec15..bf90812 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -140,15 +140,15 @@
 
     // Sampling a child shader requires that we pass explicit coords
     test_valid("uniform shader child;"
-               "half4 main(half4 c) { return sample(child, c.rg); }");
+               "half4 main(half4 c) { return child.eval(c.rg); }");
 
     // Sampling a colorFilter requires a color
     test_valid("uniform colorFilter child;"
-               "half4 main(half4 c) { return sample(child, c); }");
+               "half4 main(half4 c) { return child.eval(c); }");
 
     // Sampling a blender requires two colors
     test_valid("uniform blender child;"
-               "half4 main(half4 c) { return sample(child, c, c); }");
+               "half4 main(half4 c) { return child.eval(c, c); }");
 }
 
 DEF_TEST(SkRuntimeEffectForBlender, r) {
@@ -196,15 +196,15 @@
 
     // Sampling a child shader requires that we pass explicit coords
     test_valid("uniform shader child;"
-               "half4 main(half4 s, half4 d) { return sample(child, s.rg); }");
+               "half4 main(half4 s, half4 d) { return child.eval(s.rg); }");
 
     // Sampling a colorFilter requires a color
     test_valid("uniform colorFilter child;"
-               "half4 main(half4 s, half4 d) { return sample(child, d); }");
+               "half4 main(half4 s, half4 d) { return child.eval(d); }");
 
     // Sampling a blender requires two colors
     test_valid("uniform blender child;"
-               "half4 main(half4 s, half4 d) { return sample(child, s, d); }");
+               "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
 }
 
 DEF_TEST(SkRuntimeEffectForShader, r) {
@@ -258,15 +258,15 @@
 
     // Sampling a child shader requires that we pass explicit coords
     test_valid("uniform shader child;"
-               "half4 main(float2 p) { return sample(child, p); }");
+               "half4 main(float2 p) { return child.eval(p); }");
 
     // Sampling a colorFilter requires a color
     test_valid("uniform colorFilter child;"
-               "half4 main(float2 p, half4 c) { return sample(child, c); }");
+               "half4 main(float2 p, half4 c) { return child.eval(c); }");
 
     // Sampling a blender requires two colors
     test_valid("uniform blender child;"
-               "half4 main(float2 p, half4 c) { return sample(child, c, c); }");
+               "half4 main(float2 p, half4 c) { return child.eval(c, c); }");
 }
 
 using PreTestFn = std::function<void(SkCanvas*, SkPaint*)>;
@@ -479,7 +479,7 @@
 
     // Sampling a null child should return the paint color
     effect.build("uniform shader child;"
-                 "half4 main(float2 p) { return shade(child, p); }");
+                 "half4 main(float2 p) { return child.eval(p); }");
     effect.child("child") = nullptr;
     effect.test(0xFF00FFFF,
                 [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });
@@ -488,13 +488,13 @@
 
     // Sampling a simple child at our coordinates
     effect.build("uniform shader child;"
-                 "half4 main(float2 p) { return shade(child, p); }");
+                 "half4 main(float2 p) { return child.eval(p); }");
     effect.child("child") = rgbwShader;
     effect.test({0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 0xFFFFFFFF});
 
     // Sampling with explicit coordinates (reflecting about the diagonal)
     effect.build("uniform shader child;"
-                 "half4 main(float2 p) { return shade(child, p.yx); }");
+                 "half4 main(float2 p) { return child.eval(p.yx); }");
     effect.child("child") = rgbwShader;
     effect.test({0xFF0000FF, 0xFFFF0000, 0xFF00FF00, 0xFFFFFFFF});
 
@@ -580,13 +580,13 @@
 
     // Sampling a null shader/color filter should return the paint color.
     effect.build("uniform shader child;"
-                 "half4 main(half4 s, half4 d) { return shade(child, s.rg); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(s.rg); }");
     effect.child("child") = nullptr;
     effect.test(0xFF00FFFF,
                 [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });
 
     effect.build("uniform colorFilter child;"
-                 "half4 main(half4 s, half4 d) { return filter(child, s); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(s); }");
     effect.child("child") = nullptr;
     effect.test(0xFF00FFFF,
                 [](SkCanvas*, SkPaint* paint) { paint->setColor4f({1.0f, 1.0f, 0.0f, 1.0f}); });
@@ -594,7 +594,7 @@
     // Sampling a null blender should do a src-over blend. Draw 50% black over RGBW to verify this.
     surface->getCanvas()->drawPaint(rgbwPaint);
     effect.build("uniform blender child;"
-                 "half4 main(half4 s, half4 d) { return blend(child, s, d); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
     effect.child("child") = nullptr;
     effect.test({0xFF000080, 0xFF008000, 0xFF800000, 0xFF808080},
                 [](SkCanvas*, SkPaint* paint) { paint->setColor4f({0.0f, 0.0f, 0.0f, 0.497f}); });
@@ -602,7 +602,7 @@
     // Sampling a shader at various coordinates
     effect.build("uniform shader child;"
                  "uniform half2 pos;"
-                 "half4 main(half4 s, half4 d) { return shade(child, pos); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(pos); }");
     effect.child("child") = make_RGBW_shader();
     effect.uniform("pos") = float2{0, 0};
     effect.test(0xFF0000FF);
@@ -618,14 +618,14 @@
 
     // Sampling a color filter
     effect.build("uniform colorFilter child;"
-                 "half4 main(half4 s, half4 d) { return filter(child, half4(1)); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(half4(1)); }");
     effect.child("child") = SkColorFilters::Blend(0xFF012345, SkBlendMode::kSrc);
     effect.test(0xFF452301);
 
     // Sampling a built-in blender
     surface->getCanvas()->drawPaint(rgbwPaint);
     effect.build("uniform blender child;"
-                 "half4 main(half4 s, half4 d) { return blend(child, s, d); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
     effect.child("child") = SkBlender::Mode(SkBlendMode::kPlus);
     effect.test({0xFF4523FF, 0xFF45FF01, 0xFFFF2301, 0xFFFFFFFF},
                 [](SkCanvas*, SkPaint* paint) { paint->setColor(0xFF012345); });
@@ -633,7 +633,7 @@
     // Sampling a runtime-effect blender
     surface->getCanvas()->drawPaint(rgbwPaint);
     effect.build("uniform blender child;"
-                 "half4 main(half4 s, half4 d) { return blend(child, s, d); }");
+                 "half4 main(half4 s, half4 d) { return child.eval(s, d); }");
     effect.child("child") = SkBlenders::Arithmetic(0, 1, 1, 0, /*enforcePremul=*/false);
     effect.test({0xFF4523FF, 0xFF45FF01, 0xFFFF2301, 0xFFFFFFFF},
                 [](SkCanvas*, SkPaint* paint) { paint->setColor(0xFF012345); });
@@ -756,7 +756,7 @@
         "uniform shader paint;"
         "struct S { half4 rgba; };"
         "void process(inout S s) { s.rgba.rgb *= 0.5; }"
-        "half4 main(float2 p) { S s; s.rgba = shade(paint, p); process(s); return s.rgba; }"
+        "half4 main(float2 p) { S s; s.rgba = paint.eval(p); process(s); return s.rgba; }"
     ));
     REPORTER_ASSERT(r, childEffect, "%s\n", err.c_str());
     sk_sp<SkShader> nullChild = nullptr;
@@ -775,7 +775,7 @@
             "uniform shader child;"
             "struct S { float2 coord; };"
             "void process(inout S s) { s.coord = s.coord.yx; }"
-            "half4 main(float2 p) { S s; s.coord = p; process(s); return shade(child, s.coord); "
+            "half4 main(float2 p) { S s; s.coord = p; process(s); return child.eval(s.coord); "
             "}");
     effect.child("child") = child;
     effect.test(0xFF00407F, [](SkCanvas*, SkPaint* paint) {
@@ -835,31 +835,31 @@
 
     // Direct use of passed-in coords. Here, the only use of sample coords is for a sample call
     // converted to passthrough, so referenceSampleCoords is *false*, despite appearing in main.
-    test("half4 main(float2 xy) { return shade(child, xy); }", false, false);
+    test("half4 main(float2 xy) { return child.eval(xy); }", false, false);
     // Sample with passed-in coords, read (but don't write) sample coords elsewhere
-    test("half4 main(float2 xy) { return shade(child, xy) + sin(xy.x); }", false, true);
+    test("half4 main(float2 xy) { return child.eval(xy) + sin(xy.x); }", false, true);
 
     // Cases where our optimization is not valid, and does not happen:
 
     // Sampling with values completely unrelated to passed-in coords
-    test("half4 main(float2 xy) { return shade(child, float2(0, 0)); }", true, false);
+    test("half4 main(float2 xy) { return child.eval(float2(0, 0)); }", true, false);
     // Use of expression involving passed in coords
-    test("half4 main(float2 xy) { return shade(child, xy * 0.5); }", true, true);
+    test("half4 main(float2 xy) { return child.eval(xy * 0.5); }", true, true);
     // Use of coords after modification
-    test("half4 main(float2 xy) { xy *= 2; return shade(child, xy); }", true, true);
+    test("half4 main(float2 xy) { xy *= 2; return child.eval(xy); }", true, true);
     // Use of coords after modification via out-param call
     test("void adjust(inout float2 xy) { xy *= 2; }"
-         "half4 main(float2 xy) { adjust(xy); return shade(child, xy); }", true, true);
+         "half4 main(float2 xy) { adjust(xy); return child.eval(xy); }", true, true);
 
     // There should (must) not be any false-positive cases. There are false-negatives.
     // In all of these cases, our optimization would be valid, but does not happen:
 
     // Direct use of passed-in coords, modified after use
-    test("half4 main(float2 xy) { half4 c = shade(child, xy); xy *= 2; return c; }", true, true);
+    test("half4 main(float2 xy) { half4 c = child.eval(xy); xy *= 2; return c; }", true, true);
     // Passed-in coords copied to a temp variable
-    test("half4 main(float2 xy) { float2 p = xy; return shade(child, p); }", true, true);
+    test("half4 main(float2 xy) { float2 p = xy; return child.eval(p); }", true, true);
     // Use of coords passed to helper function
-    test("half4 helper(float2 xy) { return shade(child, xy); }"
+    test("half4 helper(float2 xy) { return child.eval(xy); }"
          "half4 main(float2 xy) { return helper(xy); }", true, true);
 }
 
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 6bfad93..ce9ec59 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -1948,7 +1948,7 @@
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), default_settings(),
                            SkSL::ProgramKind::kRuntimeShader);
     DSLGlobalVar shader(kUniform_Modifier, kShader_Type, "child");
-    EXPECT_EQUAL(Sample(shader, Float2(0, 0)), "shade(child, float2(0.0, 0.0))");
+    EXPECT_EQUAL(Sample(shader, Float2(0, 0)), "child.eval(float2(0.0, 0.0))");
 
     {
         ExpectError error(r, "no match for sample(shader, half4)");
diff --git a/tests/sksl/runtime/SampleWithExplicitCoord.stage b/tests/sksl/runtime/SampleWithExplicitCoord.stage
index 159c7c3..da80d4b 100644
--- a/tests/sksl/runtime/SampleWithExplicitCoord.stage
+++ b/tests/sksl/runtime/SampleWithExplicitCoord.stage
@@ -1,4 +1,4 @@
 half4 main(float2 p)
 {
-	return half4(shade(child_0, _coords.yx));
+	return half4(child_0.eval(_coords.yx));
 }
diff --git a/tests/sksl/runtime_errors/IllegalShaderSampling.skvm b/tests/sksl/runtime_errors/IllegalShaderSampling.skvm
index a28654d..90f46a1 100644
--- a/tests/sksl/runtime_errors/IllegalShaderSampling.skvm
+++ b/tests/sksl/runtime_errors/IllegalShaderSampling.skvm
@@ -36,4 +36,16 @@
 error: 56: call to 'filter' expected 2 arguments, but found 3
 error: 57: expected 'shader', but found 'blender'
 error: 58: call to 'shade' expected 2 arguments, but found 3
-36 errors
+error: 62: no match for shader::eval(float2, half4)
+error: 63: no match for shader::eval(half4)
+error: 64: no match for shader::eval(half4, float2)
+error: 65: no match for shader::eval()
+error: 66: no match for shader::eval(float3x3)
+error: 68: no match for colorFilter::eval()
+error: 69: no match for colorFilter::eval(float2)
+error: 70: no match for colorFilter::eval(float2, half4)
+error: 72: no match for blender::eval()
+error: 73: no match for blender::eval(half4)
+error: 74: no match for blender::eval(float2)
+error: 75: no match for blender::eval(float2, half4)
+48 errors
diff --git a/tools/RuntimeBlendUtils.cpp b/tools/RuntimeBlendUtils.cpp
index c432ee7..2305521 100644
--- a/tools/RuntimeBlendUtils.cpp
+++ b/tools/RuntimeBlendUtils.cpp
@@ -13,7 +13,7 @@
     static auto result = SkRuntimeEffect::MakeForBlender(SkString(R"(
         uniform blender b;
         half4 main(half4 src, half4 dst) {
-            return blend(b, src, dst);
+            return b.eval(src, dst);
         }
     )"));
 
diff --git a/tools/viewer/SkSLSlide.cpp b/tools/viewer/SkSLSlide.cpp
index ef3655a..4a0db13 100644
--- a/tools/viewer/SkSLSlide.cpp
+++ b/tools/viewer/SkSLSlide.cpp
@@ -43,7 +43,7 @@
         "uniform shader child;\n"
         "\n"
         "half4 main(float2 p) {\n"
-        "    return shade(child, p);\n"
+        "    return child.eval(p);\n"
         "}\n";
 
     fCodeIsDirty = true;