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

#ifndef skgpu_graphite_Surface_Graphite_DEFINED
#define skgpu_graphite_Surface_Graphite_DEFINED

#include "include/core/SkRecorder.h"
#include "src/image/SkSurface_Base.h"

#include "include/gpu/GpuTypes.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/TextureProxyView.h"

namespace skgpu::graphite {

class Context;
class Device;
class DrawContext;
class Image;
class Recorder;
class TextureProxy;

class Surface final : public SkSurface_Base {
public:
    // Convenience factory to create a Device, instantiate its target proxy and return as a Surface.
    static sk_sp<Surface> Make(Recorder* recorder,
                               const SkImageInfo& info,
                               std::string_view label,
                               Budgeted budgeted,
                               Mipmapped mipmapped = Mipmapped::kNo,
                               SkBackingFit backingFit = SkBackingFit::kExact,
                               const SkSurfaceProps* props = nullptr) {
        return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit, props,
                    LoadOp::kClear, /*registerWithRecorder=*/true);
    }
    // Make a surface that is not registered with the provided recorder. This surface should be
    // short-lived and it must be flushed manually for its draw commands to be recorded. Most
    // scratch surfaces will be budgeted, but if the underlying texture is being returned as a
    // client-owned image, that may not be the case.
    static sk_sp<Surface> MakeScratch(Recorder* recorder,
                                      const SkImageInfo& info,
                                      std::string_view label,
                                      Budgeted budgeted = Budgeted::kYes,
                                      Mipmapped mipmapped = Mipmapped::kNo,
                                      SkBackingFit backingFit = SkBackingFit::kApprox) {
        return Make(recorder, info, std::move(label), budgeted, mipmapped, backingFit,
                    /*props=*/nullptr, LoadOp::kDiscard, /*registerWithRecorder=*/false);
    }

    Surface(sk_sp<Device>);
    ~Surface() override;

    // From SkSurface.h
    SkImageInfo imageInfo() const override;

    // From SkSurface_Base.h
    SkSurface_Base::Type type() const override { return SkSurface_Base::Type::kGraphite; }

    Recorder* onGetRecorder() const override;
    SkRecorder* onGetBaseRecorder() const override;
    SkCanvas* onNewCanvas() override;
    sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override;
    sk_sp<SkImage> onNewImageSnapshot(const SkIRect* subset) override;
    sk_sp<SkImage> onMakeTemporaryImage() override;
    void onWritePixels(const SkPixmap&, int x, int y) override;
    void onAsyncRescaleAndReadPixels(const SkImageInfo& info,
                                     SkIRect srcRect,
                                     RescaleGamma rescaleGamma,
                                     RescaleMode rescaleMode,
                                     ReadPixelsCallback callback,
                                     ReadPixelsContext context) override;
    void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
                                           bool readAlpha,
                                           sk_sp<SkColorSpace> dstColorSpace,
                                           SkIRect srcRect,
                                           SkISize dstSize,
                                           RescaleGamma rescaleGamma,
                                           RescaleMode,
                                           ReadPixelsCallback callback,
                                           ReadPixelsContext context) override;
    bool onCopyOnWrite(ContentChangeMode) override;
    sk_sp<const SkCapabilities> onCapabilities() override;

    TextureProxyView readSurfaceView() const;
    sk_sp<Image> asImage() const;
    sk_sp<Image> makeImageCopy(const SkIRect* subset, Mipmapped) const;
    TextureProxy* backingTextureProxy() const;

    void flushToDrawContext(DrawContext*);

private:
    // Regular and scratch surfaces differ by initial clear and if they are registered or not,
    // otherwise are constructed the same.
    static sk_sp<Surface> Make(Recorder* recorder,
                               const SkImageInfo&,
                               std::string_view label,
                               Budgeted,
                               Mipmapped,
                               SkBackingFit,
                               const SkSurfaceProps* props,
                               LoadOp initialLoadOp,
                               bool registerWithRecorder);

    sk_sp<Device> fDevice;
    sk_sp<Image>  fImageView; // the image object returned by asImage()

    friend void Flush(SkSurface*);
};

// TODO: The long-term for the public API around surfaces and flushing/submitting will likely
// be replaced with explicit control over Recorders and submitting Recordings to the Context
// directly. For now, internal tools often rely on surface/canvas flushing to control what's
// being timed (nanobench or viewer's stats layer), so we flush any pending draws to a DrawPass.
// While this won't measure actual conversion of the task list to backend command buffers, that
// should be fairly negligible since most of the work is handled in DrawPass::Make().
// Additionally flushing pending work here ensures we don't batch across or clear prior recorded
// work when looping in a benchmark, as the controlling code expects.
void Flush(sk_sp<SkSurface> surface);
void Flush(SkSurface* surface);
} // namespace skgpu::graphite

#endif // skgpu_graphite_Surface_Graphite_DEFINED
