SkRuntimeShaderMaker -> SkRuntimeShaderFactory

This refactor makes it work like the runtime color filter, where inputs
can be updated without generating a new shader key every time.

Change-Id: Ic1762aebae96fd8b7a8a74fb200bc02ec08cc029
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235798
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gm/runtimeshader.cpp b/gm/runtimeshader.cpp
index 244de61..6234130 100644
--- a/gm/runtimeshader.cpp
+++ b/gm/runtimeshader.cpp
@@ -17,13 +17,11 @@
 #include "src/core/SkColorFilterPriv.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
+#include "src/shaders/SkRTShader.h"
 #include "tools/Resources.h"
 
 #include <stddef.h>
 
-extern sk_sp<SkShader> SkRuntimeShaderMaker(SkString sksl, sk_sp<SkData> inputs,
-                                            const SkMatrix* localMatrix, bool isOpaque);
-
 const char* gProg = R"(
     layout(ctype=SkRect) in uniform half4 gColor;
 
@@ -52,7 +50,7 @@
             fData = SkData::MakeUninitialized(sizeof(SkColor4f));
             SkColor4f* c = (SkColor4f*)fData->writable_data();
             *c = {1, 0, 0, 1};
-            gShader = SkRuntimeShaderMaker(SkString(gProg), fData, &localM, true);
+            gShader = SkRuntimeShaderFactory(SkString(gProg), true).make(fData, &localM);
         }
     }
 
diff --git a/src/shaders/SkRTShader.cpp b/src/shaders/SkRTShader.cpp
index 6d59e55..34dc5a4 100644
--- a/src/shaders/SkRTShader.cpp
+++ b/src/shaders/SkRTShader.cpp
@@ -35,12 +35,12 @@
 }
 #endif
 
-SkRTShader::SkRTShader(SkString sksl, sk_sp<SkData> inputs, const SkMatrix* localMatrix,
+SkRTShader::SkRTShader(int index, SkString sksl, sk_sp<SkData> inputs, const SkMatrix* localMatrix,
                        bool isOpaque)
     : SkShaderBase(localMatrix)
     , fSkSL(std::move(sksl))
     , fInputs(std::move(inputs))
-    , fUniqueID(new_sksl_unique_id())
+    , fUniqueID(index)
     , fIsOpaque(isOpaque)
 {}
 
@@ -112,6 +112,11 @@
 }
 
 sk_sp<SkFlattenable> SkRTShader::CreateProc(SkReadBuffer& buffer) {
+    // We don't have a way to ensure that indices are consistent and correct when deserializing.
+    // Perhaps we should have a hash table to map strings to indices? For now, all shaders get a
+    // new unique ID after serialization.
+    int index = new_sksl_unique_id();
+
     SkString sksl;
     buffer.readString(&sksl);
     sk_sp<SkData> inputs = buffer.readByteArrayAsData();
@@ -124,16 +129,10 @@
         localMPtr = &localM;
     }
 
-    return sk_sp<SkFlattenable>(new SkRTShader(std::move(sksl), std::move(inputs),
+    return sk_sp<SkFlattenable>(new SkRTShader(index, std::move(sksl), std::move(inputs),
                                                localMPtr, isOpaque));
 }
 
-sk_sp<SkShader> SkRuntimeShaderMaker(SkString sksl, sk_sp<SkData> inputs,
-                                     const SkMatrix* localMatrix, bool isOpaque) {
-    return sk_sp<SkShader>(new SkRTShader(std::move(sksl), std::move(inputs),
-                                          localMatrix, isOpaque));
-}
-
 #if SK_SUPPORT_GPU
 std::unique_ptr<GrFragmentProcessor> SkRTShader::asFragmentProcessor(const GrFPArgs& args) const {
     SkMatrix matrix;
@@ -145,3 +144,13 @@
                           &matrix);
 }
 #endif
+
+SkRuntimeShaderFactory::SkRuntimeShaderFactory(SkString sksl, bool isOpaque)
+    : fIndex(new_sksl_unique_id())
+    , fSkSL(std::move(sksl))
+    , fIsOpaque(isOpaque) {}
+
+sk_sp<SkShader> SkRuntimeShaderFactory::make(sk_sp<SkData> inputs, const SkMatrix* localMatrix) {
+    return sk_sp<SkShader>(
+            new SkRTShader(fIndex, fSkSL, std::move(inputs), localMatrix, fIsOpaque));
+}
diff --git a/src/shaders/SkRTShader.h b/src/shaders/SkRTShader.h
index a25e930..57d69c3 100644
--- a/src/shaders/SkRTShader.h
+++ b/src/shaders/SkRTShader.h
@@ -22,7 +22,8 @@
 
 class SkRTShader : public SkShaderBase {
 public:
-    SkRTShader(SkString sksl, sk_sp<SkData> inputs, const SkMatrix* localMatrix, bool isOpaque);
+    SkRTShader(int index, SkString sksl, sk_sp<SkData> inputs, const SkMatrix* localMatrix,
+               bool isOpaque);
 
     bool isOpaque() const override { return fIsOpaque; }
 
@@ -48,4 +49,16 @@
     typedef SkShaderBase INHERITED;
 };
 
+class SkRuntimeShaderFactory {
+public:
+    SkRuntimeShaderFactory(SkString sksl, bool isOpaque);
+
+    sk_sp<SkShader> make(sk_sp<SkData> inputs, const SkMatrix* localMatrix);
+
+private:
+    int fIndex;
+    SkString fSkSL;
+    bool fIsOpaque;
+};
+
 #endif