Support initializers on global variables in SkSL to SkVM

Bug: skia:11295
Change-Id: I72c09b75a3ff5d668e99dcc3620850b82071b560
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/371340
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/sksl/SkSLVMGenerator.cpp b/src/sksl/SkSLVMGenerator.cpp
index c7bb702..d17d1a2 100644
--- a/src/sksl/SkSLVMGenerator.cpp
+++ b/src/sksl/SkSLVMGenerator.cpp
@@ -424,8 +424,9 @@
     size_t fpCount = 0;
     for (const ProgramElement* e : fProgram.elements()) {
         if (e->is<GlobalVarDeclaration>()) {
-            const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
-            const Variable& var = decl.declaration()->as<VarDeclaration>().var();
+            const GlobalVarDeclaration& gvd = e->as<GlobalVarDeclaration>();
+            const VarDeclaration& decl = gvd.declaration()->as<VarDeclaration>();
+            const Variable& var = decl.var();
             SkASSERT(fVariableMap.find(&var) == fVariableMap.end());
 
             // For most variables, fVariableMap stores an index into fSlots, but for fragment
@@ -439,8 +440,10 @@
             // special types like 'void'. Of those, only fragment processors are legal variables.
             SkASSERT(!var.type().isOpaque());
 
-            size_t nslots = slot_count(var.type());
-            fVariableMap[&var] = fSlots.size();
+            // getSlot() allocates space for the variable's value in fSlots, initializes it to zero,
+            // and populates fVariableMap.
+            size_t slot   = this->getSlot(var),
+                   nslots = slot_count(var.type());
 
             if (int builtin = var.modifiers().fLayout.fBuiltin; builtin >= 0) {
                 // builtin variables are system-defined, with special semantics. The only builtin
@@ -448,10 +451,10 @@
                 switch (builtin) {
                     case SK_FRAGCOORD_BUILTIN:
                         SkASSERT(nslots == 4);
-                        fSlots.insert(fSlots.end(), {device.x.id,
-                                                     device.y.id,
-                                                     fBuilder->splat(0.0f).id,
-                                                     fBuilder->splat(1.0f).id});
+                        fSlots[slot + 0] = device.x.id;
+                        fSlots[slot + 1] = device.y.id;
+                        fSlots[slot + 2] = fBuilder->splat(0.0f).id;
+                        fSlots[slot + 3] = fBuilder->splat(1.0f).id;
                         break;
                     default:
                         SkDEBUGFAIL("Unsupported builtin");
@@ -459,11 +462,14 @@
             } else if (is_uniform(var)) {
                 // For uniforms, copy the supplied IDs over
                 SkASSERT(uniformIter + nslots <= uniforms.end());
-                fSlots.insert(fSlots.end(), uniformIter, uniformIter + nslots);
+                std::copy(uniformIter, uniformIter + nslots, fSlots.begin() + slot);
                 uniformIter += nslots;
-            } else {
-                // For other globals, initialize them to zero
-                fSlots.insert(fSlots.end(), nslots, fBuilder->splat(0.0f).id);
+            } else if (decl.value()) {
+                // For other globals, populate with the initializer expression (if there is one)
+                Value val = this->writeExpression(*decl.value());
+                for (size_t i = 0; i < nslots; ++i) {
+                    fSlots[slot + i] = val[i];
+                }
             }
         }
     }
@@ -517,8 +523,6 @@
         return entry->second;
     }
 
-    SkASSERT(!is_uniform(v));  // Should have been added at construction time
-
     size_t slot   = fSlots.size(),
            nslots = slot_count(v.type());
     fSlots.resize(slot + nslots, fBuilder->splat(0.0f).id);
diff --git a/tests/sksl/runtime/GlobalVariables.skvm b/tests/sksl/runtime/GlobalVariables.skvm
index e022147..6cdeab8 100644
--- a/tests/sksl/runtime/GlobalVariables.skvm
+++ b/tests/sksl/runtime/GlobalVariables.skvm
@@ -1,8 +1,8 @@
 2 registers, 6 instructions:
 0	r0 = splat 0 (0)
-1	r1 = splat 40000000 (2)
+1	r1 = splat 3F800000 (1)
 loop:
 2	    store32 ptr1 r0
-3	    store32 ptr2 r0
+3	    store32 ptr2 r1
 4	    store32 ptr3 r0
 5	    store32 ptr4 r1