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_DrawPass_DEFINED
9#define skgpu_DrawPass_DEFINED
10
11#include "experimental/graphite/src/DrawTypes.h"
12#include "include/core/SkColor.h"
13#include "include/core/SkRect.h"
14#include "include/core/SkRefCnt.h"
15
16#include <memory>
17
18namespace skgpu {
19
20class BoundsManager;
21class CommandBuffer;
22class DrawList;
23class Recorder;
24class TextureProxy;
25
26/**
27 * DrawPass is analogous to a subpass, storing the drawing operations in the order they are stored
28 * in the eventual command buffer, as well as the surface proxy the operations are intended for.
29 * DrawPasses are grouped into a RenderPassTask for execution within a single render pass if the
30 * subpasses are compatible with each other.
31 *
32 * Unlike DrawList, DrawPasses are immutable and represent as closely as possible what will be
33 * stored in the command buffer while being flexible as to how the pass is incorporated. Depending
34 * on the backend, it may even be able to write accumulated vertex and uniform data directly to
35 * mapped GPU memory, although that is the extent of the CPU->GPU work they perform before they are
36 * executed by a RenderPassTask.
37 */
38class DrawPass {
39public:
40    ~DrawPass();
41
42    // TODO: Replace SDC with the SDC's surface proxy view
43    static std::unique_ptr<DrawPass> Make(Recorder*,
44                                          std::unique_ptr<DrawList>,
45                                          sk_sp<TextureProxy>,
46                                          std::pair<LoadOp, StoreOp>,
47                                          std::array<float, 4> clearColor,
48                                          const BoundsManager* occlusionCuller);
49
50    // Defined relative to the top-left corner of the surface the DrawPass renders to, and is
51    // contained within its dimensions.
52    const SkIRect&      bounds() const { return fBounds;       }
53    TextureProxy* target() const { return fTarget.get(); }
54    std::pair<LoadOp, StoreOp> ops() const { return fOps; }
55    std::array<float, 4> clearColor() const { return fClearColor; }
56
57    bool requiresDstTexture() const { return false;            }
58    bool requiresStencil()    const { return fRequiresStencil; }
59    bool requiresMSAA()       const { return fRequiresMSAA;    }
60
61    size_t vertexBufferSize()  const { return 0; }
62    size_t uniformBufferSize() const { return 0; }
63
64    // TODO: Real return types, but it seems useful for DrawPass to report these as sets so that
65    // task execution can compile necessary programs and track resources within a render pass.
66    // Maybe these won't need to be exposed and RenderPassTask can do it per command as needed when
67    // it iterates over the DrawPass contents.
68    void samplers() const {}
69    void programs() const {}
70
71    // Transform this DrawPass into commands issued to the CommandBuffer. Assumes that the buffer
72    // has already begun a correctly configured render pass matching this pass's target.
73    void addCommands(CommandBuffer* buffer) const;
74
75private:
76    class SortKey;
77
78    DrawPass(sk_sp<TextureProxy> target,
79             const SkIRect& bounds,
80             std::pair<LoadOp, StoreOp> ops,
81             std::array<float, 4> clearColor,
82             bool requiresStencil,
83             bool requiresMSAA);
84
85    sk_sp<TextureProxy> fTarget;
86    SkIRect             fBounds;
87    std::pair<LoadOp, StoreOp> fOps;
88    std::array<float, 4> fClearColor;
89
90    bool fRequiresStencil;
91    bool fRequiresMSAA;
92};
93
94} // namespace skgpu
95
96#endif // skgpu_DrawPass_DEFINED
97