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

#ifndef GrManagedResource_DEFINED
#define GrManagedResource_DEFINED

#include "include/private/base/SkMutex.h"
#include "src/base/SkRandom.h"
#include "src/core/SkTHash.h"
#include "src/gpu/ganesh/GrSurface.h"
#include <atomic>

class GrTexture;

// uncomment to enable tracing of resource refs
#ifdef SK_DEBUG
#define SK_TRACE_MANAGED_RESOURCES
#endif

/** \class GrManagedResource

  GrManagedResource is the base class for GPU resources that may be shared by
  multiple objects, in particular objects that are tracked by a command buffer.
  When an existing owner wants to share a reference, it calls ref().
  When an owner wants to release its reference, it calls unref(). When the
  shared object's reference count goes to zero as the result of an unref()
  call, its (virtual) destructor is called. It is an error for the
  destructor to be called explicitly (or via the object going out of scope on
  the stack or calling delete) if getRefCnt() > 1.

  This is nearly identical to SkRefCntBase. The exceptions are that unref()
  takes a GrGpu, and any derived classes must implement freeGPUData().
*/

class GrManagedResource : SkNoncopyable {
public:
    // Simple refCount tracing, to ensure that everything ref'ed is unref'ed.
#ifdef SK_TRACE_MANAGED_RESOURCES
    struct Hash {
        uint32_t operator()(const GrManagedResource* const& r) const {
            SkASSERT(r);
            return r->fKey;
        }
    };

    class Trace {
    public:
        ~Trace() {
            fHashSet.foreach([](const GrManagedResource* r) {
                r->dumpInfo();
            });
            SkASSERT(0 == fHashSet.count());
        }

        void add(const GrManagedResource* r) {
            SkAutoMutexExclusive locked(fLock);
            fHashSet.add(r);
        }

        void remove(const GrManagedResource* r) {
            SkAutoMutexExclusive locked(fLock);
            fHashSet.remove(r);
        }

    private:
        SkMutex fLock;
        skia_private::THashSet<const GrManagedResource*, GrManagedResource::Hash> fHashSet
                SK_GUARDED_BY(fLock);
    };

    static std::atomic<uint32_t> fKeyCounter;
#endif

    /** Default construct, initializing the reference count to 1.
     */
    GrManagedResource() : fRefCnt(1) {
#ifdef SK_TRACE_MANAGED_RESOURCES
        fKey = fKeyCounter.fetch_add(+1, std::memory_order_relaxed);
        GetTrace()->add(this);
#endif
    }

    /** Destruct, asserting that the reference count is 1.
     */
    virtual ~GrManagedResource() {
#ifdef SK_DEBUG
        auto count = this->getRefCnt();
        SkASSERTF(count == 1, "fRefCnt was %d", count);
        fRefCnt.store(0);    // illegal value, to catch us if we reuse after delete
#endif
    }

#ifdef SK_DEBUG
    /** Return the reference count. Use only for debugging. */
    int32_t getRefCnt() const { return fRefCnt.load(); }
#endif

    /** May return true if the caller is the only owner.
     *  Ensures that all previous owner's actions are complete.
     */
    bool unique() const {
        // The acquire barrier is only really needed if we return true.  It
        // prevents code conditioned on the result of unique() from running
        // until previous owners are all totally done calling unref().
        return 1 == fRefCnt.load(std::memory_order_acquire);
    }

    /** Increment the reference count.
        Must be balanced by a call to unref() or unrefAndFreeResources().
     */
    void ref() const {
        // No barrier required.
        SkDEBUGCODE(int newRefCount = )fRefCnt.fetch_add(+1, std::memory_order_relaxed);
        SkASSERT(newRefCount >= 1);
    }

    /** Decrement the reference count. If the reference count is 1 before the
        decrement, then delete the object. Note that if this is the case, then
        the object needs to have been allocated via new, and not on the stack.
        Any GPU data associated with this resource will be freed before it's deleted.
     */
    void unref() const {
        // A release here acts in place of all releases we "should" have been doing in ref().
        int newRefCount = fRefCnt.fetch_add(-1, std::memory_order_acq_rel);
        SkASSERT(newRefCount >= 0);
        if (newRefCount == 1) {
            // Like unique(), the acquire is only needed on success, to make sure
            // code in internal_dispose() doesn't happen before the decrement.
            this->internal_dispose();
        }
    }

#ifdef SK_DEBUG
    // This is used for validating in the vulkan backend when using a main command buffer and temp
    // command buffer at the same time. We need to validate that no images in the temp command
    // buffer have been used in the main command buffer.
    virtual const GrManagedResource* asVkImageResource() const { return nullptr; }
#endif

#ifdef SK_DEBUG
    void validate() const {
        SkASSERT(this->getRefCnt() > 0);
    }
#endif

#ifdef SK_TRACE_MANAGED_RESOURCES
    /** Output a human-readable dump of this resource's information
     */
    virtual void dumpInfo() const = 0;
#endif

private:
#ifdef SK_TRACE_MANAGED_RESOURCES
    static Trace* GetTrace() {
        static Trace kTrace;
        return &kTrace;
    }
#endif

    /** Must be implemented by any subclasses.
     *  Deletes any GPU data associated with this resource
     */
    virtual void freeGPUData() const = 0;

    /**
     *  Called when the ref count goes to 0. Will free GPU resources.
     */
    void internal_dispose() const {
        this->freeGPUData();
#ifdef SK_TRACE_MANAGED_RESOURCES
        GetTrace()->remove(this);
#endif

#ifdef SK_DEBUG
        SkASSERT(0 == this->getRefCnt());
        fRefCnt.store(1);
#endif
        delete this;
    }

    mutable std::atomic<int32_t> fRefCnt;
#ifdef SK_TRACE_MANAGED_RESOURCES
    uint32_t fKey;
#endif

    using INHERITED = SkNoncopyable;
};

// This subclass allows for recycling
class GrRecycledResource : public GrManagedResource {
public:
    // When recycle is called and there is only one ref left on the resource, we will signal that
    // the resource can be recycled for reuse. If the subclass (or whoever is managing this resource)
    // decides not to recycle the objects, it is their responsibility to call unref on the object.
    void recycle() const {
        if (this->unique()) {
            this->onRecycle();
        } else {
            this->unref();
        }
    }

private:
    virtual void onRecycle() const = 0;
};

/** \class GrTextureResource

  GrTextureResource is the base class for managed texture resources, and implements the
  basic releaseProc functionality for them.

*/
class GrTextureResource : public GrManagedResource {
public:
    GrTextureResource() {}

    ~GrTextureResource() override {
        SkASSERT(!fReleaseHelper);
    }

    void setRelease(sk_sp<GrSurface::RefCntedReleaseProc> releaseHelper) {
        fReleaseHelper = std::move(releaseHelper);
    }

protected:
    mutable sk_sp<GrSurface::RefCntedReleaseProc> fReleaseHelper;

    void invokeReleaseProc() const {
        if (fReleaseHelper) {
            // Depending on the ref count of fReleaseHelper this may or may not actually trigger
            // the ReleaseProc to be called.
            fReleaseHelper.reset();
        }
    }

private:
    using INHERITED = GrManagedResource;
};

#endif
