Add sample(child, matrix) to SkSL.

This allows fragment processors to sample their children with their
local coordinate system transformed by a matrix.

Change-Id: Ifa848bbd85b939bbc5751fec5cf8f89ee904bf39
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282590
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 77de66b..e4b18c8 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -74,6 +74,28 @@
     fFlags |= kHasCoordTransforms_Flag;
 }
 
+void GrFragmentProcessor::setSampleMatrix(SkSL::SampleMatrix matrix) {
+    if (matrix == fMatrix) {
+        return;
+    }
+    SkASSERT(fMatrix.fKind != SkSL::SampleMatrix::Kind::kVariable);
+    if (fMatrix.fKind == SkSL::SampleMatrix::Kind::kConstantOrUniform) {
+        SkASSERT(matrix.fKind == SkSL::SampleMatrix::Kind::kVariable ||
+                 (matrix.fKind == SkSL::SampleMatrix::Kind::kMixed &&
+                  matrix.fExpression == fMatrix.fExpression));
+        fMatrix = SkSL::SampleMatrix(SkSL::SampleMatrix::Kind::kMixed, fMatrix.fOwner,
+                                     fMatrix.fExpression);
+    } else {
+        SkASSERT(fMatrix.fKind == SkSL::SampleMatrix::Kind::kNone);
+        fMatrix = matrix;
+    }
+    if (matrix.fKind == SkSL::SampleMatrix::Kind::kVariable) {
+        for (auto& child : fChildProcessors) {
+            child->setSampleMatrix(matrix);
+        }
+    }
+}
+
 #ifdef SK_DEBUG
 bool GrFragmentProcessor::isInstantiated() const {
     for (int i = 0; i < fTextureSamplerCnt; ++i) {
@@ -100,7 +122,8 @@
 
     int index = fChildProcessors.count();
     fChildProcessors.push_back(std::move(child));
-
+    SkASSERT(fMatrix.fKind == SkSL::SampleMatrix::Kind::kNone ||
+             fMatrix.fKind == SkSL::SampleMatrix::Kind::kConstantOrUniform);
     return index;
 }