/*
 * 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_DrawContext_DEFINED
#define skgpu_graphite_DrawContext_DEFINED

#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceProps.h"

#include "src/gpu/graphite/AttachmentTypes.h"
#include "src/gpu/graphite/DrawList.h"
#include "src/gpu/graphite/DrawOrder.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/UploadTask.h"

#include <vector>

#ifdef SK_ENABLE_PIET_GPU
#include "src/gpu/graphite/PietRenderTask.h"
namespace skgpu::piet {
class Scene;
}
#endif

class SkPixmap;

namespace skgpu::graphite {

class Geometry;
class Recorder;
class Transform;

class AtlasManager;
class Caps;
class DrawPass;
class Task;
class TextureProxy;
class TextureProxyView;

/**
 * DrawContext records draw commands into a specific Surface, via a general task graph
 * representing GPU work and their inter-dependencies.
 */
class DrawContext final : public SkRefCnt {
public:
    static sk_sp<DrawContext> Make(sk_sp<TextureProxy> target,
                                   SkISize deviceSize,
                                   const SkColorInfo&,
                                   const SkSurfaceProps&);

    ~DrawContext() override;

    const SkImageInfo&  imageInfo() const { return fImageInfo;    }
    TextureProxy* target()                { return fTarget.get(); }
    const TextureProxy* target()    const { return fTarget.get(); }

    TextureProxyView readSurfaceView(const Caps*);

    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }

    int pendingDrawCount() const { return fPendingDraws->drawCount(); }

    void clear(const SkColor4f& clearColor);

    void recordDraw(const Renderer* renderer,
                    const Transform& localToDevice,
                    const Geometry& geometry,
                    const Clip& clip,
                    DrawOrder ordering,
                    const PaintParams* paint,
                    const StrokeStyle* stroke);

    bool recordTextUploads(AtlasManager*);
    bool recordUpload(Recorder* recorder,
                      sk_sp<TextureProxy> targetProxy,
                      const SkColorInfo& srcColorInfo,
                      const SkColorInfo& dstColorInfo,
                      const std::vector<MipLevel>& levels,
                      const SkIRect& dstRect,
                      std::unique_ptr<ConditionalUploadContext>);

#ifdef SK_ENABLE_PIET_GPU
    bool recordPietSceneRender(Recorder* recorder,
                               sk_sp<TextureProxy> targetProxy,
                               sk_sp<const skgpu::piet::Scene> pietScene);
#endif

    // Ends the current DrawList being accumulated by the SDC, converting it into an optimized and
    // immutable DrawPass. The DrawPass will be ordered after any other snapped DrawPasses or
    // appended DrawPasses from a child SDC. A new DrawList is started to record subsequent drawing
    // operations.
    //
    // TBD - Should this take a special occluder list to filter the DrawList?
    // TBD - should this also return the task so the caller can point to it with its own
    // dependencies? Or will that be mostly automatic based on draws and proxy refs?
    void snapDrawPass(Recorder*);

    // TBD: snapRenderPassTask() might not need to be public, and could be spec'ed to require that
    // snapDrawPass() must have been called first. A lot of it will depend on how the task graph is
    // managed.

    // Ends the current DrawList if needed, as in 'snapDrawPass', and moves the new DrawPass and all
    // prior accumulated DrawPasses into a RenderPassTask that can be drawn and depended on. The
    // caller is responsible for configuring the returned Tasks's dependencies.
    //
    // Returns null if there are no pending commands or draw passes to move into a task.
    sk_sp<Task> snapRenderPassTask(Recorder*);

    // Ends the current UploadList if needed, and moves the accumulated Uploads into an UploadTask
    // that can be drawn and depended on. The caller is responsible for configuring the returned
    // Tasks's dependencies.
    //
    // Returns null if there are no pending uploads to move into a task.
    //
    // TODO: see if we can merge transfers into this
    sk_sp<Task> snapUploadTask(Recorder*);

#ifdef SK_ENABLE_PIET_GPU
    sk_sp<Task> snapPietRenderTask(Recorder*);
#endif

private:
    DrawContext(sk_sp<TextureProxy>, const SkImageInfo&, const SkSurfaceProps&);

    sk_sp<TextureProxy> fTarget;
    SkImageInfo fImageInfo;
    const SkSurfaceProps fSurfaceProps;

    // Stores the most immediately recorded draws into the SDC's surface. This list is mutable and
    // can be appended to, or have its commands rewritten if they are inlined into a parent SDC.
    std::unique_ptr<DrawList> fPendingDraws;
    // Load and store information for the current pending draws.
    LoadOp fPendingLoadOp = LoadOp::kLoad;
    StoreOp fPendingStoreOp = StoreOp::kStore;
    std::array<float, 4> fPendingClearColor = { 0, 0, 0, 0 };

    // Stores previously snapped DrawPasses of this DC, or inlined child DCs whose content
    // couldn't have been copied directly to fPendingDraws. While each DrawPass is immutable, the
    // list of DrawPasses is not final until there is an external dependency on the SDC's content
    // that requires it to be resolved as its own render pass (vs. inlining the SDC's passes into a
    // parent's render pass).
    // TODO: It will be easier to debug/understand the DrawPass structure of a context if
    // consecutive DrawPasses to the same target are stored in a DrawPassChain. A DrawContext with
    // multiple DrawPassChains is then clearly accumulating subpasses across multiple targets.
    std::vector<std::unique_ptr<DrawPass>> fDrawPasses;

    // Stores the most immediately recorded uploads into Textures. This list is mutable and
    // can be appended to, or have its commands rewritten if they are inlined into a parent DC.
    std::unique_ptr<UploadList> fPendingUploads;

#ifdef SK_ENABLE_PIET_GPU
    std::vector<PietRenderInstance> fPendingPietRenders;
#endif
};

} // namespace skgpu::graphite

#endif // skgpu_graphite_DrawContext_DEFINED
