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

#ifndef GrTexture_DEFINED
#define GrTexture_DEFINED

#include "include/core/SkImage.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrSurface.h"
#include "include/private/GrTypesPriv.h"

class GrTexturePriv;

class GrTexture : virtual public GrSurface {
public:
    GrTexture* asTexture() override { return this; }
    const GrTexture* asTexture() const override { return this; }

    virtual GrBackendTexture getBackendTexture() const = 0;

    /**
     * This function indicates that the texture parameters (wrap mode, filtering, ...) have been
     * changed externally to Skia.
     */
    SK_API virtual void textureParamsModified() = 0;

    /**
     * This function steals the backend texture from a uniquely owned GrTexture with no pending
     * IO, passing it out to the caller. The GrTexture is deleted in the process.
     *
     * Note that if the GrTexture is not uniquely owned (no other refs), or has pending IO, this
     * function will fail.
     */
    static bool StealBackendTexture(sk_sp<GrTexture>,
                                    GrBackendTexture*,
                                    SkImage::BackendTextureReleaseProc*);

#ifdef SK_DEBUG
    void validate() const {
        this->INHERITED::validate();
    }
#endif

    /** See addIdleProc. */
    enum class IdleState {
        kFlushed,
        kFinished
    };
    /**
     * Installs a proc on this texture. It will be called when the texture becomes "idle". There
     * are two types of idle states as indicated by IdleState. For managed backends (e.g. GL where
     * a driver typically handles CPU/GPU synchronization of resource access) there is no difference
     * between the two. They both mean "all work related to the resource has been flushed to the
     * backend API and the texture is not owned outside the resource cache".
     *
     * If the API is unmanaged (e.g. Vulkan) then kFinished has the additional constraint that the
     * work flushed to the GPU is finished.
     */
    virtual void addIdleProc(sk_sp<GrRefCntedCallback> idleProc, IdleState) {
        // This is the default implementation for the managed case where the IdleState can be
        // ignored. Unmanaged backends, e.g. Vulkan, must override this to consider IdleState.
        fIdleProcs.push_back(std::move(idleProc));
    }
    /** Helper version of addIdleProc that creates the ref-counted wrapper. */
    void addIdleProc(GrRefCntedCallback::Callback callback,
                     GrRefCntedCallback::Context context,
                     IdleState state) {
        this->addIdleProc(sk_make_sp<GrRefCntedCallback>(callback, context), state);
    }

    /** Access methods that are only to be used within Skia code. */
    inline GrTexturePriv texturePriv();
    inline const GrTexturePriv texturePriv() const;

protected:
    GrTexture(GrGpu*, const SkISize&, GrPixelConfig, GrProtected, GrTextureType, GrMipMapsStatus);

    virtual bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) = 0;

    SkTArray<sk_sp<GrRefCntedCallback>> fIdleProcs;

    void willRemoveLastRefOrPendingIO() override {
        // We're about to be idle in the resource cache. Do our part to trigger the idle callbacks.
        fIdleProcs.reset();
    }

private:
    void computeScratchKey(GrScratchKey*) const override;
    size_t onGpuMemorySize() const override;
    void markMipMapsDirty();
    void markMipMapsClean();

    GrTextureType                 fTextureType;
    GrMipMapsStatus               fMipMapsStatus;
    int                           fMaxMipMapLevel;
    friend class GrTexturePriv;

    typedef GrSurface INHERITED;
};

#endif
