/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/graphite/UniformManager.h"

#include "include/core/SkM44.h"
#include "include/core/SkMatrix.h"
#include "include/private/base/SkAlign.h"
#include "include/private/base/SkTemplates.h"
#include "src/base/SkHalf.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/Uniform.h"

// ensure that these types are the sizes the uniform data is expecting
static_assert(sizeof(int32_t) == 4);
static_assert(sizeof(float) == 4);
static_assert(sizeof(int16_t) == 2);
static_assert(sizeof(SkHalf) == 2);

namespace skgpu::graphite {

//////////////////////////////////////////////////////////////////////////////
template<typename BaseType>
static constexpr size_t tight_vec_size(int vecLength) {
    return sizeof(BaseType) * vecLength;
}

/**
 * From Section 7.6.2.2 "Standard Uniform Block Layout":
 *  1. If the member is a scalar consuming N basic machine units, the base alignment is N.
 *  2. If the member is a two- or four-component vector with components consuming N basic machine
 *     units, the base alignment is 2N or 4N, respectively.
 *  3. If the member is a three-component vector with components consuming N
 *     basic machine units, the base alignment is 4N.
 *  4. If the member is an array of scalars or vectors, the base alignment and array
 *     stride are set to match the base alignment of a single array element, according
 *     to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The
 *     array may have padding at the end; the base offset of the member following
 *     the array is rounded up to the next multiple of the base alignment.
 *  5. If the member is a column-major matrix with C columns and R rows, the
 *     matrix is stored identically to an array of C column vectors with R components each,
 *     according to rule (4).
 *  6. If the member is an array of S column-major matrices with C columns and
 *     R rows, the matrix is stored identically to a row of S × C column vectors
 *     with R components each, according to rule (4).
 *  7. If the member is a row-major matrix with C columns and R rows, the matrix
 *     is stored identically to an array of R row vectors with C components each,
 *     according to rule (4).
 *  8. If the member is an array of S row-major matrices with C columns and R
 *     rows, the matrix is stored identically to a row of S × R row vectors with C
 *    components each, according to rule (4).
 *  9. If the member is a structure, the base alignment of the structure is N, where
 *     N is the largest base alignment value of any of its members, and rounded
 *     up to the base alignment of a vec4. The individual members of this substructure are then
 *     assigned offsets by applying this set of rules recursively,
 *     where the base offset of the first member of the sub-structure is equal to the
 *     aligned offset of the structure. The structure may have padding at the end;
 *     the base offset of the member following the sub-structure is rounded up to
 *     the next multiple of the base alignment of the structure.
 * 10. If the member is an array of S structures, the S elements of the array are laid
 *     out in order, according to rule (9).
 */
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct Rules140 {
    /**
     * For an array of scalars or vectors this returns the stride between array elements. For
     * matrices or arrays of matrices this returns the stride between columns of the matrix. Note
     * that for single (non-array) scalars or vectors we don't require a stride.
     */
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == graphite::Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);
        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return Rules140<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == Uniform::kNonArray) {
            return n * sizeof(BaseType);
        }

        // Rule 4.

        // Alignment of vec4 by Rule 2.
        constexpr size_t kVec4Alignment = tight_vec_size<float>(4);
        size_t kElementAlignment = tight_vec_size<BaseType>(n);
        // Round kElementAlignment up to multiple of kVec4Alignment.
        size_t m = (kElementAlignment + kVec4Alignment - 1) / kVec4Alignment;
        return m * kVec4Alignment;
    }
};

/**
 * When using the std430 storage layout, shader storage blocks will be laid out in buffer storage
 * identically to uniform and shader storage blocks using the std140 layout, except that the base
 * alignment and stride of arrays of scalars and vectors in rule 4 and of structures in rule 9 are
 * not rounded up a multiple of the base alignment of a vec4.
 */
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct Rules430 {
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);

        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return Rules430<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == Uniform::kNonArray) {
            return n * sizeof(BaseType);
        }

        // Rule 4 without the round up to a multiple of align-of vec4.
        return tight_vec_size<BaseType>(n);
    }
};

// The strides used here were derived from the rules we've imposed on ourselves in
// GrMtlPipelineStateDataManger. Everything is tight except 3-component which have the stride of
// their 4-component equivalents.
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct RulesMetal {
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);

        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return RulesMetal<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == 0) {
            return n * sizeof(BaseType);
        }

        return tight_vec_size<BaseType>(n);
    }
};

template<template<typename BaseType, int RowsOrVecLength, int Cols> class Rules>
class Writer {
private:
    template <typename MemType, typename UniformType>
    static void CopyUniforms(void* dst, const void* src, int numUniforms) {
        if constexpr (std::is_same<MemType, UniformType>::value) {
            // Matching types--use memcpy.
            std::memcpy(dst, src, numUniforms * sizeof(MemType));
            return;
        }

        if constexpr (std::is_same<MemType, float>::value &&
                      std::is_same<UniformType, SkHalf>::value) {
            // Convert floats to half.
            const float* floatBits = static_cast<const float*>(src);
            SkHalf* halfBits = static_cast<SkHalf*>(dst);
            while (numUniforms-- > 0) {
                *halfBits++ = SkFloatToHalf(*floatBits++);
            }
            return;
        }

        if constexpr (std::is_same<MemType, int32_t>::value &&
                      std::is_same<UniformType, int16_t>::value) {
            // Convert ints to short.
            const int32_t* intBits = static_cast<const int32_t*>(src);
            int16_t* shortBits = static_cast<int16_t*>(dst);
            while (numUniforms-- > 0) {
                *shortBits++ = int16_t(*intBits++);
            }
            return;
        }

        SK_ABORT("implement conversion from MemType to UniformType");
    }

    template <typename MemType, typename UniformType, int RowsOrVecLength = 1, int Cols = 1>
    static uint32_t Write(void *dst, int n, const MemType src[]) {
        size_t stride = Rules<UniformType, RowsOrVecLength, Cols>::Stride(n);
        n = (n == Uniform::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);
            } else {
                for (int i = 0; i < n; ++i) {
                    CopyUniforms<MemType, UniformType>(dst, src, RowsOrVecLength);
                    src += RowsOrVecLength;
                    dst = SkTAddOffset<void>(dst, stride);
                }
            }
        }

        return n * stride;
    }

    template <typename UniformType>
    static uint32_t WriteSkMatrices(void *dst, int n, const SkMatrix m[]) {
        // Stride() will give us the stride of each column, so mul by 3 to get matrix stride.
        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) {
                float mt[] = {
                        m[i].get(SkMatrix::kMScaleX),
                        m[i].get(SkMatrix::kMSkewY),
                        m[i].get(SkMatrix::kMPersp0),
                        m[i].get(SkMatrix::kMSkewX),
                        m[i].get(SkMatrix::kMScaleY),
                        m[i].get(SkMatrix::kMPersp1),
                        m[i].get(SkMatrix::kMTransX),
                        m[i].get(SkMatrix::kMTransY),
                        m[i].get(SkMatrix::kMPersp2),
                };
                Write<float, UniformType, 3, 3>(SkTAddOffset<void>(dst, offset), 1, mt);
                offset += stride;
            }
        }
        return n * stride;
    }

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,
                                 int n,
                                 const void *src) {
        SkASSERT(n >= 1 || n == Uniform::kNonArray);
        switch (type) {
            case SkSLType::kShort:
                return Write<int32_t, int16_t>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort2:
                return Write<int32_t, int16_t, 2>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort3:
                return Write<int32_t, int16_t, 3>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort4:
                return Write<int32_t, int16_t, 4>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt:
                return Write<int32_t, int32_t>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt2:
                return Write<int32_t, int32_t, 2>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt3:
                return Write<int32_t, int32_t, 3>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt4:
                return Write<int32_t, int32_t, 4>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kHalf:
                return Write<float, SkHalf>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat:
                return Write<float, float>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf2:
                return Write<float, SkHalf, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat2:
                return Write<float, float, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf3:
                return Write<float, SkHalf, 3>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat3:
                return Write<float, float, 3>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf4:
                return Write<float, SkHalf, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat4:
                return Write<float, float, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf2x2:
                return Write<float, SkHalf, 2, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat2x2:
                return Write<float, float, 2, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf3x3:
                switch (ctype) {
                    case CType::kDefault:
                        return Write<float, SkHalf, 3, 3>(dest, n, static_cast<const float *>(src));
                    case CType::kSkMatrix:
                        return WriteSkMatrices<SkHalf>(dest, n, static_cast<const SkMatrix *>(src));
                }
                SkUNREACHABLE;

            case SkSLType::kFloat3x3:
                switch (ctype) {
                    case CType::kDefault:
                        return Write<float, float, 3, 3>(dest, n, static_cast<const float *>(src));
                    case CType::kSkMatrix:
                        return WriteSkMatrices<float>(dest, n, static_cast<const SkMatrix *>(src));
                }
                SkUNREACHABLE;

            case SkSLType::kHalf4x4:
                return Write<float, SkHalf, 4, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat4x4:
                return Write<float, float, 4, 4>(dest, n, static_cast<const float *>(src));

            default:
                SK_ABORT("Unexpected uniform type");
        }
    }
};

// To determine whether a current offset is aligned, we can just 'and' the lowest bits with the
// alignment mask. A value of 0 means aligned, any other value is how many bytes past alignment we
// are. This works since all alignments are powers of 2. The mask is always (alignment - 1).
static uint32_t sksltype_to_alignment_mask(SkSLType type) {
    switch (type) {
        case SkSLType::kInt:
        case SkSLType::kUInt:
        case SkSLType::kFloat:
            return 0x3;
        case SkSLType::kInt2:
        case SkSLType::kUInt2:
        case SkSLType::kFloat2:
            return 0x7;
        case SkSLType::kInt3:
        case SkSLType::kUInt3:
        case SkSLType::kFloat3:
        case SkSLType::kInt4:
        case SkSLType::kUInt4:
        case SkSLType::kFloat4:
            return 0xF;

        case SkSLType::kFloat2x2:
            return 0x7;
        case SkSLType::kFloat3x3:
            return 0xF;
        case SkSLType::kFloat4x4:
            return 0xF;

        case SkSLType::kShort:
        case SkSLType::kUShort:
        case SkSLType::kHalf:
            return 0x1;
        case SkSLType::kShort2:
        case SkSLType::kUShort2:
        case SkSLType::kHalf2:
            return 0x3;
        case SkSLType::kShort3:
        case SkSLType::kShort4:
        case SkSLType::kUShort3:
        case SkSLType::kUShort4:
        case SkSLType::kHalf3:
        case SkSLType::kHalf4:
            return 0x7;

        case SkSLType::kHalf2x2:
            return 0x3;
        case SkSLType::kHalf3x3:
            return 0x7;
        case SkSLType::kHalf4x4:
            return 0x7;

        // 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. Returns the aligned start offset for the
// new uniform.
static uint32_t get_ubo_aligned_offset(Layout layout,
                                       uint32_t currentOffset,
                                       SkSLType type,
                                       bool isArray) {
    uint32_t alignmentMask;
    if (layout == Layout::kStd140 && isArray) {
        // std140 array element alignment always equals the base alignment of a vec4.
        alignmentMask = sksltype_to_alignment_mask(SkSLType::kFloat4);
    } else {
        alignmentMask = sksltype_to_alignment_mask(type);
    }
    return (currentOffset + alignmentMask) & ~alignmentMask;
}

SkSLType UniformOffsetCalculator::getUniformTypeForLayout(SkSLType type) {
    if (fLayout != Layout::kMetal) {
        // GL/Vk expect uniforms in 32-bit precision. Convert lower-precision types to 32-bit.
        switch (type) {
            case SkSLType::kShort:      return SkSLType::kInt;
            case SkSLType::kUShort:     return SkSLType::kUInt;
            case SkSLType::kHalf:       return SkSLType::kFloat;

            case SkSLType::kShort2:     return SkSLType::kInt2;
            case SkSLType::kUShort2:    return SkSLType::kUInt2;
            case SkSLType::kHalf2:      return SkSLType::kFloat2;

            case SkSLType::kShort3:     return SkSLType::kInt3;
            case SkSLType::kUShort3:    return SkSLType::kUInt3;
            case SkSLType::kHalf3:      return SkSLType::kFloat3;

            case SkSLType::kShort4:     return SkSLType::kInt4;
            case SkSLType::kUShort4:    return SkSLType::kUInt4;
            case SkSLType::kHalf4:      return SkSLType::kFloat4;

            case SkSLType::kHalf2x2:    return SkSLType::kFloat2x2;
            case SkSLType::kHalf3x3:    return SkSLType::kFloat3x3;
            case SkSLType::kHalf4x4:    return SkSLType::kFloat4x4;

            default:                    break;
        }
    }

    return type;
}

void UniformOffsetCalculator::setLayout(Layout layout) {
    fLayout = layout;
    switch (layout) {
        case Layout::kStd140:
            fWriteUniform = Writer<Rules140>::WriteUniform;
            break;
        case Layout::kStd430:
            fWriteUniform = Writer<Rules430>::WriteUniform;
            break;
        case Layout::kMetal:
            fWriteUniform = Writer<RulesMetal>::WriteUniform;
            break;
        case Layout::kInvalid:
            SK_ABORT("Invalid layout type");
            break;
    }
}

UniformOffsetCalculator::UniformOffsetCalculator(Layout layout, uint32_t startingOffset)
        : fLayout(layout), fOffset(startingOffset) {
    this->setLayout(fLayout);
}

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(fLayout,
                                                    fOffset,
                                                    revisedType,
                                                    /*isArray=*/count != Uniform::kNonArray);
    SkASSERT(alignedOffset >= fOffset);

    // Append the uniform size to our offset, then return the uniform start position.
    uint32_t uniformSize = fWriteUniform(revisedType, CType::kDefault,
                                         /*dest=*/nullptr, count, /*src=*/nullptr);
    fOffset = alignedOffset + uniformSize;
    return alignedOffset;
}

UniformDataBlock UniformManager::finishUniformDataBlock() {
    size_t size = SkAlignTo(fStorage.size(), fReqAlignment);
    size_t paddingSize = size - fStorage.size();
    char* padding = fStorage.append(paddingSize);
    memset(padding, 0, paddingSize);
    return UniformDataBlock(SkSpan(fStorage.begin(), size));
}

void UniformManager::resetWithNewLayout(Layout layout) {
    if (layout != fLayout) {
        this->setLayout(layout);
    }
    this->reset();
}

void UniformManager::reset() {
    fOffset = 0;
    fReqAlignment = 0;
    fStorage.clear();
}

void UniformManager::checkReset() const {
    SkASSERT(fOffset == 0);
    SkASSERT(fStorage.empty());
}

void UniformManager::setExpectedUniforms(SkSpan<const Uniform> expectedUniforms) {
    SkDEBUGCODE(fExpectedUniforms = expectedUniforms;)
    SkDEBUGCODE(fExpectedUniformIndex = 0;)
}

void UniformManager::checkExpected(SkSLType type, unsigned int count) {
    SkASSERT(fExpectedUniforms.size());
    SkASSERT(fExpectedUniformIndex >= 0 && fExpectedUniformIndex < (int)fExpectedUniforms.size());

    SkASSERT(fExpectedUniforms[fExpectedUniformIndex].type() == type);
    SkASSERT((fExpectedUniforms[fExpectedUniformIndex].count() == 0 && count == 1) ||
             fExpectedUniforms[fExpectedUniformIndex].count() == count);
    SkDEBUGCODE(fExpectedUniformIndex++;)
}

void UniformManager::doneWithExpectedUniforms() {
    SkASSERT(fExpectedUniformIndex == static_cast<int>(fExpectedUniforms.size()));
    SkDEBUGCODE(fExpectedUniforms = {};)
}

void UniformManager::writeInternal(SkSLType type, unsigned int count, const void* src) {
    SkSLType revisedType = this->getUniformTypeForLayout(type);

    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;

    // Insert padding if needed.
    if (alignedStartOffset > startOffset) {
        fStorage.append(alignedStartOffset - startOffset);
    }
    char* dst = fStorage.append(bytesNeeded);
    [[maybe_unused]] uint32_t bytesWritten =
            fWriteUniform(revisedType, CType::kDefault, dst, count, src);
    SkASSERT(bytesNeeded == bytesWritten);

    fReqAlignment = std::max(fReqAlignment, sksltype_to_alignment_mask(revisedType) + 1);
}

void UniformManager::write(SkSLType type, const void* src) {
    this->checkExpected(type, 1);
    this->writeInternal(type, Uniform::kNonArray, src);
}

void UniformManager::writeArray(SkSLType type, const void* src, unsigned int count) {
    // Don't write any elements if count is 0. Since Uniform::kNonArray == 0, passing count
    // directly would cause a one-element non-array write.
    if (count > 0) {
        this->checkExpected(type, count);
        this->writeInternal(type, count, src);
    }
}

void UniformManager::write(const Uniform& u, const uint8_t* src) {
    this->checkExpected(u.type(), (u.count() == Uniform::kNonArray) ? 1 : u.count());
    this->writeInternal(u.type(), u.count(), src);
}

void UniformManager::write(const SkM44& mat) {
    static constexpr SkSLType kType = SkSLType::kFloat4x4;
    this->write(kType, &mat);
}

void UniformManager::write(const SkPMColor4f& color) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &color);
}

void UniformManager::write(const SkRect& rect) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &rect);
}

void UniformManager::write(const SkPoint& point) {
    static constexpr SkSLType kType = SkSLType::kFloat2;
    this->write(kType, &point);
}

void UniformManager::write(float f) {
    static constexpr SkSLType kType = SkSLType::kFloat;
    this->write(kType, &f);
}

void UniformManager::write(int i) {
    static constexpr SkSLType kType = SkSLType::kInt;
    this->write(kType, &i);
}

void UniformManager::write(const SkV2& v) {
    static constexpr SkSLType kType = SkSLType::kFloat2;
    this->write(kType, &v);
}

void UniformManager::write(const SkV4& v) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &v);
}

void UniformManager::writeArray(SkSpan<const SkColor4f> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeArray(SkSpan<const SkPMColor4f> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeArray(SkSpan<const float> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeHalf(const SkMatrix& mat) {
    static constexpr SkSLType kType = SkSLType::kHalf3x3;
    this->write(kType, &mat);
}

void UniformManager::writeHalfArray(SkSpan<const float> arr) {
    static constexpr SkSLType kType = SkSLType::kHalf;
    this->writeArray(kType, arr.data(), arr.size());
}

} // namespace skgpu::graphite
