migrate spiral demo from canvaskit

- add atan, fract, dividef, subtractf

Also wants mix(), but I'm still learning how to handle 2 args
functions (e.g. how to support atan(y,x) as well)

Change-Id: Ib9f233cd1c4266110cfea68a7d444f834f875f1f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/286276
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index 233fbd9..89eb7ff 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -452,6 +452,19 @@
                 push(uniform[ix]);
             } break;
 
+            case Inst::kLoadUniform2: {
+                int ix = u8();
+                push(uniform[ix + 0]);
+                push(uniform[ix + 1]);
+            } break;
+
+            case Inst::kLoadUniform3: {
+                int ix = u8();
+                push(uniform[ix + 0]);
+                push(uniform[ix + 1]);
+                push(uniform[ix + 2]);
+            } break;
+
             case Inst::kLoadUniform4: {
                 int ix = u8();
                 push(uniform[ix + 0]);
@@ -525,6 +538,36 @@
                 push(a+x);
             } break;
 
+            case Inst::kSubtractF: {
+                skvm::F32 x = pop(),
+                          a = pop();
+                push(a-x);
+            } break;
+
+            case Inst::kSubtractF2: {
+                skvm::F32 x = pop(), y = pop(),
+                          a = pop(), b = pop();
+                push(b-y);
+                push(a-x);
+            } break;
+
+            case Inst::kSubtractF3: {
+                skvm::F32 x = pop(), y = pop(), z = pop(),
+                          a = pop(), b = pop(), c = pop();
+                push(c-z);
+                push(b-y);
+                push(a-x);
+            } break;
+
+            case Inst::kSubtractF4: {
+                skvm::F32 x = pop(), y = pop(), z = pop(), w = pop(),
+                          a = pop(), b = pop(), c = pop(), d = pop();
+                push(d-w);
+                push(c-z);
+                push(b-y);
+                push(a-x);
+            } break;
+
             case Inst::kMultiplyF: {
                 skvm::F32 x = pop(),
                           a = pop();
@@ -555,6 +598,51 @@
                 push(a*x);
             } break;
 
+            case Inst::kDivideF: {
+                skvm::F32 x = pop(),
+                          a = pop();
+                push(a/x);
+            } break;
+
+            case Inst::kDivideF2: {
+                skvm::F32 x = pop(), y = pop(),
+                          a = pop(), b = pop();
+                push(b/y);
+                push(a/x);
+            } break;
+
+            case Inst::kDivideF3: {
+                skvm::F32 x = pop(), y = pop(), z = pop(),
+                          a = pop(), b = pop(), c = pop();
+                push(c/z);
+                push(b/y);
+                push(a/x);
+            } break;
+
+            case Inst::kDivideF4: {
+                skvm::F32 x = pop(), y = pop(), z = pop(), w = pop(),
+                          a = pop(), b = pop(), c = pop(), d = pop();
+                push(d/w);
+                push(c/z);
+                push(b/y);
+                push(a/x);
+            } break;
+
+            case Inst::kATan: {
+                skvm::F32 x = pop();
+                push(approx_atan(x));
+            } break;
+
+            case Inst::kFract: {
+                skvm::F32 x = pop();
+                push(fract(x));
+            } break;
+
+            case Inst::kSqrt: {
+                skvm::F32 x = pop();
+                push(sqrt(x));
+            } break;
+
             case Inst::kSin: {
                 skvm::F32 x = pop();
                 push(approx_sin(x));
diff --git a/src/sksl/SkSLByteCode.cpp b/src/sksl/SkSLByteCode.cpp
index c2a1ab6..3af0f6f 100644
--- a/src/sksl/SkSLByteCode.cpp
+++ b/src/sksl/SkSLByteCode.cpp
@@ -51,6 +51,7 @@
         VECTOR_MATRIX_DISASSEMBLE(kAddF, "addf")
         VECTOR_DISASSEMBLE(kAddI, "addi")
         case ByteCodeInstruction::kAndB: printf("andb"); break;
+        VECTOR_DISASSEMBLE(kATan, "atan")
         case ByteCodeInstruction::kBranch: printf("branch %d", READ16()); break;
         case ByteCodeInstruction::kCall: printf("call %d", READ8()); break;
         case ByteCodeInstruction::kCallExternal: {
@@ -85,6 +86,7 @@
         VECTOR_DISASSEMBLE(kDivideS, "divideS")
         VECTOR_DISASSEMBLE(kDivideU, "divideu")
         VECTOR_MATRIX_DISASSEMBLE(kDup, "dup")
+        VECTOR_DISASSEMBLE(kFract, "fract")
         case ByteCodeInstruction::kInverse2x2: printf("inverse2x2"); break;
         case ByteCodeInstruction::kInverse3x3: printf("inverse3x3"); break;
         case ByteCodeInstruction::kInverse4x4: printf("inverse4x4"); break;
@@ -654,6 +656,8 @@
                 continue;
             }
 
+            VECTOR_UNARY_FN(kFract, skvx::fract, fFloat)
+
             case ByteCodeInstruction::kInverse2x2:
                 Inverse2x2(sp);
                 continue;
@@ -1062,6 +1066,7 @@
                 continue;
             }
 
+            VECTOR_UNARY_FN(kATan, skvx::atan, fFloat)
             VECTOR_UNARY_FN(kTan, skvx::tan, fFloat)
 
             case ByteCodeInstruction::kWriteExternal4:
diff --git a/src/sksl/SkSLByteCode.h b/src/sksl/SkSLByteCode.h
index f2acdf7..7c1f1ec 100644
--- a/src/sksl/SkSLByteCode.h
+++ b/src/sksl/SkSLByteCode.h
@@ -27,6 +27,7 @@
     VECTOR_MATRIX(kAddF),
     VECTOR(kAddI),
     kAndB,
+    VECTOR(kATan),
     kBranch,
     // Followed by a byte indicating the index of the function to call
     kCall,
@@ -60,6 +61,7 @@
     VECTOR(kDivideU),
     // Duplicates the top stack value
     VECTOR_MATRIX(kDup),
+    VECTOR(kFract),
     kInverse2x2,
     kInverse3x3,
     kInverse4x4,
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 210b54e..60bff34 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright 2019 Google LLC
  *
  * Use of this source code is governed by a BSD-style license that can be
@@ -43,8 +43,10 @@
     , fContext(*context)
     , fOutput(output)
     , fIntrinsics {
+        { "atan",    ByteCodeInstruction::kATan },
         { "cos",     ByteCodeInstruction::kCos },
         { "dot",     SpecialIntrinsic::kDot },
+        { "fract",   ByteCodeInstruction::kFract },
         { "inverse", ByteCodeInstruction::kInverse2x2 },
         { "sin",     ByteCodeInstruction::kSin },
         { "sqrt",    ByteCodeInstruction::kSqrt },
@@ -217,7 +219,9 @@
         VECTOR_UNARY_OP(kConvertStoF)
         VECTOR_UNARY_OP(kConvertUtoF)
 
+        VECTOR_UNARY_OP(kATan)
         VECTOR_UNARY_OP(kCos)
+        VECTOR_UNARY_OP(kFract)
         VECTOR_UNARY_OP(kSin)
         VECTOR_UNARY_OP(kSqrt)
         VECTOR_UNARY_OP(kTan)
@@ -994,7 +998,9 @@
         }
     } else {
         switch (found->second.fValue.fInstruction) {
+            case ByteCodeInstruction::kATan:
             case ByteCodeInstruction::kCos:
+            case ByteCodeInstruction::kFract:
             case ByteCodeInstruction::kSin:
             case ByteCodeInstruction::kSqrt:
             case ByteCodeInstruction::kTan: