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

#ifndef GrMtlResourceProvider_DEFINED
#define GrMtlResourceProvider_DEFINED

#include "include/private/SkSpinlock.h"
#include "include/private/SkTArray.h"
#include "src/core/SkLRUCache.h"
#include "src/gpu/GrProgramDesc.h"
#include "src/gpu/mtl/GrMtlDepthStencil.h"
#include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
#include "src/gpu/mtl/GrMtlSampler.h"

#import <Metal/Metal.h>

class GrMtlGpu;
class GrMtlCommandBuffer;

class GrMtlResourceProvider {
public:
    GrMtlResourceProvider(GrMtlGpu* gpu);

    GrMtlPipelineState* findOrCreateCompatiblePipelineState(GrRenderTarget*,
                                                            const GrProgramInfo&);

    // Finds or creates a compatible MTLDepthStencilState based on the GrStencilSettings.
    GrMtlDepthStencil* findOrCreateCompatibleDepthStencilState(const GrStencilSettings&,
                                                               GrSurfaceOrigin);

    // Finds or creates a compatible MTLSamplerState based on the GrSamplerState.
    GrMtlSampler* findOrCreateCompatibleSampler(GrSamplerState);

    id<MTLBuffer> getDynamicBuffer(size_t size, size_t* offset);
    void addBufferCompletionHandler(GrMtlCommandBuffer* cmdBuffer);

    // Destroy any cached resources. To be called before releasing the MtlDevice.
    void destroyResources();

#if GR_TEST_UTILS
    void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
#endif

private:
#ifdef SK_DEBUG
#define GR_PIPELINE_STATE_CACHE_STATS
#endif

    class PipelineStateCache : public ::SkNoncopyable {
    public:
        PipelineStateCache(GrMtlGpu* gpu);
        ~PipelineStateCache();

        void release();
        GrMtlPipelineState* refPipelineState(GrRenderTarget*, const GrProgramInfo&);

    private:
        struct Entry;

        struct DescHash {
            uint32_t operator()(const GrProgramDesc& desc) const {
                return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
            }
        };

        SkLRUCache<const GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;

        GrMtlGpu*                   fGpu;

#ifdef GR_PIPELINE_STATE_CACHE_STATS
        int                         fTotalRequests;
        int                         fCacheMisses;
#endif
    };

    // Buffer allocator
    class BufferSuballocator : public SkRefCnt {
    public:
        BufferSuballocator(id<MTLDevice> device, size_t size);
        ~BufferSuballocator() {
            fBuffer = nil;
            fTotalSize = 0;
        }

        id<MTLBuffer> getAllocation(size_t size, size_t* offset);
        void addCompletionHandler(GrMtlCommandBuffer* cmdBuffer);
        size_t size() { return fTotalSize; }

    private:
        id<MTLBuffer> fBuffer;
        size_t        fTotalSize;
        size_t        fHead SK_GUARDED_BY(fMutex);     // where we start allocating
        size_t        fTail SK_GUARDED_BY(fMutex);     // where we start deallocating
        SkSpinlock    fMutex;
    };
    static constexpr size_t kBufferSuballocatorStartSize = 1024*1024;

    GrMtlGpu* fGpu;

    // Cache of GrMtlPipelineStates
    std::unique_ptr<PipelineStateCache> fPipelineStateCache;

    SkTDynamicHash<GrMtlSampler, GrMtlSampler::Key> fSamplers;
    SkTDynamicHash<GrMtlDepthStencil, GrMtlDepthStencil::Key> fDepthStencilStates;

    // This is ref-counted because we might delete the GrContext before the command buffer
    // finishes. The completion handler will retain a reference to this so it won't get
    // deleted along with the GrContext.
    sk_sp<BufferSuballocator> fBufferSuballocator;
    size_t fBufferSuballocatorMaxSize;
};

#endif
