1/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef skgpu_DrawContext_DEFINED
9#define skgpu_DrawContext_DEFINED
10
11#include "include/core/SkImageInfo.h"
12#include "include/core/SkRefCnt.h"
13
14#include "experimental/graphite/src/DrawList.h"
15#include "experimental/graphite/src/DrawOrder.h"
16#include "experimental/graphite/src/DrawTypes.h"
17
18#include <vector>
19
20namespace skgpu {
21
22class BoundsManager;
23class Recorder;
24class Shape;
25class Transform;
26
27class DrawPass;
28class Task;
29class TextureProxy;
30
31/**
32 * DrawContext records draw commands into a specific Surface, via a general task graph
33 * representing GPU work and their inter-dependencies.
34 */
35class DrawContext final : public SkRefCnt {
36public:
37    static sk_sp<DrawContext> Make(sk_sp<TextureProxy> target,
38                                   sk_sp<SkColorSpace> colorSpace,
39                                   SkColorType colorType,
40                                   SkAlphaType alphaType);
41
42    ~DrawContext() override;
43
44    const SkImageInfo&  imageInfo() const { return fImageInfo;    }
45    TextureProxy* target()                { return fTarget.get(); }
46    const TextureProxy* target()    const { return fTarget.get(); }
47
48    int pendingDrawCount() const { return fPendingDraws->drawCount(); }
49
50    // TODO: need color/depth clearing functions (so DCL will probably need those too)
51
52    void clear(const SkColor4f& clearColor);
53
54    void stencilAndFillPath(const Transform& localToDevice,
55                            const Shape& shape,
56                            const Clip& clip,
57                            DrawOrder order,
58                            const PaintParams* paint);
59
60    void fillConvexPath(const Transform& localToDevice,
61                        const Shape& shape,
62                        const Clip& clip,
63                        DrawOrder order,
64                        const PaintParams* paint);
65
66    void strokePath(const Transform& localToDevice,
67                    const Shape& shape,
68                    const StrokeParams& stroke,
69                    const Clip& clip,
70                    DrawOrder order,
71                    const PaintParams* paint);
72
73    // Ends the current DrawList being accumulated by the SDC, converting it into an optimized and
74    // immutable DrawPass. The DrawPass will be ordered after any other snapped DrawPasses or
75    // appended DrawPasses from a child SDC. A new DrawList is started to record subsequent drawing
76    // operations.
77    //
78    // If 'occlusionCuller' is null, then culling is skipped when converting the DrawList into a
79    // DrawPass.
80    // TBD - should this also return the task so the caller can point to it with its own
81    // dependencies? Or will that be mostly automatic based on draws and proxy refs?
82    void snapDrawPass(Recorder*, const BoundsManager* occlusionCuller);
83
84    // TBD: snapRenderPassTask() might not need to be public, and could be spec'ed to require that
85    // snapDrawPass() must have been called first. A lot of it will depend on how the task graph is
86    // managed.
87
88    // Ends the current DrawList if needed, as in 'snapDrawPass', and moves the new DrawPass and all
89    // prior accumulated DrawPasses into a RenderPassTask that can be drawn and depended on. The
90    // caller is responsible for configuring the returned Tasks's dependencies.
91    //
92    // Returns null if there are no pending commands or draw passes to move into a task.
93    sk_sp<Task> snapRenderPassTask(Recorder*, const BoundsManager* occlusionCuller);
94
95private:
96    DrawContext(sk_sp<TextureProxy>, const SkImageInfo&);
97
98    sk_sp<TextureProxy> fTarget;
99    SkImageInfo fImageInfo;
100
101    // Stores the most immediately recorded draws into the SDC's surface. This list is mutable and
102    // can be appended to, or have its commands rewritten if they are inlined into a parent SDC.
103    std::unique_ptr<DrawList> fPendingDraws;
104    // Load and store information for the current pending draws.
105    LoadOp fPendingLoadOp = LoadOp::kLoad;
106    StoreOp fPendingStoreOp = StoreOp::kStore;
107    std::array<float, 4> fPendingClearColor = { 0, 0, 0, 0 };
108
109    // Stores previously snapped DrawPasses of this SDC, or inlined child SDCs whose content
110    // couldn't have been copied directly to fPendingDraws. While each DrawPass is immutable, the
111    // list of DrawPasses is not final until there is an external dependency on the SDC's content
112    // that requires it to be resolved as its own render pass (vs. inlining the SDC's passes into a
113    // parent's render pass).
114    // TODO: It will be easier to debug/understand the DrawPass structure of a context if
115    // consecutive DrawPasses to the same target are stored in a DrawPassChain. A DrawContext with
116    // multiple DrawPassChains is then clearly accumulating subpasses across multiple targets.
117    std::vector<std::unique_ptr<DrawPass>> fDrawPasses;
118};
119
120} // namespace skgpu
121
122#endif // skgpu_DrawContext_DEFINED
123