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

#ifndef GrSurfaceProxy_DEFINED
#define GrSurfaceProxy_DEFINED

#include "include/core/SkRect.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/private/SkNoncopyable.h"
#include "src/gpu/GrGpuResource.h"
#include "src/gpu/GrSurface.h"
#include "src/gpu/GrTexture.h"

class GrCaps;
class GrContext_Base;
class GrRecordingContext;
class GrRenderTargetProxy;
class GrRenderTask;
class GrResourceProvider;
class GrSurfaceProxyPriv;
class GrSurfaceProxyView;
class GrTextureProxy;

class GrSurfaceProxy : public SkNVRefCnt<GrSurfaceProxy> {
public:
    virtual ~GrSurfaceProxy();

    /**
     * Indicates "resolutions" that need to be done on a surface before its pixels can be accessed.
     * If both types of resolve are requested, the MSAA resolve will happen first.
     */
    enum class ResolveFlags {
        kNone = 0,
        kMSAA = 1 << 0,  // Blit and resolve an internal MSAA render buffer into the texture.
        kMipMaps = 1 << 1,  // Regenerate all mipmap levels.
    };

    /**
     * Some lazy proxy callbacks want to set their own (or no key) on the GrSurfaces they return.
     * Others want the GrSurface's key to be kept in sync with the proxy's key. This enum controls
     * the key relationship between proxies and their targets.
     */
    enum class LazyInstantiationKeyMode {
        /**
         * Don't key the GrSurface with the proxy's key. The lazy instantiation callback is free to
         * return a GrSurface that already has a unique key unrelated to the proxy's key.
         */
        kUnsynced,
        /**
         * Keep the GrSurface's unique key in sync with the proxy's unique key. The GrSurface
         * returned from the lazy instantiation callback must not have a unique key or have the same
         * same unique key as the proxy. If the proxy is later assigned a key it is in turn assigned
         * to the GrSurface.
         */
        kSynced
    };

    /**
     * Specifies the expected properties of the GrSurface returned by a lazy instantiation
     * callback. The dimensions will be negative in the case of a fully lazy proxy.
     */
    struct LazySurfaceDesc {
        SkISize fDimensions;
        SkBackingFit fFit;
        GrRenderable fRenderable;
        GrMipmapped fMipmapped;
        int fSampleCnt;
        const GrBackendFormat& fFormat;
        GrTextureType fTextureType;
        GrProtected fProtected;
        SkBudgeted fBudgeted;
    };

    struct LazyCallbackResult {
        LazyCallbackResult() = default;
        LazyCallbackResult(const LazyCallbackResult&) = default;
        LazyCallbackResult(LazyCallbackResult&& that) = default;
        LazyCallbackResult(sk_sp<GrSurface> surf,
                           bool releaseCallback = true,
                           LazyInstantiationKeyMode mode = LazyInstantiationKeyMode::kSynced)
                : fSurface(std::move(surf)), fKeyMode(mode), fReleaseCallback(releaseCallback) {}
        LazyCallbackResult(sk_sp<GrTexture> tex)
                : LazyCallbackResult(sk_sp<GrSurface>(std::move(tex))) {}

        LazyCallbackResult& operator=(const LazyCallbackResult&) = default;
        LazyCallbackResult& operator=(LazyCallbackResult&&) = default;

        sk_sp<GrSurface> fSurface;
        LazyInstantiationKeyMode fKeyMode = LazyInstantiationKeyMode::kSynced;
        /**
         * Should the callback be disposed of after it has returned or preserved until the proxy
         * is freed. Only honored if fSurface is not-null. If it is null the callback is preserved.
         */
        bool fReleaseCallback = true;
    };

    using LazyInstantiateCallback =
            std::function<LazyCallbackResult(GrResourceProvider*, const LazySurfaceDesc&)>;

    enum class UseAllocator {
        /**
         * This proxy will be instantiated outside the allocator (e.g. for proxies that are
         * instantiated in on-flush callbacks).
         */
        kNo = false,
        /**
         * GrResourceAllocator should instantiate this proxy.
         */
        kYes = true,
    };

    bool isLazy() const { return !this->isInstantiated() && SkToBool(fLazyInstantiateCallback); }

    bool isFullyLazy() const {
        bool result = fDimensions.width() < 0;
        SkASSERT(result == (fDimensions.height() < 0));
        SkASSERT(!result || this->isLazy());
        return result;
    }

    SkISize dimensions() const {
        SkASSERT(!this->isFullyLazy());
        return fDimensions;
    }
    int width() const { return this->dimensions().width(); }
    int height() const { return this->dimensions().height(); }

    SkISize backingStoreDimensions() const;

    /**
     * Helper that gets the width and height of the proxy as a bounding rectangle.
     */
    SkRect getBoundsRect() const { return SkRect::Make(this->dimensions()); }

    /* A perhaps faster check for this->dimensions() == this->backingStoreDimensions(). */
    bool isFunctionallyExact() const;

    /**
     * Helper that gets the dimensions the backing GrSurface will have as a bounding rectangle.
     */
    SkRect backingStoreBoundsRect() const {
        return SkRect::Make(this->backingStoreDimensions());
    }

    SkIRect backingStoreBoundsIRect() const {
        return SkIRect::MakeSize(this->backingStoreDimensions());
    }

    const GrBackendFormat& backendFormat() const { return fFormat; }

    bool isFormatCompressed(const GrCaps*) const;

    class UniqueID {
    public:
        static UniqueID InvalidID() {
            return UniqueID(uint32_t(SK_InvalidUniqueID));
        }

        // wrapped
        explicit UniqueID(const GrGpuResource::UniqueID& id) : fID(id.asUInt()) { }
        // deferred and lazy-callback
        UniqueID() : fID(GrGpuResource::CreateUniqueID()) { }

        uint32_t asUInt() const { return fID; }

        bool operator==(const UniqueID& other) const {
            return fID == other.fID;
        }
        bool operator!=(const UniqueID& other) const {
            return !(*this == other);
        }

        void makeInvalid() { fID = SK_InvalidUniqueID; }
        bool isInvalid() const { return SK_InvalidUniqueID == fID; }

    private:
        explicit UniqueID(uint32_t id) : fID(id) {}

        uint32_t fID;
    };

    /*
     * The contract for the uniqueID is:
     *   for wrapped resources:
     *      the uniqueID will match that of the wrapped resource
     *
     *   for deferred resources:
     *      the uniqueID will be different from the real resource, when it is allocated
     *      the proxy's uniqueID will not change across the instantiate call
     *
     *    the uniqueIDs of the proxies and the resources draw from the same pool
     *
     * What this boils down to is that the uniqueID of a proxy can be used to consistently
     * track/identify a proxy but should never be used to distinguish between
     * resources and proxies - beware!
     */
    UniqueID uniqueID() const { return fUniqueID; }

    UniqueID underlyingUniqueID() const {
        if (fTarget) {
            return UniqueID(fTarget->uniqueID());
        }

        return fUniqueID;
    }

    virtual bool instantiate(GrResourceProvider*) = 0;

    void deinstantiate();

    /**
     * Proxies that are already instantiated and whose backing surface cannot be recycled to
     * instantiate other proxies do not need to be considered by GrResourceAllocator.
     */
    bool canSkipResourceAllocator() const;

    /**
     * @return the texture proxy associated with the surface proxy, may be NULL.
     */
    virtual GrTextureProxy* asTextureProxy() { return nullptr; }
    virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }

    /**
     * @return the render target proxy associated with the surface proxy, may be NULL.
     */
    virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
    virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }

    /** @return The unique key for this proxy. May be invalid. */
    virtual const skgpu::UniqueKey& getUniqueKey() const {
        // Base class never has a valid unique key.
        static const skgpu::UniqueKey kInvalidKey;
        return kInvalidKey;
    }

    bool isInstantiated() const { return SkToBool(fTarget); }

    /** Called when this task becomes a target of a GrRenderTask. */
    void isUsedAsTaskTarget() { ++fTaskTargetCount; }

    /** How many render tasks has this proxy been the target of? */
    int getTaskTargetCount() const { return fTaskTargetCount; }

    // If the proxy is already instantiated, return its backing GrTexture; if not, return null.
    GrSurface* peekSurface() const { return fTarget.get(); }

    // If this is a texture proxy and the proxy is already instantiated, return its backing
    // GrTexture; if not, return null.
    GrTexture* peekTexture() const { return fTarget ? fTarget->asTexture() : nullptr; }

    // If this is a render target proxy and the proxy is already instantiated, return its backing
    // GrRenderTarget; if not, return null.
    GrRenderTarget* peekRenderTarget() const {
        return fTarget ? fTarget->asRenderTarget() : nullptr;
    }

    /**
     * Does the resource count against the resource budget?
     */
    SkBudgeted isBudgeted() const { return fBudgeted; }

    /**
     * The pixel values of this proxy's surface cannot be modified (e.g. doesn't support write
     * pixels or MIP map level regen). Read-only proxies also bypass interval tracking and
     * assignment in GrResourceAllocator.
     */
    bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
    bool framebufferOnly() const {
        return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly;
    }

    /**
     * This means surface is a multisampled render target, and internally holds a non-msaa texture
     * for resolving into. The render target resolves itself by blitting into this internal texture.
     * (asTexture() might or might not return the internal texture, but if it does, we always
     * resolve the render target before accessing this texture's data.)
     */
    bool requiresManualMSAAResolve() const {
        return fSurfaceFlags & GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
    }

    /**
     * Retrieves the amount of GPU memory that will be or currently is used by this resource
     * in bytes. It is approximate since we aren't aware of additional padding or copies made
     * by the driver.
     *
     * @return the amount of GPU memory used in bytes
     */
    size_t gpuMemorySize() const {
        SkASSERT(!this->isFullyLazy());
        if (kInvalidGpuMemorySize == fGpuMemorySize) {
            fGpuMemorySize = this->onUninstantiatedGpuMemorySize();
            SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
        }
        return fGpuMemorySize;
    }

    enum class RectsMustMatch : bool {
        kNo = false,
        kYes = true
    };

    // Helper function that creates a temporary SurfaceContext to perform the copy
    // The copy is is not a render target and not multisampled.
    //
    // The intended use of this copy call is simply to copy exact pixel values from one proxy to a
    // new one. Thus, there isn't a need for a swizzle when doing the copy. The format of the copy
    // will be the same as the src. Therefore, the copy can be used in a view with the same swizzle
    // as the original for use with a given color type.
    //
    // Optionally gets the render task that performs the copy. If it is later determined that the
    // copy is not neccessaru then the task can be marked skippable using GrRenderTask::canSkip() and
    // the copy will be elided.
    static sk_sp<GrSurfaceProxy> Copy(GrRecordingContext*,
                                      sk_sp<GrSurfaceProxy> src,
                                      GrSurfaceOrigin,
                                      GrMipmapped,
                                      SkIRect srcRect,
                                      SkBackingFit,
                                      SkBudgeted,
                                      RectsMustMatch = RectsMustMatch::kNo,
                                      sk_sp<GrRenderTask>* outTask = nullptr);

    // Same as above Copy but copies the entire 'src'
    static sk_sp<GrSurfaceProxy> Copy(GrRecordingContext*,
                                      sk_sp<GrSurfaceProxy> src,
                                      GrSurfaceOrigin,
                                      GrMipmapped,
                                      SkBackingFit,
                                      SkBudgeted,
                                      sk_sp<GrRenderTask>* outTask = nullptr);

#if GR_TEST_UTILS
    int32_t testingOnly_getBackingRefCnt() const;
    GrInternalSurfaceFlags testingOnly_getFlags() const;
    SkString dump() const;
#endif

#ifdef SK_DEBUG
    void validate(GrContext_Base*) const;
    SkString getDebugName() {
        return fDebugName.isEmpty() ? SkStringPrintf("%d", this->uniqueID().asUInt()) : fDebugName;
    }
    void setDebugName(SkString name) { fDebugName = std::move(name); }
#endif

    // Provides access to functions that aren't part of the public API.
    inline GrSurfaceProxyPriv priv();
    inline const GrSurfaceProxyPriv priv() const;  // NOLINT(readability-const-return-type)

    bool isDDLTarget() const { return fIsDDLTarget; }

    GrProtected isProtected() const { return fIsProtected; }

    bool isPromiseProxy() { return fIsPromiseProxy; }

protected:
    // Deferred version - takes a new UniqueID from the shared resource/proxy pool.
    GrSurfaceProxy(const GrBackendFormat&,
                   SkISize,
                   SkBackingFit,
                   SkBudgeted,
                   GrProtected,
                   GrInternalSurfaceFlags,
                   UseAllocator);
    // Lazy-callback version - takes a new UniqueID from the shared resource/proxy pool.
    GrSurfaceProxy(LazyInstantiateCallback&&,
                   const GrBackendFormat&,
                   SkISize,
                   SkBackingFit,
                   SkBudgeted,
                   GrProtected,
                   GrInternalSurfaceFlags,
                   UseAllocator);

    // Wrapped version - shares the UniqueID of the passed surface.
    // Takes UseAllocator because even though this is already instantiated it still can participate
    // in allocation by having its backing resource recycled to other uninstantiated proxies or
    // not depending on UseAllocator.
    GrSurfaceProxy(sk_sp<GrSurface>,
                   SkBackingFit,
                   UseAllocator);

    friend class GrSurfaceProxyPriv;

    // Methods made available via GrSurfaceProxyPriv
    bool ignoredByResourceAllocator() const { return fIgnoredByResourceAllocator; }
    void setIgnoredByResourceAllocator() { fIgnoredByResourceAllocator = true; }

    void computeScratchKey(const GrCaps&, skgpu::ScratchKey*) const;

    virtual sk_sp<GrSurface> createSurface(GrResourceProvider*) const = 0;
    void assign(sk_sp<GrSurface> surface);

    sk_sp<GrSurface> createSurfaceImpl(GrResourceProvider*, int sampleCnt, GrRenderable,
                                       GrMipmapped) const;

    // Once the dimensions of a fully-lazy proxy are decided, and before it gets instantiated, the
    // client can use this optional method to specify the proxy's dimensions. (A proxy's dimensions
    // can be less than the GPU surface that backs it. e.g., SkBackingFit::kApprox.) Otherwise,
    // the proxy's dimensions will be set to match the underlying GPU surface upon instantiation.
    void setLazyDimensions(SkISize dimensions) {
        SkASSERT(this->isFullyLazy());
        SkASSERT(!dimensions.isEmpty());
        fDimensions = dimensions;
    }

    bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, GrRenderable,
                         GrMipmapped, const skgpu::UniqueKey*);

    // For deferred proxies this will be null until the proxy is instantiated.
    // For wrapped proxies it will point to the wrapped resource.
    sk_sp<GrSurface>       fTarget;

    // In many cases these flags aren't actually known until the proxy has been instantiated.
    // However, Ganesh frequently needs to change its behavior based on these settings. For
    // internally create proxies we will know these properties ahead of time. For wrapped
    // proxies we will copy the properties off of the GrSurface. For lazy proxies we force the
    // call sites to provide the required information ahead of time. At instantiation time
    // we verify that the assumed properties match the actual properties.
    GrInternalSurfaceFlags fSurfaceFlags;

private:
    // For wrapped resources, 'fFormat' and 'fDimensions' will always be filled in from the
    // wrapped resource.
    const GrBackendFormat  fFormat;
    SkISize                fDimensions;

    SkBackingFit           fFit;      // always kApprox for lazy-callback resources
                                      // always kExact for wrapped resources
    mutable SkBudgeted     fBudgeted; // always kYes for lazy-callback resources
                                      // set from the backing resource for wrapped resources
                                      // mutable bc of SkSurface/SkImage wishy-washiness
                                      // Only meaningful if fLazyInstantiateCallback is non-null.
    UseAllocator           fUseAllocator;

    const UniqueID         fUniqueID; // set from the backing resource for wrapped resources

    LazyInstantiateCallback fLazyInstantiateCallback;

    SkDEBUGCODE(void validateSurface(const GrSurface*);)
    SkDEBUGCODE(virtual void onValidateSurface(const GrSurface*) = 0;)

    static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
    SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; })

    virtual size_t onUninstantiatedGpuMemorySize() const = 0;

    virtual LazySurfaceDesc callbackDesc() const = 0;

    bool                   fIgnoredByResourceAllocator = false;
    bool                   fIsDDLTarget = false;
    bool                   fIsPromiseProxy = false;
    GrProtected            fIsProtected;

    int                     fTaskTargetCount = 0;

    // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
    // will be called but, when the proxy is deferred, it will compute the answer itself.
    // If the proxy computes its own answer that answer is checked (in debug mode) in
    // the instantiation method. The image may be shared between threads, hence atomic.
    mutable std::atomic<size_t>         fGpuMemorySize{kInvalidGpuMemorySize};
    SkDEBUGCODE(SkString   fDebugName;)
};

GR_MAKE_BITFIELD_CLASS_OPS(GrSurfaceProxy::ResolveFlags)

#endif
