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

#ifndef SkImage_Base_DEFINED
#define SkImage_Base_DEFINED

#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "src/core/SkMipmap.h"
#include <atomic>

#if SK_SUPPORT_GPU
#include "include/private/SkTDArray.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/SkGr.h"

class GrTexture;
#endif

#ifdef SK_GRAPHITE_ENABLED
#include "src/gpu/graphite/TextureProxyView.h"
#endif

#include <new>

class GrDirectContext;
class GrImageContext;
class GrSamplerState;
class SkCachedData;

enum {
    kNeedNewImageUniqueID = 0
};

class SkImage_Base : public SkImage {
public:
    ~SkImage_Base() override;

    virtual bool onPeekPixels(SkPixmap*) const { return false; }

    virtual const SkBitmap* onPeekBitmap() const { return nullptr; }

    virtual bool onReadPixels(GrDirectContext*,
                              const SkImageInfo& dstInfo,
                              void* dstPixels,
                              size_t dstRowBytes,
                              int srcX,
                              int srcY,
                              CachingHint) const = 0;

    virtual bool onHasMipmaps() const = 0;

    virtual SkMipmap* onPeekMips() const { return nullptr; }

    sk_sp<SkMipmap> refMips() const {
        return sk_ref_sp(this->onPeekMips());
    }

    /**
     * Default implementation does a rescale/read and then calls the callback.
     */
    virtual void onAsyncRescaleAndReadPixels(const SkImageInfo&,
                                             const SkIRect& srcRect,
                                             RescaleGamma,
                                             RescaleMode,
                                             ReadPixelsCallback,
                                             ReadPixelsContext) const;
    /**
     * Default implementation does a rescale/read/yuv conversion and then calls the callback.
     */
    virtual void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
                                                   sk_sp<SkColorSpace> dstColorSpace,
                                                   const SkIRect& srcRect,
                                                   const SkISize& dstSize,
                                                   RescaleGamma,
                                                   RescaleMode,
                                                   ReadPixelsCallback,
                                                   ReadPixelsContext) const;

    virtual GrImageContext* context() const { return nullptr; }

    /** this->context() try-casted to GrDirectContext. Useful for migrations – avoid otherwise! */
    GrDirectContext* directContext() const;

#if SK_SUPPORT_GPU
    virtual GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) const {
        return GrSemaphoresSubmitted::kNo;
    }

    // Returns a GrSurfaceProxyView representation of the image, if possible. This also returns
    // a color type. This may be different than the image's color type when the image is not
    // texture-backed and the capabilities of the GPU require a data type conversion to put
    // the data in a texture.
    std::tuple<GrSurfaceProxyView, GrColorType> asView(
            GrRecordingContext* context,
            GrMipmapped mipmapped,
            GrImageTexGenPolicy policy = GrImageTexGenPolicy::kDraw) const;

    /**
     * Returns a GrFragmentProcessor that can be used with the passed GrRecordingContext to
     * draw the image. SkSamplingOptions indicates the filter and SkTileMode[] indicates the x and
     * y tile modes. The passed matrix is applied to the coordinates before sampling the image.
     * Optional 'subset' indicates whether the tile modes should be applied to a subset of the image
     * Optional 'domain' is a bound on the coordinates of the image that will be required and can be
     * used to optimize the shader if 'subset' is also specified.
     */
    std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
                                                             SkSamplingOptions,
                                                             const SkTileMode[2],
                                                             const SkMatrix&,
                                                             const SkRect* subset = nullptr,
                                                             const SkRect* domain = nullptr) const;

    virtual bool isYUVA() const { return false; }

    // If this image is the current cached image snapshot of a surface then this is called when the
    // surface is destroyed to indicate no further writes may happen to surface backing store.
    virtual void generatingSurfaceIsDeleted() {}

    virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
                                                 GrSurfaceOrigin* origin) const;
#endif
#ifdef SK_GRAPHITE_ENABLED
    // Returns a TextureProxyView representation of the image, if possible. This also returns
    // a color type. This may be different than the image's color type when the image is not
    // texture-backed and the capabilities of the GPU require a data type conversion to put
    // the data in a texture.
    std::tuple<skgpu::graphite::TextureProxyView, SkColorType> asView(
            skgpu::graphite::Recorder*,
            skgpu::graphite::Mipmapped mipmapped) const;
#endif

    virtual bool onPinAsTexture(GrRecordingContext*) const { return false; }
    virtual void onUnpinAsTexture(GrRecordingContext*) const {}
    virtual bool isPinnedOnContext(GrRecordingContext*) const { return false; }

    // return a read-only copy of the pixels. We promise to not modify them,
    // but only inspect them (or encode them).
    virtual bool getROPixels(GrDirectContext*, SkBitmap*,
                             CachingHint = kAllow_CachingHint) const = 0;

    virtual sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const = 0;

    virtual sk_sp<SkData> onRefEncoded() const { return nullptr; }

    virtual bool onAsLegacyBitmap(GrDirectContext*, SkBitmap*) const;

    // True for picture-backed and codec-backed
    virtual bool onIsLazyGenerated() const { return false; }

    // True for images instantiated by Ganesh in GPU memory
    virtual bool isGaneshBacked() const { return false; }

    // True for images instantiated by Graphite in GPU memory
    virtual bool isGraphiteBacked() const { return false; }

    // Amount of texture memory used by texture-backed images.
    virtual size_t onTextureSize() const { return 0; }

    // Call when this image is part of the key to a resourcecache entry. This allows the cache
    // to know automatically those entries can be purged when this SkImage deleted.
    virtual void notifyAddedToRasterCache() const {
        fAddedToRasterCache.store(true);
    }

    virtual bool onIsValid(GrRecordingContext*) const = 0;

    virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>,
                                                        GrDirectContext*) const = 0;

    virtual sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const = 0;

    // on failure, returns nullptr
    virtual sk_sp<SkImage> onMakeWithMipmaps(sk_sp<SkMipmap>) const {
        return nullptr;
    }

protected:
    SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);

#if SK_SUPPORT_GPU
    // Utility for making a copy of an existing view when the GrImageTexGenPolicy is not kDraw.
    static GrSurfaceProxyView CopyView(GrRecordingContext*,
                                       GrSurfaceProxyView src,
                                       GrMipmapped,
                                       GrImageTexGenPolicy,
                                       std::string_view label);

    static std::unique_ptr<GrFragmentProcessor> MakeFragmentProcessorFromView(GrRecordingContext*,
                                                                              GrSurfaceProxyView,
                                                                              SkAlphaType,
                                                                              SkSamplingOptions,
                                                                              const SkTileMode[2],
                                                                              const SkMatrix&,
                                                                              const SkRect* subset,
                                                                              const SkRect* domain);

    /**
     * Returns input view if it is already mipmapped. Otherwise, attempts to make a mipmapped view
     * with the same contents. If the mipmapped copy is successfully created it will be cached
     * using the image unique ID. A subsequent call with the same unique ID will return the cached
     * view if it has not been purged. The view is cached with a key domain specific to this
     * function.
     */
    static GrSurfaceProxyView FindOrMakeCachedMipmappedView(GrRecordingContext*,
                                                            GrSurfaceProxyView,
                                                            uint32_t imageUniqueID);
#endif

private:
#if SK_SUPPORT_GPU
    virtual std::tuple<GrSurfaceProxyView, GrColorType> onAsView(
            GrRecordingContext*,
            GrMipmapped,
            GrImageTexGenPolicy policy) const = 0;

    virtual std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(
            GrRecordingContext*,
            SkSamplingOptions,
            const SkTileMode[2],
            const SkMatrix&,
            const SkRect* subset,
            const SkRect* domain) const = 0;
#endif
#ifdef SK_GRAPHITE_ENABLED
    virtual std::tuple<skgpu::graphite::TextureProxyView, SkColorType> onAsView(
            skgpu::graphite::Recorder*,
            skgpu::graphite::Mipmapped mipmapped) const {
        return {}; // TODO: once incompatible derived classes are removed make this pure virtual
    }
#endif
    // Set true by caches when they cache content that's derived from the current pixels.
    mutable std::atomic<bool> fAddedToRasterCache;

    using INHERITED = SkImage;
};

static inline SkImage_Base* as_IB(SkImage* image) {
    return static_cast<SkImage_Base*>(image);
}

static inline SkImage_Base* as_IB(const sk_sp<SkImage>& image) {
    return static_cast<SkImage_Base*>(image.get());
}

static inline const SkImage_Base* as_IB(const SkImage* image) {
    return static_cast<const SkImage_Base*>(image);
}

#if SK_SUPPORT_GPU
inline GrSurfaceProxyView SkImage_Base::CopyView(GrRecordingContext* context,
                                                 GrSurfaceProxyView src,
                                                 GrMipmapped mipmapped,
                                                 GrImageTexGenPolicy policy,
                                                 std::string_view label) {
    SkBudgeted budgeted = policy == GrImageTexGenPolicy::kNew_Uncached_Budgeted
                          ? SkBudgeted::kYes
                          : SkBudgeted::kNo;
    return GrSurfaceProxyView::Copy(context,
                                    std::move(src),
                                    mipmapped,
                                    SkBackingFit::kExact,
                                    budgeted,
                                    /*label=*/label);
}
#endif

#endif
