Metal: Fix buffer alignment issues on Mac

Bug: skia:8243
Change-Id: I9d588c732e9aba2348a294cd88f17d261ba05f03
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255088
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/mtl/GrMtlBuffer.mm b/src/gpu/mtl/GrMtlBuffer.mm
index fe585fc..304da54 100644
--- a/src/gpu/mtl/GrMtlBuffer.mm
+++ b/src/gpu/mtl/GrMtlBuffer.mm
@@ -41,6 +41,11 @@
         if (@available(macOS 10.11, iOS 9.0, *)) {
             options |= MTLResourceStorageModePrivate;
         }
+#ifdef SK_BUILD_FOR_MAC
+        // Mac requires 4-byte alignment for copies so we need
+        // to ensure we have space for the extra data
+        size = GrSizeAlignUp(size, 4);
+#endif
         fMtlBuffer = size == 0 ? nil :
                 [gpu->device() newBufferWithLength: size
                                            options: options];
@@ -77,7 +82,7 @@
     }
     SkASSERT(fMappedBuffer);
     if (!fIsDynamic) {
-        SkASSERT(srcInBytes == fMappedBuffer.length);
+        SkASSERT(GrSizeAlignUp(srcInBytes, 4) == fMappedBuffer.length);
     }
     memcpy(fMapPtr, src, srcInBytes);
     this->internalUnmap(srcInBytes);
@@ -129,6 +134,10 @@
         if (@available(macOS 10.11, iOS 9.0, *)) {
             options |= MTLResourceStorageModeShared;
         }
+#ifdef SK_BUILD_FOR_MAC
+        // Mac requires 4-byte alignment for copies so we pad this out
+        sizeInBytes = GrSizeAlignUp(sizeInBytes, 4);
+#endif
         fMappedBuffer =
                 [this->mtlGpu()->device() newBufferWithLength: sizeInBytes
                                                       options: options];
@@ -149,9 +158,13 @@
         fMapPtr = nullptr;
         return;
     }
+#ifdef SK_BUILD_FOR_MAC
+    // In both cases the size needs to be 4-byte aligned on Mac
+    sizeInBytes = GrSizeAlignUp(sizeInBytes, 4);
+#endif
     if (fIsDynamic) {
 #ifdef SK_BUILD_FOR_MAC
-        // TODO: need to make sure offset and size have valid alignments.
+        SkASSERT(0 == (fOffset & 0x3));  // should be 4-byte aligned
         [fMtlBuffer didModifyRange: NSMakeRange(fOffset, sizeInBytes)];
 #endif
     } else {
diff --git a/src/gpu/mtl/GrMtlResourceProvider.mm b/src/gpu/mtl/GrMtlResourceProvider.mm
index 2aecb4c..bb5b75f 100644
--- a/src/gpu/mtl/GrMtlResourceProvider.mm
+++ b/src/gpu/mtl/GrMtlResourceProvider.mm
@@ -262,6 +262,10 @@
 }
 
 id<MTLBuffer> GrMtlResourceProvider::getDynamicBuffer(size_t size, size_t* offset) {
+#ifdef SK_BUILD_FOR_MAC
+    // Mac requires 4-byte alignment for didModifyRange:
+    size = GrSizeAlignUp(size, 4);
+#endif
     id<MTLBuffer> buffer = fBufferSuballocator->getAllocation(size, offset);
     if (buffer) {
         return buffer;