[graphite] Refactor UniformManager::calculateOffset

- Removed fCurUBOOffset. This variable mainly mirrored (and always
  equaled) fOffset.
- UniformOffsetCalculator::calculateOffset computed offset twice and two
  separate ways: once calling `sksltype_to_size` and once calling
  Writer::WriteUniform with a null pointer. These two routines compute
  the exact same value and the latter has support for arrays in Metal,
  std140, std430 layout. Removed `sksltype_to_size`. Also removed size
  calculation (which was used to independently update fCurUBOOffset))
  from `get_ubo_aligned_offset`. Now it only computes the aligned start
  offset.
- Renamed `calculateOffset` to `advanceOffset` to better reflect its
  state mutating nature.
- `UniformManager::write` now calls `advanceOffset` instead of
  duplicating the logic that mutates fOffset.

Bug: skia:13860
Change-Id: Iaff81dd629da55e5dc071d09690d32c6ebd2ce82
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/596764
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Arman Uguray <armansito@google.com>
diff --git a/src/gpu/graphite/ContextUtils.cpp b/src/gpu/graphite/ContextUtils.cpp
index 7e466e8..9c815ab 100644
--- a/src/gpu/graphite/ContextUtils.cpp
+++ b/src/gpu/graphite/ContextUtils.cpp
@@ -90,8 +90,9 @@
     UniformOffsetCalculator offsetter(Layout::kMetal, *offset);
 
     for (const SkUniform& u : uniforms) {
-        SkSL::String::appendf(&result, "    layout(offset=%zu) %s %s",
-                              offsetter.calculateOffset(u.type(), u.count()),
+        SkSL::String::appendf(&result,
+                              "    layout(offset=%zu) %s %s",
+                              offsetter.advanceOffset(u.type(), u.count()),
                               SkSLTypeString(u.type()),
                               u.name());
         if (manglingSuffix >= 0) {
diff --git a/src/gpu/graphite/UniformManager.cpp b/src/gpu/graphite/UniformManager.cpp
index cd8434f..20d09df 100644
--- a/src/gpu/graphite/UniformManager.cpp
+++ b/src/gpu/graphite/UniformManager.cpp
@@ -194,6 +194,8 @@
         n = (n == SkUniform::kNonArray) ? 1 : n;
         n *= Cols;
 
+        // A null value for `dst` means that this method was called to calculate the size of the
+        // write without actually copying data.
         if (dst) {
             if (stride == RowsOrVecLength * sizeof(UniformType)) {
                 CopyUniforms<MemType, UniformType>(dst, src, n * RowsOrVecLength);
@@ -215,6 +217,8 @@
         size_t stride = 3 * Rules<UniformType, 3, 3>::Stride(1);
         n = std::max(n, 1);
 
+        // A null value for `dst` means that this method was called to calculate the size of the
+        // write without actually copying data.
         if (dst) {
             size_t offset = 0;
             for (int i = 0; i < n; ++i) {
@@ -237,6 +241,8 @@
     }
 
 public:
+    // If `dest` is a nullptr, then this method returns the size of the write without writing any
+    // data.
     static uint32_t WriteUniform(SkSLType type,
                                  CType ctype,
                                  void *dest,
@@ -396,92 +402,16 @@
     SK_ABORT("Unexpected type");
 }
 
-/** Returns the size in bytes taken up in uniform buffers for SkSLTypes. */
-inline uint32_t sksltype_to_size(SkSLType type) {
-    switch (type) {
-        case SkSLType::kInt:
-        case SkSLType::kUInt:
-        case SkSLType::kFloat:
-            return 4;
-        case SkSLType::kInt2:
-        case SkSLType::kUInt2:
-        case SkSLType::kFloat2:
-            return 8;
-        case SkSLType::kInt3:
-        case SkSLType::kUInt3:
-        case SkSLType::kFloat3:
-        case SkSLType::kInt4:
-        case SkSLType::kUInt4:
-        case SkSLType::kFloat4:
-            return 16;
-
-        case SkSLType::kFloat2x2:
-            return 16;
-        case SkSLType::kFloat3x3:
-            return 48;
-        case SkSLType::kFloat4x4:
-            return 64;
-
-        case SkSLType::kShort:
-        case SkSLType::kUShort:
-        case SkSLType::kHalf:
-            return 2;
-        case SkSLType::kShort2:
-        case SkSLType::kUShort2:
-        case SkSLType::kHalf2:
-            return 4;
-        case SkSLType::kShort3:
-        case SkSLType::kShort4:
-        case SkSLType::kUShort3:
-        case SkSLType::kUShort4:
-        case SkSLType::kHalf3:
-        case SkSLType::kHalf4:
-            return 8;
-
-        case SkSLType::kHalf2x2:
-            return 8;
-        case SkSLType::kHalf3x3:
-            return 24;
-        case SkSLType::kHalf4x4:
-            return 32;
-
-        // This query is only valid for certain types.
-        case SkSLType::kVoid:
-        case SkSLType::kBool:
-        case SkSLType::kBool2:
-        case SkSLType::kBool3:
-        case SkSLType::kBool4:
-        case SkSLType::kTexture2DSampler:
-        case SkSLType::kTextureExternalSampler:
-        case SkSLType::kTexture2DRectSampler:
-        case SkSLType::kSampler:
-        case SkSLType::kTexture2D:
-        case SkSLType::kInput:
-            break;
-    }
-    SK_ABORT("Unexpected type");
-}
-
 // Given the current offset into the ubo, calculate the offset for the uniform we're trying to add
-// taking into consideration all alignment requirements. The uniformOffset is set to the offset for
-// the new uniform, and currentOffset is updated to be the offset to the end of the new uniform.
-static uint32_t get_ubo_aligned_offset(uint32_t* currentOffset,
-                                       SkSLType type,
-                                       int arrayCount) {
+// taking into consideration all alignment requirements. Returns the aligned start offset for the
+// new uniform.
+static uint32_t get_ubo_aligned_offset(uint32_t currentOffset, SkSLType type, int arrayCount) {
     uint32_t alignmentMask = sksltype_to_alignment_mask(type);
-    uint32_t offsetDiff = *currentOffset & alignmentMask;
+    uint32_t offsetDiff = currentOffset & alignmentMask;
     if (offsetDiff != 0) {
         offsetDiff = alignmentMask - offsetDiff + 1;
     }
-    uint32_t uniformOffset = *currentOffset + offsetDiff;
-
-    if (arrayCount) {
-        // TODO(skia:13478): array size calculations currently do not honor std140 layout.
-        *currentOffset = uniformOffset + sksltype_to_size(type) * arrayCount;
-    } else {
-        *currentOffset = uniformOffset + sksltype_to_size(type);
-    }
-    return uniformOffset;
+    return currentOffset + offsetDiff;
 }
 
 SkSLType UniformOffsetCalculator::getUniformTypeForLayout(SkSLType type) {
@@ -516,10 +446,7 @@
 }
 
 UniformOffsetCalculator::UniformOffsetCalculator(Layout layout, uint32_t startingOffset)
-        : fLayout(layout)
-        , fOffset(startingOffset)
-        , fCurUBOOffset(startingOffset) {
-
+        : fLayout(layout), fOffset(startingOffset) {
     switch (layout) {
         case Layout::kStd140:
             fWriteUniform = Writer<Rules140>::WriteUniform;
@@ -533,11 +460,11 @@
     }
 }
 
-size_t UniformOffsetCalculator::calculateOffset(SkSLType type, unsigned int count) {
+size_t UniformOffsetCalculator::advanceOffset(SkSLType type, unsigned int count) {
     SkSLType revisedType = this->getUniformTypeForLayout(type);
 
     // Insert padding as needed to get the correct uniform alignment.
-    uint32_t alignedOffset = get_ubo_aligned_offset(&fCurUBOOffset, revisedType, count);
+    uint32_t alignedOffset = get_ubo_aligned_offset(fOffset, revisedType, count);
     SkASSERT(alignedOffset >= fOffset);
 
     // Append the uniform size to our offset, then return the uniform start position.
@@ -556,14 +483,12 @@
 }
 
 void UniformManager::reset() {
-    fCurUBOOffset = 0;
     fOffset = 0;
     fReqAlignment = 0;
     fStorage.clear();
 }
 
 void UniformManager::checkReset() const {
-    SkASSERT(fCurUBOOffset == 0);
     SkASSERT(fOffset == 0);
     SkASSERT(fStorage.empty());
 }
@@ -593,20 +518,19 @@
 
     SkSLType revisedType = this->getUniformTypeForLayout(type);
 
-    // Insert padding as needed to get the correct uniform alignment.
-    uint32_t alignedOffset = get_ubo_aligned_offset(&fCurUBOOffset, revisedType, count);
-    SkASSERT(alignedOffset >= fOffset);
-    if (alignedOffset > fOffset) {
-        fStorage.append(alignedOffset - fOffset);
-        fOffset = alignedOffset;
-    }
+    const uint32_t startOffset = fOffset;
+    const uint32_t alignedStartOffset = this->advanceOffset(revisedType, count);
+    SkASSERT(fOffset > alignedStartOffset);  // `fOffset` now equals the total bytes to be written
+    const uint32_t bytesNeeded = fOffset - alignedStartOffset;
 
-    uint32_t bytesNeeded = fWriteUniform(revisedType, CType::kDefault,
-                                         /*dest=*/nullptr, count, /*src=*/nullptr);
+    // Insert padding if needed.
+    if (alignedStartOffset > startOffset) {
+        fStorage.append(alignedStartOffset - startOffset);
+    }
     char* dst = fStorage.append(bytesNeeded);
-    uint32_t bytesWritten = fWriteUniform(revisedType, CType::kDefault, dst, count, src);
+    [[maybe_unused]] uint32_t bytesWritten =
+            fWriteUniform(revisedType, CType::kDefault, dst, count, src);
     SkASSERT(bytesNeeded == bytesWritten);
-    fOffset += bytesWritten;
 
     fReqAlignment = std::max(fReqAlignment, sksltype_to_alignment_mask(revisedType) + 1);
 }
diff --git a/src/gpu/graphite/UniformManager.h b/src/gpu/graphite/UniformManager.h
index 3f144ef..feb2023 100644
--- a/src/gpu/graphite/UniformManager.h
+++ b/src/gpu/graphite/UniformManager.h
@@ -35,9 +35,15 @@
 public:
     UniformOffsetCalculator(Layout layout, uint32_t startingOffset);
 
-    size_t size() const { return fCurUBOOffset; }
+    size_t size() const { return fOffset; }
 
-    size_t calculateOffset(SkSLType type, unsigned int count);
+    // Calculates the correctly aligned offset to accommodate `count` instances of `type` and
+    // advances the internal offset. Returns the correctly aligned start offset.
+    //
+    // After a call to this method, `size()` will return the offset to the end of `count` instances
+    // of `type` (while the return value equals the aligned start offset). Subsequent calls will
+    // calculate the new start offset starting at `size()`.
+    size_t advanceOffset(SkSLType type, unsigned int count);
 
 protected:
     SkSLType getUniformTypeForLayout(SkSLType type);
@@ -51,7 +57,6 @@
     WriteUniformFn fWriteUniform;
     Layout fLayout;  // TODO: eventually 'fLayout' will not need to be stored
     uint32_t fOffset = 0;
-    uint32_t fCurUBOOffset = 0;
 };
 
 class UniformManager : public UniformOffsetCalculator {
diff --git a/tests/graphite/UniformOffsetCalculatorTest.cpp b/tests/graphite/UniformOffsetCalculatorTest.cpp
index e7a23c1..cff5e1e 100644
--- a/tests/graphite/UniformOffsetCalculatorTest.cpp
+++ b/tests/graphite/UniformOffsetCalculatorTest.cpp
@@ -26,7 +26,7 @@
     // Set the start offset at 1 to force alignment.
     constexpr uint32_t kStart = 1;
     UniformOffsetCalculator calc(layout, kStart);
-    size_t alignment = calc.calculateOffset(type, arrayCount);
+    size_t alignment = calc.advanceOffset(type, arrayCount);
     return {alignment, calc.size() - alignment};
 }