Replace DSL's Sample() with DSLGlobalVar::eval()

Bug: skia:12302
Change-Id: I7ff7bae388c5991f2c23c8945355fea55c42095a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/447436
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/include/sksl/DSLCore.h b/include/sksl/DSLCore.h
index 6dc470c..f4eb8c1 100644
--- a/include/sksl/DSLCore.h
+++ b/include/sksl/DSLCore.h
@@ -433,26 +433,6 @@
 DSLExpression Round(DSLExpression x, PositionInfo pos = PositionInfo::Capture());
 
 /**
- * Samples the child processor at the current coordinates.
- */
-DSLExpression Sample(DSLExpression fp, PositionInfo pos = PositionInfo::Capture());
-
-/**
- * Implements the following functions:
- *     half4 sample(fragmentProcessor fp, float2 coords);
- *     half4 sample(fragmentProcessor fp, half4 input);
- */
-DSLExpression Sample(DSLExpression target, DSLExpression x,
-                     PositionInfo pos = PositionInfo::Capture());
-
-/**
- * Implements the following functions:
- *     half4 sample(fragmentProcessor fp, float2 coords, half4 input);
- */
-DSLExpression Sample(DSLExpression childProcessor, DSLExpression x, DSLExpression y,
-                     PositionInfo pos = PositionInfo::Capture());
-
-/**
  * Returns x clamped to the range [0, 1]. If x is a vector, operates componentwise.
  */
 DSLExpression Saturate(DSLExpression x, PositionInfo pos = PositionInfo::Capture());
diff --git a/include/sksl/DSLType.h b/include/sksl/DSLType.h
index 762df61..115711c 100644
--- a/include/sksl/DSLType.h
+++ b/include/sksl/DSLType.h
@@ -146,6 +146,11 @@
      */
     bool isStruct() const;
 
+    /**
+     * Returns true if this is a Skia object type (shader, colorFilter, blender).
+     */
+    bool isEffectChild() const;
+
     template<typename... Args>
     static DSLExpression Construct(DSLType type, DSLVarBase& var, Args&&... args) {
         DSLExpression argArray[] = {var, args...};
diff --git a/include/sksl/DSLVar.h b/include/sksl/DSLVar.h
index cfac770..059bbab 100644
--- a/include/sksl/DSLVar.h
+++ b/include/sksl/DSLVar.h
@@ -14,6 +14,7 @@
 
 namespace SkSL {
 
+class Expression;
 class IRGenerator;
 class SPIRVCodeGenerator;
 class Variable;
@@ -236,7 +237,23 @@
         return this->operator=(DSLExpression(param));
     }
 
+    /**
+     * Implements the following method calls:
+     *     half4 shader::eval(float2 coords);
+     *     half4 colorFilter::eval(half4 input);
+     */
+    DSLPossibleExpression eval(DSLExpression x, PositionInfo pos = PositionInfo::Capture());
+
+    /**
+     * Implements the following method call:
+     *     half4 blender::eval(half4 src, half4 dst);
+     */
+    DSLPossibleExpression eval(DSLExpression x, DSLExpression y,
+                               PositionInfo pos = PositionInfo::Capture());
+
 private:
+    std::unique_ptr<SkSL::Expression> methodCall(skstd::string_view methodName, PositionInfo pos);
+
     using INHERITED = DSLVarBase;
 };
 
diff --git a/src/sksl/dsl/DSLCore.cpp b/src/sksl/dsl/DSLCore.cpp
index f7664cb..4fbbefb 100644
--- a/src/sksl/dsl/DSLCore.cpp
+++ b/src/sksl/dsl/DSLCore.cpp
@@ -601,15 +601,6 @@
     return DSLExpression(DSLCore::Call("round", std::move(x)), pos);
 }
 
-DSLExpression Sample(DSLExpression target, DSLExpression x, PositionInfo pos) {
-    return DSLExpression(DSLCore::Call("$eval", std::move(x), std::move(target)), pos);
-}
-
-DSLExpression Sample(DSLExpression target, DSLExpression x, DSLExpression y, PositionInfo pos) {
-    return DSLExpression(DSLCore::Call("$eval", std::move(x), std::move(y), std::move(target)),
-                         pos);
-}
-
 DSLExpression Saturate(DSLExpression x, PositionInfo pos) {
     return DSLExpression(DSLCore::Call("saturate", std::move(x)), pos);
 }
diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp
index 4221a97..8ed0530 100644
--- a/src/sksl/dsl/DSLType.cpp
+++ b/src/sksl/dsl/DSLType.cpp
@@ -103,6 +103,10 @@
     return this->skslType().isStruct();
 }
 
+bool DSLType::isEffectChild() const {
+    return this->skslType().isEffectChild();
+}
+
 const SkSL::Type& DSLType::skslType() const {
     if (fSkSLType) {
         return *fSkSLType;
diff --git a/src/sksl/dsl/DSLVar.cpp b/src/sksl/dsl/DSLVar.cpp
index 9e89be4..70d0115 100644
--- a/src/sksl/dsl/DSLVar.cpp
+++ b/src/sksl/dsl/DSLVar.cpp
@@ -178,6 +178,34 @@
     return this->assign(std::move(expr));
 }
 
+std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(skstd::string_view methodName,
+                                                           PositionInfo pos) {
+    if (!this->fType.isEffectChild()) {
+        DSLWriter::ReportError("type does not support method calls", pos);
+        return nullptr;
+    }
+    return DSLWriter::ConvertField(DSLExpression(*this).release(), methodName);
+}
+
+DSLPossibleExpression DSLGlobalVar::eval(DSLExpression x, PositionInfo pos) {
+    ExpressionArray converted;
+    converted.push_back(x.release());
+
+    auto method = this->methodCall("eval", pos);
+    return DSLPossibleExpression(
+            method ? DSLWriter::Call(std::move(method), std::move(converted), pos) : nullptr);
+}
+
+DSLPossibleExpression DSLGlobalVar::eval(DSLExpression x, DSLExpression y, PositionInfo pos) {
+    ExpressionArray converted;
+    converted.push_back(x.release());
+    converted.push_back(y.release());
+
+    auto method = this->methodCall("eval", pos);
+    return DSLPossibleExpression(
+            method ? DSLWriter::Call(std::move(method), std::move(converted), pos) : nullptr);
+}
+
 } // namespace dsl
 
 } // namespace SkSL
diff --git a/tests/SkDSLRuntimeEffectTest.cpp b/tests/SkDSLRuntimeEffectTest.cpp
index d0cfd06..f9a197e 100644
--- a/tests/SkDSLRuntimeEffectTest.cpp
+++ b/tests/SkDSLRuntimeEffectTest.cpp
@@ -256,7 +256,7 @@
         Declare(child);
         Parameter p2(kFloat2_Type, "p");
         Function(kFloat4_Type, "main", p2).define(
-            Return(Sample(child, p2))
+            Return(child.eval(p2))
         );
         effect.end();
         effect.child(child.name()) = nullptr;
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 8298609..a21ea76 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -1951,11 +1951,17 @@
     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)), "child.eval(float2(0.0, 0.0))");
+    DSLGlobalVar notShader(kUniform_Modifier, kFloat_Type, "x");
+    EXPECT_EQUAL(shader.eval(Float2(0, 0)), "child.eval(float2(0.0, 0.0))");
 
     {
-        ExpectError error(r, "no match for $eval(half4, shader)");
-        Sample(shader, Half4(1)).release();
+        ExpectError error(r, "no match for shader::eval(half4)");
+        shader.eval(Half4(1)).release();
+    }
+
+    {
+        ExpectError error(r, "type does not support method calls");
+        notShader.eval(Half4(1)).release();
     }
 }