Prevent seed_shader from being appended mid-shader.

Runtime color filters use a dummy identity matrix when evaluating
child shaders. Because the MatrixRec was newly constructed, it
thought that nothing was initialized, and calling `apply` would
inject a `seed_shader` into the pipeline. This would clobber all
SkRP registers, replacing any coordinates in r/g with device-space
pixel coordinates.

Change-Id: I93cd9b4921c2958fae0dfe1d25566421ff55a949
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/637836
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index a22ecf2..d7b187b 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -1213,6 +1213,7 @@
                                                                                 rec.fDstCS);
 
             SkShaderBase::MatrixRec matrix(SkMatrix::I());
+            matrix.markCTMApplied();
             RuntimeEffectRPCallbacks callbacks(rec, matrix, fChildren, fEffect->fSampleUsages);
             bool success = program->appendStages(rec.fPipeline, rec.fAlloc, &callbacks,
                                                  uniforms_as_span(inputs.get()));
diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp
index b1a1783..7e51cba 100644
--- a/src/shaders/SkShader.cpp
+++ b/src/shaders/SkShader.cpp
@@ -77,7 +77,8 @@
                      fTotalLocalMatrix,
                      /*pendingLocalMatrix=*/SkMatrix::I(),
                      fTotalMatrixIsValid,
-                     /*ctmApplied=*/true};}
+                     /*ctmApplied=*/true};
+}
 
 SkShaderBase::MatrixRec SkShaderBase::MatrixRec::concat(const SkMatrix& m) const {
     return {fCTM,
diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h
index fa137af..40d878c 100644
--- a/src/shaders/SkShaderBase.h
+++ b/src/shaders/SkShaderBase.h
@@ -237,6 +237,9 @@
         /** Call to indicate that the mapping from shader to device space is not known. */
         void markTotalMatrixInvalid() { fTotalMatrixIsValid = false; }
 
+        /** Marks the CTM as already applied; can avoid re-seeding the shader unnecessarily. */
+        void markCTMApplied() { fCTMApplied = true; }
+
         /**
          * Indicates whether the total matrix of a MatrixRec passed to a SkShader actually
          * represents the full transform between that shader's coordinate space and device space.