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

#include "src/gpu/mtl/GrMtlGpu.h"

#include "include/private/GrTypesPriv.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkMipmap.h"
#include "src/gpu/GrBackendUtils.h"
#include "src/gpu/GrDataUtils.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrThreadSafePipelineBuilder.h"
#include "src/gpu/mtl/GrMtlBuffer.h"
#include "src/gpu/mtl/GrMtlCommandBuffer.h"
#include "src/gpu/mtl/GrMtlOpsRenderPass.h"
#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
#include "src/gpu/mtl/GrMtlRenderCommandEncoder.h"
#include "src/gpu/mtl/GrMtlSemaphore.h"
#include "src/gpu/mtl/GrMtlTexture.h"
#include "src/gpu/mtl/GrMtlTextureRenderTarget.h"
#include "src/gpu/mtl/GrMtlUtil.h"

#import <simd/simd.h>

#if !__has_feature(objc_arc)
#error This file must be compiled with Arc. Use -fobjc-arc flag
#endif

GR_NORETAIN_BEGIN

static bool get_feature_set(id<MTLDevice> device, MTLFeatureSet* featureSet) {
    // Mac OSX
#ifdef SK_BUILD_FOR_MAC
    if (@available(macOS 10.12, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_OSX_GPUFamily1_v2]) {
            *featureSet = MTLFeatureSet_OSX_GPUFamily1_v2;
            return true;
        }
    }
    if ([device supportsFeatureSet:MTLFeatureSet_OSX_GPUFamily1_v1]) {
        *featureSet = MTLFeatureSet_OSX_GPUFamily1_v1;
        return true;
    }
#endif

    // iOS Family group 3
#ifdef SK_BUILD_FOR_IOS
    if (@available(iOS 10.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily3_v2;
            return true;
        }
    }
    if (@available(iOS 9.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily3_v1;
            return true;
        }
    }

    // iOS Family group 2
    if (@available(iOS 10.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v3]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily2_v3;
            return true;
        }
    }
    if (@available(iOS 9.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v2]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily2_v2;
            return true;
        }
    }
    if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]) {
        *featureSet = MTLFeatureSet_iOS_GPUFamily2_v1;
        return true;
    }

    // iOS Family group 1
    if (@available(iOS 10.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v3]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily1_v3;
            return true;
        }
    }
    if (@available(iOS 9.0, *)) {
        if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v2]) {
            *featureSet = MTLFeatureSet_iOS_GPUFamily1_v2;
            return true;
        }
    }
    if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v1]) {
        *featureSet = MTLFeatureSet_iOS_GPUFamily1_v1;
        return true;
    }
#endif
    // No supported feature sets were found
    return false;
}

sk_sp<GrGpu> GrMtlGpu::Make(const GrMtlBackendContext& context, const GrContextOptions& options,
                            GrDirectContext* direct) {
    if (!context.fDevice || !context.fQueue) {
        return nullptr;
    }
    if (@available(macOS 10.14, iOS 10.0, *)) {
        // no warning needed
    } else {
        SkDebugf("*** Error ***: Skia's Metal backend no longer supports this OS version.\n");
#ifdef SK_BUILD_FOR_IOS
        SkDebugf("Minimum supported version is iOS 10.0.\n");
#else
        SkDebugf("Minimum supported version is MacOS 10.14.\n");
#endif
        return nullptr;
    }

    id<MTLDevice> GR_NORETAIN device = (__bridge id<MTLDevice>)(context.fDevice.get());
    id<MTLCommandQueue> GR_NORETAIN queue = (__bridge id<MTLCommandQueue>)(context.fQueue.get());


    MTLFeatureSet featureSet;
    if (!get_feature_set(device, &featureSet)) {
        return nullptr;
    }
    return sk_sp<GrGpu>(new GrMtlGpu(direct, options, device, queue, context.fBinaryArchive.get(),
                                     featureSet));
}

// This constant determines how many OutstandingCommandBuffers are allocated together as a block in
// the deque. As such it needs to balance allocating too much memory vs. incurring
// allocation/deallocation thrashing. It should roughly correspond to the max number of outstanding
// command buffers we expect to see.
static const int kDefaultOutstandingAllocCnt = 8;

GrMtlGpu::GrMtlGpu(GrDirectContext* direct, const GrContextOptions& options,
                   id<MTLDevice> device, id<MTLCommandQueue> queue, GrMTLHandle binaryArchive,
                   MTLFeatureSet featureSet)
        : INHERITED(direct)
        , fDevice(device)
        , fQueue(queue)
        , fOutstandingCommandBuffers(sizeof(OutstandingCommandBuffer), kDefaultOutstandingAllocCnt)
        , fResourceProvider(this)
        , fStagingBufferManager(this)
        , fUniformsRingBuffer(this, 128 * 1024, 256, GrGpuBufferType::kVertex)
        , fDisconnected(false) {
    fMtlCaps.reset(new GrMtlCaps(options, fDevice, featureSet));
    this->initCapsAndCompiler(fMtlCaps);
    fCurrentCmdBuffer = GrMtlCommandBuffer::Make(fQueue);
#if GR_METAL_SDK_VERSION >= 230
    if (@available(macOS 11.0, iOS 14.0, *)) {
        fBinaryArchive = (__bridge id<MTLBinaryArchive>)(binaryArchive);
    }
#endif
}

GrMtlGpu::~GrMtlGpu() {
    if (!fDisconnected) {
        this->destroyResources();
    }
}

void GrMtlGpu::disconnect(DisconnectType type) {
    INHERITED::disconnect(type);

    if (!fDisconnected) {
        this->destroyResources();
        fDisconnected = true;
    }
}

GrThreadSafePipelineBuilder* GrMtlGpu::pipelineBuilder() {
    return nullptr;
}

sk_sp<GrThreadSafePipelineBuilder> GrMtlGpu::refPipelineBuilder() {
    return nullptr;
}

void GrMtlGpu::destroyResources() {
    this->submitCommandBuffer(SyncQueue::kForce_SyncQueue);

    // We used a placement new for each object in fOutstandingCommandBuffers, so we're responsible
    // for calling the destructor on each of them as well.
    while (!fOutstandingCommandBuffers.empty()) {
        OutstandingCommandBuffer* buffer =
                (OutstandingCommandBuffer*)fOutstandingCommandBuffers.front();
        // make sure we remove before deleting as deletion might try to kick off another submit
        fOutstandingCommandBuffers.pop_front();
        buffer->~OutstandingCommandBuffer();
    }

    fStagingBufferManager.reset();

    fResourceProvider.destroyResources();

    fQueue = nil;
    fDevice = nil;
}

GrOpsRenderPass* GrMtlGpu::onGetOpsRenderPass(
            GrRenderTarget* renderTarget, bool /*useMSAASurface*/, GrAttachment*,
            GrSurfaceOrigin origin, const SkIRect& bounds,
            const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
            const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
            const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
            GrXferBarrierFlags renderPassXferBarriers) {
    return new GrMtlOpsRenderPass(this, renderTarget, origin, colorInfo, stencilInfo);
}

GrMtlCommandBuffer* GrMtlGpu::commandBuffer() {
    if (!fCurrentCmdBuffer) {
        // Create a new command buffer for the next submit
        fCurrentCmdBuffer = GrMtlCommandBuffer::Make(fQueue);
    }

    SkASSERT(fCurrentCmdBuffer);
    return fCurrentCmdBuffer.get();
}

void GrMtlGpu::takeOwnershipOfBuffer(sk_sp<GrGpuBuffer> buffer) {
    SkASSERT(buffer);
    this->commandBuffer()->addGrBuffer(std::move(buffer));
}

void GrMtlGpu::submit(GrOpsRenderPass* renderPass) {
    GrMtlOpsRenderPass* mtlRenderPass = reinterpret_cast<GrMtlOpsRenderPass*>(renderPass);
    mtlRenderPass->submit();
    delete renderPass;
}

bool GrMtlGpu::submitCommandBuffer(SyncQueue sync) {
    if (!fCurrentCmdBuffer || !fCurrentCmdBuffer->hasWork()) {
        if (sync == SyncQueue::kForce_SyncQueue) {
            this->finishOutstandingGpuWork();
            this->checkForFinishedCommandBuffers();
        }
        // We need to manually call the finishedCallbacks since we don't add this
        // to the OutstandingCommandBuffer list
        if (fCurrentCmdBuffer) {
            fCurrentCmdBuffer->callFinishedCallbacks();
        }
        return true;
    }

    SkASSERT(fCurrentCmdBuffer);
    new (fOutstandingCommandBuffers.push_back()) OutstandingCommandBuffer(fCurrentCmdBuffer);

    if (!fCurrentCmdBuffer->commit(sync == SyncQueue::kForce_SyncQueue)) {
        return false;
    }

    // We don't create a new command buffer here because we may end up using it
    // in the next frame, and that confuses the GPU debugger. Instead we
    // create when we next need one.
    fCurrentCmdBuffer = nullptr;

    // If the freeing of any resources held by a finished command buffer causes us to send
    // a new command to the gpu (like changing the resource state) we'll create the new
    // command buffer in commandBuffer(), above.
    this->checkForFinishedCommandBuffers();

    return true;
}

void GrMtlGpu::checkForFinishedCommandBuffers() {
    // Iterate over all the outstanding command buffers to see if any have finished. The command
    // buffers are in order from oldest to newest, so we start at the front to check if their fence
    // has signaled. If so we pop it off and move onto the next.
    // Repeat till we find a command list that has not finished yet (and all others afterwards are
    // also guaranteed to not have finished).
    OutstandingCommandBuffer* front = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.front();
    while (front && (*front)->isCompleted()) {
        // Make sure we remove before deleting as deletion might try to kick off another submit
        fOutstandingCommandBuffers.pop_front();
        // Since we used placement new we are responsible for calling the destructor manually.
        front->~OutstandingCommandBuffer();
        front = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.front();
    }
}

void GrMtlGpu::finishOutstandingGpuWork() {
    // wait for the last command buffer we've submitted to finish
    OutstandingCommandBuffer* back =
            (OutstandingCommandBuffer*)fOutstandingCommandBuffers.back();
    if (back) {
        (*back)->waitUntilCompleted();
    }
}

void GrMtlGpu::addFinishedProc(GrGpuFinishedProc finishedProc,
                               GrGpuFinishedContext finishedContext) {
    SkASSERT(finishedProc);
    this->addFinishedCallback(GrRefCntedCallback::Make(finishedProc, finishedContext));
}

void GrMtlGpu::addFinishedCallback(sk_sp<GrRefCntedCallback> finishedCallback) {
    SkASSERT(finishedCallback);
    // Besides the current commandbuffer, we also add the finishedCallback to the newest outstanding
    // commandbuffer. Our contract for calling the proc is that all previous submitted cmdbuffers
    // have finished when we call it. However, if our current command buffer has no work when it is
    // flushed it will drop its ref to the callback immediately. But the previous work may not have
    // finished. It is safe to only add the proc to the newest outstanding commandbuffer cause that
    // must finish after all previously submitted command buffers.
    OutstandingCommandBuffer* back = (OutstandingCommandBuffer*)fOutstandingCommandBuffers.back();
    if (back) {
        (*back)->addFinishedCallback(finishedCallback);
    }
    commandBuffer()->addFinishedCallback(std::move(finishedCallback));
}

bool GrMtlGpu::onSubmitToGpu(bool syncCpu) {
    if (syncCpu) {
        return this->submitCommandBuffer(kForce_SyncQueue);
    } else {
        return this->submitCommandBuffer(kSkip_SyncQueue);
    }
}

std::unique_ptr<GrSemaphore> GrMtlGpu::prepareTextureForCrossContextUsage(GrTexture*) {
    this->submitToGpu(false);
    return nullptr;
}

sk_sp<GrGpuBuffer> GrMtlGpu::onCreateBuffer(size_t size, GrGpuBufferType type,
                                            GrAccessPattern accessPattern, const void* data) {
    return GrMtlBuffer::Make(this, size, type, accessPattern, data);
}

static bool check_max_blit_width(int widthInPixels) {
    if (widthInPixels > 32767) {
        SkASSERT(false); // surfaces should not be this wide anyway
        return false;
    }
    return true;
}

bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex,
                               SkIRect rect,
                               GrColorType dataColorType,
                               const GrMipLevel texels[],
                               int mipLevelCount) {
    SkASSERT(this->caps()->isFormatTexturable(tex->backendFormat()));
    // The assumption is either that we have no mipmaps, or that our rect is the entire texture
    SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(tex->dimensions()));

    // We assume that if the texture has mip levels, we either upload to all the levels or just the
    // first.
    SkASSERT(mipLevelCount == 1 || mipLevelCount == (tex->maxMipmapLevel() + 1));

    if (!check_max_blit_width(rect.width())) {
        return false;
    }
    if (rect.isEmpty()) {
        return false;
    }

    SkASSERT(this->mtlCaps().surfaceSupportsWritePixels(tex));
    SkASSERT(this->mtlCaps().areColorTypeAndFormatCompatible(dataColorType, tex->backendFormat()));

    id<MTLTexture> GR_NORETAIN mtlTexture = tex->mtlTexture();
    SkASSERT(mtlTexture);
    // Either upload only the first miplevel or all miplevels
    SkASSERT(1 == mipLevelCount || mipLevelCount == (int)mtlTexture.mipmapLevelCount);

    if (mipLevelCount == 1 && !texels[0].fPixels) {
        return true;   // no data to upload
    }

    for (int i = 0; i < mipLevelCount; ++i) {
        // We do not allow any gaps in the mip data
        if (!texels[i].fPixels) {
            return false;
        }
    }

    size_t bpp = GrColorTypeBytesPerPixel(dataColorType);

    SkTArray<size_t> individualMipOffsets(mipLevelCount);
    size_t combinedBufferSize = GrComputeTightCombinedBufferSize(bpp,
                                                                 rect.size(),
                                                                 &individualMipOffsets,
                                                                 mipLevelCount);
    SkASSERT(combinedBufferSize);


    // offset value must be a multiple of the destination texture's pixel size in bytes
#ifdef SK_BUILD_FOR_MAC
    static const size_t kMinAlignment = 4;
#else
    static const size_t kMinAlignment = 1;
#endif
    size_t alignment = std::max(bpp, kMinAlignment);
    GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
            combinedBufferSize, alignment);
    if (!slice.fBuffer) {
        return false;
    }
    char* bufferData = (char*)slice.fOffsetMapPtr;
    GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);

    int currentWidth = rect.width();
    int currentHeight = rect.height();
    int layerHeight = tex->height();
    MTLOrigin origin = MTLOriginMake(rect.left(), rect.top(), 0);

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
        if (texels[currentMipLevel].fPixels) {
            SkASSERT(1 == mipLevelCount || currentHeight == layerHeight);
            const size_t trimRowBytes = currentWidth * bpp;
            const size_t rowBytes = texels[currentMipLevel].fRowBytes;

            // copy data into the buffer, skipping any trailing bytes
            char* dst = bufferData + individualMipOffsets[currentMipLevel];
            const char* src = (const char*)texels[currentMipLevel].fPixels;
            SkRectMemcpy(dst, trimRowBytes, src, rowBytes, trimRowBytes, currentHeight);

            [blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
                              sourceOffset: slice.fOffset + individualMipOffsets[currentMipLevel]
                         sourceBytesPerRow: trimRowBytes
                       sourceBytesPerImage: trimRowBytes*currentHeight
                                sourceSize: MTLSizeMake(currentWidth, currentHeight, 1)
                                 toTexture: mtlTexture
                          destinationSlice: 0
                          destinationLevel: currentMipLevel
                         destinationOrigin: origin];
        }
        currentWidth = std::max(1, currentWidth/2);
        currentHeight = std::max(1, currentHeight/2);
        layerHeight = currentHeight;
    }
#ifdef SK_BUILD_FOR_MAC
    [mtlBuffer->mtlBuffer() didModifyRange: NSMakeRange(slice.fOffset, combinedBufferSize)];
#endif

    if (mipLevelCount < (int) tex->mtlTexture().mipmapLevelCount) {
        tex->markMipmapsDirty();
    }

    return true;
}

bool GrMtlGpu::clearTexture(GrMtlTexture* tex, size_t bpp, uint32_t levelMask) {
    SkASSERT(this->mtlCaps().isFormatTexturable(tex->backendFormat()));

    if (!levelMask) {
        return true;
    }

    id<MTLTexture> GR_NORETAIN mtlTexture = tex->mtlTexture();
    SkASSERT(mtlTexture);
    // Either upload only the first miplevel or all miplevels
    int mipLevelCount = (int)mtlTexture.mipmapLevelCount;

    SkTArray<size_t> individualMipOffsets(mipLevelCount);
    size_t combinedBufferSize = 0;
    int currentWidth = tex->width();
    int currentHeight = tex->height();

    // The alignment must be at least 4 bytes and a multiple of the bytes per pixel of the image
    // config. This works with the assumption that the bytes in pixel config is always a power of 2.
    // TODO: can we just copy from a single buffer the size of the largest cleared level w/o a perf
    // penalty?
    SkASSERT((bpp & (bpp - 1)) == 0);
    const size_t alignmentMask = 0x3 | (bpp - 1);
    for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
        if (levelMask & (1 << currentMipLevel)) {
            const size_t trimmedSize = currentWidth * bpp * currentHeight;
            const size_t alignmentDiff = combinedBufferSize & alignmentMask;
            if (alignmentDiff != 0) {
                combinedBufferSize += alignmentMask - alignmentDiff + 1;
            }
            individualMipOffsets.push_back(combinedBufferSize);
            combinedBufferSize += trimmedSize;
        }
        currentWidth = std::max(1, currentWidth/2);
        currentHeight = std::max(1, currentHeight/2);
    }
    SkASSERT(combinedBufferSize > 0 && !individualMipOffsets.empty());

    // TODO: Create GrMtlTransferBuffer
    NSUInteger options = 0;
    if (@available(macOS 10.11, iOS 9.0, *)) {
        options |= MTLResourceStorageModePrivate;
    }
    id<MTLBuffer> transferBuffer = [fDevice newBufferWithLength: combinedBufferSize
                                                        options: options];
    if (nil == transferBuffer) {
        return false;
    }

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    // clear the buffer to transparent black
    NSRange clearRange;
    clearRange.location = 0;
    clearRange.length = combinedBufferSize;
    [blitCmdEncoder fillBuffer: transferBuffer
                         range: clearRange
                         value: 0];

    // now copy buffer to texture
    currentWidth = tex->width();
    currentHeight = tex->height();
    MTLOrigin origin = MTLOriginMake(0, 0, 0);
    for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
        if (levelMask & (1 << currentMipLevel)) {
            const size_t rowBytes = currentWidth * bpp;

            [blitCmdEncoder copyFromBuffer: transferBuffer
                              sourceOffset: individualMipOffsets[currentMipLevel]
                         sourceBytesPerRow: rowBytes
                       sourceBytesPerImage: rowBytes * currentHeight
                                sourceSize: MTLSizeMake(currentWidth, currentHeight, 1)
                                 toTexture: mtlTexture
                          destinationSlice: 0
                          destinationLevel: currentMipLevel
                         destinationOrigin: origin];
        }
        currentWidth = std::max(1, currentWidth/2);
        currentHeight = std::max(1, currentHeight/2);
    }

    if (mipLevelCount < (int) tex->mtlTexture().mipmapLevelCount) {
        tex->markMipmapsDirty();
    }

    return true;
}

sk_sp<GrAttachment> GrMtlGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
                                                    SkISize dimensions, int numStencilSamples) {
    MTLPixelFormat sFmt = this->mtlCaps().preferredStencilFormat();

    fStats.incStencilAttachmentCreates();
    return GrMtlAttachment::GrMtlAttachment::MakeStencil(this, dimensions, numStencilSamples, sFmt);
}

sk_sp<GrTexture> GrMtlGpu::onCreateTexture(SkISize dimensions,
                                           const GrBackendFormat& format,
                                           GrRenderable renderable,
                                           int renderTargetSampleCnt,
                                           SkBudgeted budgeted,
                                           GrProtected isProtected,
                                           int mipLevelCount,
                                           uint32_t levelClearMask) {
    // We don't support protected textures in Metal.
    if (isProtected == GrProtected::kYes) {
        return nullptr;
    }
    SkASSERT(mipLevelCount > 0);

    MTLPixelFormat mtlPixelFormat = GrBackendFormatAsMTLPixelFormat(format);
    SkASSERT(mtlPixelFormat != MTLPixelFormatInvalid);
    SkASSERT(!this->caps()->isFormatCompressed(format));

    sk_sp<GrMtlTexture> tex;
    // This TexDesc refers to the texture that will be read by the client. Thus even if msaa is
    // requested, this TexDesc describes the resolved texture. Therefore we always have samples
    // set to 1.
    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
    texDesc.textureType = MTLTextureType2D;
    texDesc.pixelFormat = mtlPixelFormat;
    texDesc.width = dimensions.fWidth;
    texDesc.height = dimensions.fHeight;
    texDesc.depth = 1;
    texDesc.mipmapLevelCount = mipLevelCount;
    texDesc.sampleCount = 1;
    texDesc.arrayLength = 1;
    // Make all textures have private gpu only access. We can use transfer buffers or textures
    // to copy to them.
    if (@available(macOS 10.11, iOS 9.0, *)) {
        texDesc.storageMode = MTLStorageModePrivate;
        texDesc.usage = MTLTextureUsageShaderRead;
        texDesc.usage |= (renderable == GrRenderable::kYes) ? MTLTextureUsageRenderTarget : 0;
    }

    GrMipmapStatus mipmapStatus =
            mipLevelCount > 1 ? GrMipmapStatus::kDirty : GrMipmapStatus::kNotAllocated;
    if (renderable == GrRenderable::kYes) {
        tex = GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(
                this, budgeted, dimensions, renderTargetSampleCnt, texDesc, mipmapStatus);
    } else {
        tex = GrMtlTexture::MakeNewTexture(this, budgeted, dimensions, texDesc, mipmapStatus);
    }

    if (!tex) {
        return nullptr;
    }

    if (levelClearMask) {
        this->clearTexture(tex.get(), GrMtlFormatBytesPerBlock(mtlPixelFormat), levelClearMask);
    }

    return std::move(tex);
}

sk_sp<GrTexture> GrMtlGpu::onCreateCompressedTexture(SkISize dimensions,
                                                     const GrBackendFormat& format,
                                                     SkBudgeted budgeted,
                                                     GrMipmapped mipMapped,
                                                     GrProtected isProtected,
                                                     const void* data, size_t dataSize) {
    // We don't support protected textures in Metal.
    if (isProtected == GrProtected::kYes) {
        return nullptr;
    }

    SkASSERT(this->caps()->isFormatTexturable(format));
    SkASSERT(data);

    if (!check_max_blit_width(dimensions.width())) {
        return nullptr;
    }

    MTLPixelFormat mtlPixelFormat = GrBackendFormatAsMTLPixelFormat(format);
    SkASSERT(this->caps()->isFormatCompressed(format));

    int numMipLevels = 1;
    if (mipMapped == GrMipmapped::kYes) {
        numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
    }

    // This TexDesc refers to the texture that will be read by the client. Thus even if msaa is
    // requested, this TexDesc describes the resolved texture. Therefore we always have samples
    // set to 1.
    // Compressed textures with MIP levels or multiple samples are not supported as of now.
    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
    texDesc.textureType = MTLTextureType2D;
    texDesc.pixelFormat = mtlPixelFormat;
    texDesc.width = dimensions.width();
    texDesc.height = dimensions.height();
    texDesc.depth = 1;
    texDesc.mipmapLevelCount = numMipLevels;
    texDesc.sampleCount = 1;
    texDesc.arrayLength = 1;
    // Make all textures have private gpu only access. We can use transfer buffers or textures
    // to copy to them.
    if (@available(macOS 10.11, iOS 9.0, *)) {
        texDesc.storageMode = MTLStorageModePrivate;
        texDesc.usage = MTLTextureUsageShaderRead;
    }

    GrMipmapStatus mipmapStatus = (mipMapped == GrMipmapped::kYes)
                                                                ? GrMipmapStatus::kValid
                                                                : GrMipmapStatus::kNotAllocated;

    auto tex = GrMtlTexture::MakeNewTexture(this, budgeted, dimensions, texDesc, mipmapStatus);
    if (!tex) {
        return nullptr;
    }

    // Upload to texture
    id<MTLTexture> GR_NORETAIN mtlTexture = tex->mtlTexture();
    SkASSERT(mtlTexture);

    auto compressionType = GrBackendFormatToCompressionType(format);
    SkASSERT(compressionType != SkImage::CompressionType::kNone);

    SkTArray<size_t> individualMipOffsets(numMipLevels);
    SkDEBUGCODE(size_t combinedBufferSize =) SkCompressedDataSize(compressionType, dimensions,
                                                                  &individualMipOffsets,
                                                                  mipMapped == GrMipmapped::kYes);
    SkASSERT(individualMipOffsets.count() == numMipLevels);
    SkASSERT(dataSize == combinedBufferSize);

    // offset value must be a multiple of the destination texture's pixel size in bytes
    // for compressed textures, this is the block size
    size_t alignment = SkCompressedBlockSize(compressionType);
    GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
            dataSize, alignment);
    if (!slice.fBuffer) {
        return nullptr;
    }
    char* bufferData = (char*)slice.fOffsetMapPtr;
    GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);

    MTLOrigin origin = MTLOriginMake(0, 0, 0);

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();

    // copy data into the buffer, skipping any trailing bytes
    memcpy(bufferData, data, dataSize);

    SkISize levelDimensions = dimensions;
    for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
        const size_t levelRowBytes = GrCompressedRowBytes(compressionType, levelDimensions.width());
        size_t levelSize = SkCompressedDataSize(compressionType, levelDimensions, nullptr, false);

        // TODO: can this all be done in one go?
        [blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
                          sourceOffset: slice.fOffset + individualMipOffsets[currentMipLevel]
                     sourceBytesPerRow: levelRowBytes
                   sourceBytesPerImage: levelSize
                            sourceSize: MTLSizeMake(levelDimensions.width(),
                                                    levelDimensions.height(), 1)
                             toTexture: mtlTexture
                      destinationSlice: 0
                      destinationLevel: currentMipLevel
                     destinationOrigin: origin];

        levelDimensions = {std::max(1, levelDimensions.width() /2),
                           std::max(1, levelDimensions.height()/2)};
    }
#ifdef SK_BUILD_FOR_MAC
    [mtlBuffer->mtlBuffer() didModifyRange: NSMakeRange(slice.fOffset, dataSize)];
#endif

    return std::move(tex);
}

// TODO: Extra retain/release can't be avoided here because of getMtlTextureInfo copying the
// sk_cfp. It would be useful to have a (possibly-internal-only?) API to get the raw pointer.
static id<MTLTexture> get_texture_from_backend(const GrBackendTexture& backendTex) {
    GrMtlTextureInfo textureInfo;
    if (!backendTex.getMtlTextureInfo(&textureInfo)) {
        return nil;
    }
    return GrGetMTLTexture(textureInfo.fTexture.get());
}

static id<MTLTexture> get_texture_from_backend(const GrBackendRenderTarget& backendRT) {
    GrMtlTextureInfo textureInfo;
    if (!backendRT.getMtlTextureInfo(&textureInfo)) {
        return nil;
    }
    return GrGetMTLTexture(textureInfo.fTexture.get());
}

sk_sp<GrTexture> GrMtlGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
                                                GrWrapOwnership,
                                                GrWrapCacheable cacheable,
                                                GrIOType ioType) {
    id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex);
    if (!mtlTexture) {
        return nullptr;
    }
    // We don't currently support sampling from a MSAA texture in shaders.
    if (mtlTexture.sampleCount != 1) {
        return nullptr;
    }

    return GrMtlTexture::MakeWrappedTexture(this, backendTex.dimensions(), mtlTexture, cacheable,
                                            ioType);
}

sk_sp<GrTexture> GrMtlGpu::onWrapCompressedBackendTexture(const GrBackendTexture& backendTex,
                                                          GrWrapOwnership,
                                                          GrWrapCacheable cacheable) {
    id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex);
    if (!mtlTexture) {
        return nullptr;
    }
    // We don't currently support sampling from a MSAA texture in shaders.
    if (mtlTexture.sampleCount != 1) {
        return nullptr;
    }

    return GrMtlTexture::MakeWrappedTexture(this, backendTex.dimensions(), mtlTexture, cacheable,
                                            kRead_GrIOType);
}

sk_sp<GrTexture> GrMtlGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,
                                                          int sampleCnt,
                                                          GrWrapOwnership,
                                                          GrWrapCacheable cacheable) {
    id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex);
    if (!mtlTexture) {
        return nullptr;
    }
    // We don't currently support sampling from a MSAA texture in shaders.
    if (mtlTexture.sampleCount != 1) {
        return nullptr;
    }

    const GrMtlCaps& caps = this->mtlCaps();

    MTLPixelFormat format = mtlTexture.pixelFormat;
    if (!caps.isFormatRenderable(format, sampleCnt)) {
        return nullptr;
    }

    if (@available(macOS 10.11, iOS 9.0, *)) {
        SkASSERT(MTLTextureUsageRenderTarget & mtlTexture.usage);
    }

    sampleCnt = caps.getRenderTargetSampleCount(sampleCnt, format);
    SkASSERT(sampleCnt);

    return GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
            this, backendTex.dimensions(), sampleCnt, mtlTexture, cacheable);
}

sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
    if (!this->caps()->isFormatRenderable(backendRT.getBackendFormat(), backendRT.sampleCnt())) {
        return nullptr;
    }

    id<MTLTexture> mtlTexture = get_texture_from_backend(backendRT);
    if (!mtlTexture) {
        return nullptr;
    }

    if (@available(macOS 10.11, iOS 9.0, *)) {
        SkASSERT(MTLTextureUsageRenderTarget & mtlTexture.usage);
    }

    return GrMtlRenderTarget::MakeWrappedRenderTarget(this, backendRT.dimensions(),
                                                      backendRT.sampleCnt(), mtlTexture);
}

bool GrMtlGpu::onRegenerateMipMapLevels(GrTexture* texture) {
    GrMtlTexture* grMtlTexture = static_cast<GrMtlTexture*>(texture);
    id<MTLTexture> GR_NORETAIN mtlTexture = grMtlTexture->mtlTexture();

    // Automatic mipmap generation is only supported by color-renderable formats
    if (!fMtlCaps->isFormatRenderable(mtlTexture.pixelFormat, 1) &&
        // We have pixel configs marked as textureable-only that use RGBA8 as the internal format
        MTLPixelFormatRGBA8Unorm != mtlTexture.pixelFormat) {
        return false;
    }

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    [blitCmdEncoder generateMipmapsForTexture: mtlTexture];

    return true;
}

// Used to "clear" a backend texture to a constant color by transferring.
static GrColorType mtl_format_to_backend_tex_clear_colortype(MTLPixelFormat format) {
    switch(format) {
        case MTLPixelFormatA8Unorm:         return GrColorType::kAlpha_8;
        case MTLPixelFormatR8Unorm:         return GrColorType::kR_8;

#ifdef SK_BUILD_FOR_IOS
        case MTLPixelFormatB5G6R5Unorm:     return GrColorType::kBGR_565;
        case MTLPixelFormatABGR4Unorm:      return GrColorType::kABGR_4444;
#endif
        case MTLPixelFormatRGBA8Unorm:      return GrColorType::kRGBA_8888;
        case MTLPixelFormatRGBA8Unorm_sRGB: return GrColorType::kRGBA_8888_SRGB;

        case MTLPixelFormatRG8Unorm:        return GrColorType::kRG_88;
        case MTLPixelFormatBGRA8Unorm:      return GrColorType::kBGRA_8888;
        case MTLPixelFormatRGB10A2Unorm:    return GrColorType::kRGBA_1010102;
#ifdef SK_BUILD_FOR_MAC
        case MTLPixelFormatBGR10A2Unorm:    return GrColorType::kBGRA_1010102;
#endif
        case MTLPixelFormatR16Float:        return GrColorType::kR_F16;
        case MTLPixelFormatRGBA16Float:     return GrColorType::kRGBA_F16;
        case MTLPixelFormatR16Unorm:        return GrColorType::kR_16;
        case MTLPixelFormatRG16Unorm:       return GrColorType::kRG_1616;
        case MTLPixelFormatRGBA16Unorm:     return GrColorType::kRGBA_16161616;
        case MTLPixelFormatRG16Float:       return GrColorType::kRG_F16;
        default:                            return GrColorType::kUnknown;
    }

    SkUNREACHABLE;
}

void copy_src_data(char* dst,
                   size_t bytesPerPixel,
                   const SkTArray<size_t>& individualMipOffsets,
                   const GrPixmap srcData[],
                   int numMipLevels,
                   size_t bufferSize) {
    SkASSERT(srcData && numMipLevels);
    SkASSERT(individualMipOffsets.count() == numMipLevels);

    for (int level = 0; level < numMipLevels; ++level) {
        const size_t trimRB = srcData[level].width() * bytesPerPixel;
        SkASSERT(individualMipOffsets[level] + trimRB * srcData[level].height() <= bufferSize);
        SkRectMemcpy(dst + individualMipOffsets[level], trimRB,
                     srcData[level].addr(), srcData[level].rowBytes(),
                     trimRB, srcData[level].height());
    }
}

bool GrMtlGpu::createMtlTextureForBackendSurface(MTLPixelFormat mtlFormat,
                                                 SkISize dimensions,
                                                 int sampleCnt,
                                                 GrTexturable texturable,
                                                 GrRenderable renderable,
                                                 GrMipmapped mipMapped,
                                                 GrMtlTextureInfo* info) {
    SkASSERT(texturable == GrTexturable::kYes || renderable == GrRenderable::kYes);

    if (texturable == GrTexturable::kYes && !fMtlCaps->isFormatTexturable(mtlFormat)) {
        return false;
    }
    if (renderable == GrRenderable::kYes && !fMtlCaps->isFormatRenderable(mtlFormat, 1)) {
        return false;
    }

    if (!check_max_blit_width(dimensions.width())) {
        return false;
    }

    auto desc = [[MTLTextureDescriptor alloc] init];
    desc.pixelFormat = mtlFormat;
    desc.width = dimensions.width();
    desc.height = dimensions.height();
    if (mipMapped == GrMipMapped::kYes) {
        desc.mipmapLevelCount = 1 + SkPrevLog2(std::max(dimensions.width(), dimensions.height()));
    }
    if (@available(macOS 10.11, iOS 9.0, *)) {
        desc.storageMode = MTLStorageModePrivate;
        MTLTextureUsage usage = texturable == GrTexturable::kYes ? MTLTextureUsageShaderRead : 0;
        usage |= renderable == GrRenderable::kYes ? MTLTextureUsageRenderTarget : 0;
        desc.usage = usage;
    }
    if (sampleCnt != 1) {
        desc.sampleCount = sampleCnt;
        desc.textureType = MTLTextureType2DMultisample;
    }
    id<MTLTexture> testTexture = [fDevice newTextureWithDescriptor: desc];
    info->fTexture.reset(GrRetainPtrFromId(testTexture));
    return true;
}

GrBackendTexture GrMtlGpu::onCreateBackendTexture(SkISize dimensions,
                                                  const GrBackendFormat& format,
                                                  GrRenderable renderable,
                                                  GrMipmapped mipMapped,
                                                  GrProtected isProtected) {
    const MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);

    GrMtlTextureInfo info;
    if (!this->createMtlTextureForBackendSurface(mtlFormat, dimensions, 1, GrTexturable::kYes,
                                                 renderable, mipMapped, &info)) {
        return {};
    }

    GrBackendTexture backendTex(dimensions.width(), dimensions.height(), mipMapped, info);
    return backendTex;
}

bool GrMtlGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
                                     sk_sp<GrRefCntedCallback> finishedCallback,
                                     std::array<float, 4> color) {
    GrMtlTextureInfo info;
    SkAssertResult(backendTexture.getMtlTextureInfo(&info));

    id<MTLTexture> GR_NORETAIN mtlTexture = GrGetMTLTexture(info.fTexture.get());

    const MTLPixelFormat mtlFormat = mtlTexture.pixelFormat;

    // Create a transfer buffer and fill with data.
    size_t bytesPerPixel = GrMtlFormatBytesPerBlock(mtlFormat);
    size_t combinedBufferSize;

    // Reuse the same buffer for all levels. Should be ok since we made the row bytes tight.
    combinedBufferSize = bytesPerPixel*backendTexture.width()*backendTexture.height();

#ifdef SK_BUILD_FOR_MAC
    static const size_t kMinAlignment = 4;
#else
    static const size_t kMinAlignment = 1;
#endif
    size_t alignment = std::max(bytesPerPixel, kMinAlignment);
    GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
            combinedBufferSize, alignment);
    if (!slice.fBuffer) {
        return false;
    }
    char* buffer = (char*)slice.fOffsetMapPtr;

    auto colorType = mtl_format_to_backend_tex_clear_colortype(mtlFormat);
    if (colorType == GrColorType::kUnknown) {
        return false;
    }
    GrImageInfo ii(colorType, kUnpremul_SkAlphaType, nullptr, backendTexture.dimensions());
    auto rb = ii.minRowBytes();
    SkASSERT(rb == bytesPerPixel*backendTexture.width());
    if (!GrClearImage(ii, buffer, rb, color)) {
        return false;
    }

    // Transfer buffer contents to texture
    MTLOrigin origin = MTLOriginMake(0, 0, 0);

    GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);

    SkISize levelDimensions(backendTexture.dimensions());
    int numMipLevels = mtlTexture.mipmapLevelCount;
    for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
        size_t levelRowBytes;
        size_t levelSize;

        levelRowBytes = levelDimensions.width() * bytesPerPixel;
        levelSize = levelRowBytes * levelDimensions.height();

        // TODO: can this all be done in one go?
        [blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
                          sourceOffset: slice.fOffset
                     sourceBytesPerRow: levelRowBytes
                   sourceBytesPerImage: levelSize
                            sourceSize: MTLSizeMake(levelDimensions.width(),
                                                    levelDimensions.height(),
                                                    1)
                             toTexture: mtlTexture
                      destinationSlice: 0
                      destinationLevel: currentMipLevel
                     destinationOrigin: origin];

        levelDimensions = {std::max(1, levelDimensions.width() / 2),
                           std::max(1, levelDimensions.height() / 2)};
    }
#ifdef SK_BUILD_FOR_MAC
    [mtlBuffer->mtlBuffer() didModifyRange: NSMakeRange(slice.fOffset, combinedBufferSize)];
#endif

    if (finishedCallback) {
        this->addFinishedCallback(std::move(finishedCallback));
    }

    return true;
}

GrBackendTexture GrMtlGpu::onCreateCompressedBackendTexture(
        SkISize dimensions, const GrBackendFormat& format, GrMipmapped mipMapped,
        GrProtected isProtected) {
    const MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format);

    GrMtlTextureInfo info;
    if (!this->createMtlTextureForBackendSurface(mtlFormat, dimensions, 1, GrTexturable::kYes,
                                                 GrRenderable::kNo, mipMapped, &info)) {
        return {};
    }

    return GrBackendTexture(dimensions.width(), dimensions.height(), mipMapped, info);
}

bool GrMtlGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture,
                                                sk_sp<GrRefCntedCallback> finishedCallback,
                                                const void* data,
                                                size_t size) {
    GrMtlTextureInfo info;
    SkAssertResult(backendTexture.getMtlTextureInfo(&info));

    id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture.get());

    int numMipLevels = mtlTexture.mipmapLevelCount;
    GrMipmapped mipMapped = numMipLevels > 1 ? GrMipmapped::kYes : GrMipmapped::kNo;

    SkImage::CompressionType compression =
            GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
    SkASSERT(compression != SkImage::CompressionType::kNone);

    // Create a transfer buffer and fill with data.
    SkSTArray<16, size_t> individualMipOffsets;
    size_t combinedBufferSize;
    combinedBufferSize = SkCompressedDataSize(compression,
                                              backendTexture.dimensions(),
                                              &individualMipOffsets,
                                              mipMapped == GrMipmapped::kYes);
    SkASSERT(individualMipOffsets.count() == numMipLevels);

#ifdef SK_BUILD_FOR_MAC
    static const size_t kMinAlignment = 4;
#else
    static const size_t kMinAlignment = 1;
#endif
    size_t alignment = std::max(SkCompressedBlockSize(compression), kMinAlignment);
    GrStagingBufferManager::Slice slice =
            fStagingBufferManager.allocateStagingBufferSlice(combinedBufferSize, alignment);
    if (!slice.fBuffer) {
        return false;
    }
    char* buffer = (char*)slice.fOffsetMapPtr;

    memcpy(buffer, data, size);

    // Transfer buffer contents to texture
    MTLOrigin origin = MTLOriginMake(0, 0, 0);

    GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);

    SkISize levelDimensions(backendTexture.dimensions());
    for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
        size_t levelRowBytes;
        size_t levelSize;

        levelRowBytes = GrCompressedRowBytes(compression, levelDimensions.width());
        levelSize = SkCompressedDataSize(compression, levelDimensions, nullptr, false);

        // TODO: can this all be done in one go?
        [blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
                          sourceOffset: slice.fOffset + individualMipOffsets[currentMipLevel]
                     sourceBytesPerRow: levelRowBytes
                   sourceBytesPerImage: levelSize
                            sourceSize: MTLSizeMake(levelDimensions.width(),
                                                    levelDimensions.height(),
                                                    1)
                             toTexture: mtlTexture
                      destinationSlice: 0
                      destinationLevel: currentMipLevel
                     destinationOrigin: origin];

        levelDimensions = {std::max(1, levelDimensions.width() / 2),
                           std::max(1, levelDimensions.height() / 2)};
    }
#ifdef SK_BUILD_FOR_MAC
    [mtlBuffer->mtlBuffer() didModifyRange:NSMakeRange(slice.fOffset, combinedBufferSize)];
#endif

    if (finishedCallback) {
        this->addFinishedCallback(std::move(finishedCallback));
    }

    return true;
}

void GrMtlGpu::deleteBackendTexture(const GrBackendTexture& tex) {
    SkASSERT(GrBackendApi::kMetal == tex.backend());
    // Nothing to do here, will get cleaned up when the GrBackendTexture object goes away
}

bool GrMtlGpu::compile(const GrProgramDesc& desc, const GrProgramInfo& programInfo) {

    GrThreadSafePipelineBuilder::Stats::ProgramCacheResult stat;

    auto pipelineState = this->resourceProvider().findOrCreateCompatiblePipelineState(
                                 desc, programInfo, &stat);
    if (!pipelineState) {
        return false;
    }

    return stat != GrThreadSafePipelineBuilder::Stats::ProgramCacheResult::kHit;
}

bool GrMtlGpu::precompileShader(const SkData& key, const SkData& data) {
    return this->resourceProvider().precompileShader(key, data);
}

#if GR_TEST_UTILS
bool GrMtlGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
    SkASSERT(GrBackendApi::kMetal == tex.backend());

    GrMtlTextureInfo info;
    if (!tex.getMtlTextureInfo(&info)) {
        return false;
    }
    id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture.get());
    if (!mtlTexture) {
        return false;
    }
    if (@available(macOS 10.11, iOS 9.0, *)) {
        return mtlTexture.usage & MTLTextureUsageShaderRead;
    } else {
        return true; // best we can do
    }
}

GrBackendRenderTarget GrMtlGpu::createTestingOnlyBackendRenderTarget(SkISize dimensions,
                                                                     GrColorType ct,
                                                                     int sampleCnt,
                                                                     GrProtected isProtected) {
    if (dimensions.width()  > this->caps()->maxRenderTargetSize() ||
        dimensions.height() > this->caps()->maxRenderTargetSize()) {
        return {};
    }
    if (isProtected == GrProtected::kYes) {
        return {};
    }

    MTLPixelFormat format = this->mtlCaps().getFormatFromColorType(ct);
    sampleCnt = this->mtlCaps().getRenderTargetSampleCount(sampleCnt, format);
    if (sampleCnt == 0) {
        return {};
    }

    GrMtlTextureInfo info;
    if (!this->createMtlTextureForBackendSurface(format, dimensions, sampleCnt, GrTexturable::kNo,
                                                 GrRenderable::kYes, GrMipmapped::kNo, &info)) {
        return {};
    }

    return GrBackendRenderTarget(dimensions.width(), dimensions.height(), info);
}

void GrMtlGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget& rt) {
    SkASSERT(GrBackendApi::kMetal == rt.backend());

    GrMtlTextureInfo info;
    if (rt.getMtlTextureInfo(&info)) {
        this->submitToGpu(true);
        // Nothing else to do here, will get cleaned up when the GrBackendRenderTarget
        // is deleted.
    }
}
#endif // GR_TEST_UTILS

void GrMtlGpu::copySurfaceAsResolve(GrSurface* dst, GrSurface* src) {
    // TODO: Add support for subrectangles
    GrMtlRenderTarget* srcRT = static_cast<GrMtlRenderTarget*>(src->asRenderTarget());
    GrRenderTarget* dstRT = dst->asRenderTarget();
    id<MTLTexture> dstTexture;
    if (dstRT) {
        GrMtlRenderTarget* mtlRT = static_cast<GrMtlRenderTarget*>(dstRT);
        dstTexture = mtlRT->mtlColorTexture();
    } else {
        SkASSERT(dst->asTexture());
        dstTexture = static_cast<GrMtlTexture*>(dst->asTexture())->mtlTexture();
    }

    this->resolveTexture(dstTexture, srcRT->mtlColorTexture());
}

void GrMtlGpu::copySurfaceAsBlit(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
                                 const SkIPoint& dstPoint) {
#ifdef SK_DEBUG
    SkASSERT(this->mtlCaps().canCopyAsBlit(dst, src, srcRect, dstPoint));
#endif
    id<MTLTexture> GR_NORETAIN dstTex = GrGetMTLTextureFromSurface(dst);
    id<MTLTexture> GR_NORETAIN srcTex = GrGetMTLTextureFromSurface(src);

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    [blitCmdEncoder copyFromTexture: srcTex
                        sourceSlice: 0
                        sourceLevel: 0
                       sourceOrigin: MTLOriginMake(srcRect.x(), srcRect.y(), 0)
                         sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1)
                          toTexture: dstTex
                   destinationSlice: 0
                   destinationLevel: 0
                  destinationOrigin: MTLOriginMake(dstPoint.fX, dstPoint.fY, 0)];
}

bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
                             const SkIPoint& dstPoint) {
    SkASSERT(!src->isProtected() && !dst->isProtected());

    bool success = false;
    if (this->mtlCaps().canCopyAsBlit(dst, src, srcRect, dstPoint)) {
       this->copySurfaceAsBlit(dst, src, srcRect, dstPoint);
       success = true;
    } else if (this->mtlCaps().canCopyAsResolve(dst, src, srcRect, dstPoint)) {
        this->copySurfaceAsResolve(dst, src);
        success = true;
    }
    if (success) {
        SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.x(), dstPoint.y(),
                                            srcRect.width(), srcRect.height());
        // The rect is already in device space so we pass in kTopLeft so no flip is done.
        this->didWriteToSurface(dst, kTopLeft_GrSurfaceOrigin, &dstRect);
    }
    return success;
}

bool GrMtlGpu::onWritePixels(GrSurface* surface,
                             SkIRect rect,
                             GrColorType surfaceColorType,
                             GrColorType srcColorType,
                             const GrMipLevel texels[],
                             int mipLevelCount,
                             bool prepForTexSampling) {
    GrMtlTexture* mtlTexture = static_cast<GrMtlTexture*>(surface->asTexture());
    // TODO: In principle we should be able to support pure rendertargets as well, but
    // until we find a use case we'll only support texture rendertargets.
    if (!mtlTexture) {
        return false;
    }
    if (!mipLevelCount) {
        return false;
    }
#ifdef SK_DEBUG
    for (int i = 0; i < mipLevelCount; i++) {
        SkASSERT(texels[i].fPixels);
    }
#endif
    return this->uploadToTexture(mtlTexture, rect, srcColorType, texels, mipLevelCount);
}

bool GrMtlGpu::onReadPixels(GrSurface* surface,
                            SkIRect rect,
                            GrColorType surfaceColorType,
                            GrColorType dstColorType,
                            void* buffer,
                            size_t rowBytes) {
    SkASSERT(surface);

    if (surfaceColorType != dstColorType) {
        return false;
    }

    int bpp = GrColorTypeBytesPerPixel(dstColorType);
    size_t transBufferRowBytes = bpp*rect.width();
    size_t transBufferImageBytes = transBufferRowBytes*rect.height();

    // TODO: implement some way of reusing buffers instead of making a new one every time.
    NSUInteger options = 0;
    if (@available(macOS 10.11, iOS 9.0, *)) {
#ifdef SK_BUILD_FOR_MAC
        options |= MTLResourceStorageModeManaged;
#else
        options |= MTLResourceStorageModeShared;
#endif
    }

    GrResourceProvider* resourceProvider = this->getContext()->priv().resourceProvider();
    sk_sp<GrGpuBuffer> transferBuffer = resourceProvider->createBuffer(
            transBufferImageBytes, GrGpuBufferType::kXferGpuToCpu,
            kDynamic_GrAccessPattern);

    if (!transferBuffer) {
        return false;
    }

    GrMtlBuffer* grMtlBuffer = static_cast<GrMtlBuffer*>(transferBuffer.get());
    if (!this->readOrTransferPixels(surface,
                                    rect,
                                    dstColorType,
                                    grMtlBuffer->mtlBuffer(),
                                    0,
                                    transBufferImageBytes,
                                    transBufferRowBytes)) {
        return false;
    }
    this->submitCommandBuffer(kForce_SyncQueue);

    const void* mappedMemory = grMtlBuffer->mtlBuffer().contents;

    SkRectMemcpy(buffer,
                 rowBytes,
                 mappedMemory,
                 transBufferRowBytes,
                 transBufferRowBytes,
                 rect.height());

    return true;
}

bool GrMtlGpu::onTransferPixelsTo(GrTexture* texture,
                                  SkIRect rect,
                                  GrColorType textureColorType,
                                  GrColorType bufferColorType,
                                  sk_sp<GrGpuBuffer> transferBuffer,
                                  size_t offset,
                                  size_t rowBytes) {
    SkASSERT(texture);
    SkASSERT(transferBuffer);
    if (textureColorType != bufferColorType) {
        return false;
    }

    GrMtlTexture* grMtlTexture = static_cast<GrMtlTexture*>(texture);
    id<MTLTexture> GR_NORETAIN mtlTexture = grMtlTexture->mtlTexture();
    SkASSERT(mtlTexture);

    GrMtlBuffer* grMtlBuffer = static_cast<GrMtlBuffer*>(transferBuffer.get());
    id<MTLBuffer> GR_NORETAIN mtlBuffer = grMtlBuffer->mtlBuffer();
    SkASSERT(mtlBuffer);

    size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
    if (offset % bpp) {
        return false;
    }
    if (GrBackendFormatBytesPerPixel(texture->backendFormat()) != bpp) {
        return false;
    }

    MTLOrigin origin = MTLOriginMake(rect.left(), rect.top(), 0);

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    [blitCmdEncoder copyFromBuffer: mtlBuffer
                      sourceOffset: offset + grMtlBuffer->offset()
                 sourceBytesPerRow: rowBytes
               sourceBytesPerImage: rowBytes*rect.height()
                        sourceSize: MTLSizeMake(rect.width(), rect.height(), 1)
                         toTexture: mtlTexture
                  destinationSlice: 0
                  destinationLevel: 0
                 destinationOrigin: origin];

    return true;
}

bool GrMtlGpu::onTransferPixelsFrom(GrSurface* surface,
                                    SkIRect rect,
                                    GrColorType surfaceColorType,
                                    GrColorType bufferColorType,
                                    sk_sp<GrGpuBuffer> transferBuffer,
                                    size_t offset) {
    SkASSERT(surface);
    SkASSERT(transferBuffer);

    if (surfaceColorType != bufferColorType) {
        return false;
    }

    // Metal only supports offsets that are aligned to a pixel.
    size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
    if (offset % bpp) {
        return false;
    }
    if (GrBackendFormatBytesPerPixel(surface->backendFormat()) != bpp) {
        return false;
    }

    GrMtlBuffer* grMtlBuffer = static_cast<GrMtlBuffer*>(transferBuffer.get());

    size_t transBufferRowBytes = bpp*rect.width();
    size_t transBufferImageBytes = transBufferRowBytes*rect.height();

    return this->readOrTransferPixels(surface,
                                      rect,
                                      bufferColorType,
                                      grMtlBuffer->mtlBuffer(),
                                      offset + grMtlBuffer->offset(),
                                      transBufferImageBytes,
                                      transBufferRowBytes);
}

bool GrMtlGpu::readOrTransferPixels(GrSurface* surface,
                                    SkIRect rect,
                                    GrColorType dstColorType,
                                    id<MTLBuffer> transferBuffer,
                                    size_t offset,
                                    size_t imageBytes,
                                    size_t rowBytes) {
    if (!check_max_blit_width(rect.width())) {
        return false;
    }

    id<MTLTexture> mtlTexture;
    if (GrMtlRenderTarget* rt = static_cast<GrMtlRenderTarget*>(surface->asRenderTarget())) {
        if (rt->numSamples() > 1) {
            SkASSERT(rt->requiresManualMSAAResolve());  // msaa-render-to-texture not yet supported.
            mtlTexture = rt->mtlResolveTexture();
        } else {
            SkASSERT(!rt->requiresManualMSAAResolve());
            mtlTexture = rt->mtlColorTexture();
        }
    } else if (GrMtlTexture* texture = static_cast<GrMtlTexture*>(surface->asTexture())) {
        mtlTexture = texture->mtlTexture();
    }
    if (!mtlTexture) {
        return false;
    }

    auto cmdBuffer = this->commandBuffer();
    id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
    [blitCmdEncoder copyFromTexture: mtlTexture
                        sourceSlice: 0
                        sourceLevel: 0
                       sourceOrigin: MTLOriginMake(rect.left(), rect.top(), 0)
                         sourceSize: MTLSizeMake(rect.width(), rect.height(), 1)
                           toBuffer: transferBuffer
                  destinationOffset: offset
             destinationBytesPerRow: rowBytes
           destinationBytesPerImage: imageBytes];
#ifdef SK_BUILD_FOR_MAC
    // Sync GPU data back to the CPU
    [blitCmdEncoder synchronizeResource: transferBuffer];
#endif

    return true;
}

GrFence SK_WARN_UNUSED_RESULT GrMtlGpu::insertFence() {
    GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
    // We create a semaphore and signal it within the current
    // command buffer's completion handler.
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    cmdBuffer->addCompletedHandler(^(id <MTLCommandBuffer>commandBuffer) {
        dispatch_semaphore_signal(semaphore);
    });

    const void* cfFence = (__bridge_retained const void*) semaphore;
    return (GrFence) cfFence;
}

bool GrMtlGpu::waitFence(GrFence fence) {
    const void* cfFence = (const void*) fence;
    dispatch_semaphore_t semaphore = (__bridge dispatch_semaphore_t)cfFence;

    long result = dispatch_semaphore_wait(semaphore, 0);

    return !result;
}

void GrMtlGpu::deleteFence(GrFence fence) const {
    const void* cfFence = (const void*) fence;
    // In this case it's easier to release in CoreFoundation than depend on ARC
    CFRelease(cfFence);
}

std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT GrMtlGpu::makeSemaphore(bool /*isOwned*/) {
    SkASSERT(this->caps()->semaphoreSupport());
    return GrMtlSemaphore::Make(this);
}

std::unique_ptr<GrSemaphore> GrMtlGpu::wrapBackendSemaphore(
        const GrBackendSemaphore& semaphore,
        GrResourceProvider::SemaphoreWrapType wrapType,
        GrWrapOwnership /*ownership*/) {
    SkASSERT(this->caps()->semaphoreSupport());
    return GrMtlSemaphore::MakeWrapped(semaphore.mtlSemaphore(), semaphore.mtlValue());
}

void GrMtlGpu::insertSemaphore(GrSemaphore* semaphore) {
    if (@available(macOS 10.14, iOS 12.0, *)) {
        SkASSERT(semaphore);
        GrMtlSemaphore* mtlSem = static_cast<GrMtlSemaphore*>(semaphore);

        this->commandBuffer()->encodeSignalEvent(mtlSem->event(), mtlSem->value());
    }
}

void GrMtlGpu::waitSemaphore(GrSemaphore* semaphore) {
    if (@available(macOS 10.14, iOS 12.0, *)) {
        SkASSERT(semaphore);
        GrMtlSemaphore* mtlSem = static_cast<GrMtlSemaphore*>(semaphore);

        this->commandBuffer()->encodeWaitForEvent(mtlSem->event(), mtlSem->value());
    }
}

void GrMtlGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect&) {
    this->resolveTexture(static_cast<GrMtlRenderTarget*>(target)->mtlResolveTexture(),
                         static_cast<GrMtlRenderTarget*>(target)->mtlColorTexture());
}

void GrMtlGpu::resolveTexture(id<MTLTexture> resolveTexture, id<MTLTexture> colorTexture) {
    auto renderPassDesc = [[MTLRenderPassDescriptor alloc] init];
    auto colorAttachment = renderPassDesc.colorAttachments[0];
    colorAttachment.texture = colorTexture;
    colorAttachment.resolveTexture = resolveTexture;
    colorAttachment.loadAction = MTLLoadActionLoad;
    colorAttachment.storeAction = MTLStoreActionMultisampleResolve;

    GrMtlRenderCommandEncoder* cmdEncoder =
            this->commandBuffer()->getRenderCommandEncoder(renderPassDesc, nullptr, nullptr);
    SkASSERT(nil != cmdEncoder);
    cmdEncoder->setLabel(@"resolveTexture");
}

#if GR_TEST_UTILS
void GrMtlGpu::testingOnly_startCapture() {
    if (@available(macOS 10.13, iOS 11.0, *)) {
        // TODO: add Metal 3 interface as well
        MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
        [captureManager startCaptureWithDevice: fDevice];
    }
}

void GrMtlGpu::testingOnly_endCapture() {
    if (@available(macOS 10.13, iOS 11.0, *)) {
        MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
        [captureManager stopCapture];
    }
}
#endif

#ifdef SK_ENABLE_DUMP_GPU
#include "src/utils/SkJSONWriter.h"
void GrMtlGpu::onDumpJSON(SkJSONWriter* writer) const {
    // We are called by the base class, which has already called beginObject(). We choose to nest
    // all of our caps information in a named sub-object.
    writer->beginObject("Metal GPU");

    writer->beginObject("Device");
    writer->appendString("name", fDevice.name.UTF8String);
#ifdef SK_BUILD_FOR_MAC
    if (@available(macOS 10.11, *)) {
        writer->appendBool("isHeadless", fDevice.isHeadless);
        writer->appendBool("isLowPower", fDevice.isLowPower);
    }
    if (@available(macOS 10.13, *)) {
        writer->appendBool("isRemovable", fDevice.isRemovable);
    }
#endif
    if (@available(macOS 10.13, iOS 11.0, *)) {
        writer->appendU64("registryID", fDevice.registryID);
    }
#if defined(SK_BUILD_FOR_MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
    if (@available(macOS 10.15, *)) {
        switch (fDevice.location) {
            case MTLDeviceLocationBuiltIn:
                writer->appendString("location", "builtIn");
                break;
            case MTLDeviceLocationSlot:
                writer->appendString("location", "slot");
                break;
            case MTLDeviceLocationExternal:
                writer->appendString("location", "external");
                break;
            case MTLDeviceLocationUnspecified:
                writer->appendString("location", "unspecified");
                break;
            default:
                writer->appendString("location", "unknown");
                break;
        }
        writer->appendU64("locationNumber", fDevice.locationNumber);
        writer->appendU64("maxTransferRate", fDevice.maxTransferRate);
    }
#endif  // SK_BUILD_FOR_MAC
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
    if (@available(macOS 10.15, iOS 13.0, *)) {
        writer->appendBool("hasUnifiedMemory", fDevice.hasUnifiedMemory);
    }
#endif
#ifdef SK_BUILD_FOR_MAC
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
    if (@available(macOS 10.15, *)) {
        writer->appendU64("peerGroupID", fDevice.peerGroupID);
        writer->appendU32("peerCount", fDevice.peerCount);
        writer->appendU32("peerIndex", fDevice.peerIndex);
    }
#endif
    if (@available(macOS 10.12, *)) {
        writer->appendU64("recommendedMaxWorkingSetSize", fDevice.recommendedMaxWorkingSetSize);
    }
#endif  // SK_BUILD_FOR_MAC
    if (@available(macOS 10.13, iOS 11.0, *)) {
        writer->appendU64("currentAllocatedSize", fDevice.currentAllocatedSize);
        writer->appendU64("maxThreadgroupMemoryLength", fDevice.maxThreadgroupMemoryLength);
    }

    if (@available(macOS 10.11, iOS 9.0, *)) {
        writer->beginObject("maxThreadsPerThreadgroup");
        writer->appendU64("width", fDevice.maxThreadsPerThreadgroup.width);
        writer->appendU64("height", fDevice.maxThreadsPerThreadgroup.height);
        writer->appendU64("depth", fDevice.maxThreadsPerThreadgroup.depth);
        writer->endObject();
    }

    if (@available(macOS 10.13, iOS 11.0, *)) {
        writer->appendBool("areProgrammableSamplePositionsSupported",
                           fDevice.areProgrammableSamplePositionsSupported);
        writer->appendBool("areRasterOrderGroupsSupported",
                           fDevice.areRasterOrderGroupsSupported);
    }
#ifdef SK_BUILD_FOR_MAC
    if (@available(macOS 10.11, *)) {
        writer->appendBool("isDepth24Stencil8PixelFormatSupported",
                           fDevice.isDepth24Stencil8PixelFormatSupported);

    }
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
    if (@available(macOS 10.15, *)) {
        writer->appendBool("areBarycentricCoordsSupported",
                           fDevice.areBarycentricCoordsSupported);
        writer->appendBool("supportsShaderBarycentricCoordinates",
                           fDevice.supportsShaderBarycentricCoordinates);
    }
#endif
#endif  // SK_BUILD_FOR_MAC
    if (@available(macOS 10.14, iOS 12.0, *)) {
        writer->appendU64("maxBufferLength", fDevice.maxBufferLength);
    }
    if (@available(macOS 10.13, iOS 11.0, *)) {
        switch (fDevice.readWriteTextureSupport) {
            case MTLReadWriteTextureTier1:
                writer->appendString("readWriteTextureSupport", "tier1");
                break;
            case MTLReadWriteTextureTier2:
                writer->appendString("readWriteTextureSupport", "tier2");
                break;
            case MTLReadWriteTextureTierNone:
                writer->appendString("readWriteTextureSupport", "tierNone");
                break;
            default:
                writer->appendString("readWriteTextureSupport", "unknown");
                break;
        }
        switch (fDevice.argumentBuffersSupport) {
            case MTLArgumentBuffersTier1:
                writer->appendString("argumentBuffersSupport", "tier1");
                break;
            case MTLArgumentBuffersTier2:
                writer->appendString("argumentBuffersSupport", "tier2");
                break;
            default:
                writer->appendString("argumentBuffersSupport", "unknown");
                break;
        }
    }
    if (@available(macOS 10.14, iOS 12.0, *)) {
        writer->appendU64("maxArgumentBufferSamplerCount", fDevice.maxArgumentBufferSamplerCount);
    }
#ifdef SK_BUILD_FOR_IOS
    if (@available(iOS 13.0, *)) {
        writer->appendU64("sparseTileSizeInBytes", fDevice.sparseTileSizeInBytes);
    }
#endif
    writer->endObject();

    writer->appendString("queue", fQueue.label.UTF8String);
    writer->appendBool("disconnected", fDisconnected);

    writer->endObject();
}
#endif

GR_NORETAIN_END
