• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_graphite_DrawContext_DEFINED
9 #define skgpu_graphite_DrawContext_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkSurfaceProps.h"
14 #include "include/private/base/SkTArray.h"
15 
16 #include "src/gpu/graphite/DrawList.h"
17 #include "src/gpu/graphite/DrawOrder.h"
18 #include "src/gpu/graphite/DrawTypes.h"
19 #include "src/gpu/graphite/ResourceTypes.h"
20 #include "src/gpu/graphite/TextureProxyView.h"
21 #include "src/gpu/graphite/task/UploadTask.h"
22 
23 #include <vector>
24 
25 class SkPixmap;
26 
27 namespace skgpu::graphite {
28 
29 class Geometry;
30 class Recorder;
31 class Transform;
32 
33 class Caps;
34 class ComputePathAtlas;
35 class DrawTask;
36 class PathAtlas;
37 class Task;
38 class TextureProxy;
39 
40 /**
41  * DrawContext records draw commands into a specific Surface, via a general task graph
42  * representing GPU work and their inter-dependencies.
43  */
44 class DrawContext final : public SkRefCnt {
45 public:
46     static sk_sp<DrawContext> Make(const Caps* caps,
47                                    sk_sp<TextureProxy> target,
48                                    SkISize deviceSize,
49                                    const SkColorInfo&,
50                                    const SkSurfaceProps&);
51 
52     ~DrawContext() override;
53 
imageInfo()54     const SkImageInfo& imageInfo() const { return fImageInfo;    }
colorInfo()55     const SkColorInfo& colorInfo() const { return fImageInfo.colorInfo(); }
target()56     TextureProxy* target()                { return fTarget.get(); }
target()57     const TextureProxy* target()    const { return fTarget.get(); }
refTarget()58     sk_sp<TextureProxy> refTarget() const { return fTarget; }
59 
60     // May be null if the target is not texturable.
readSurfaceView()61     const TextureProxyView& readSurfaceView() const { return fReadView; }
62 
surfaceProps()63     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
64 
pendingRenderSteps()65     int pendingRenderSteps() const { return fPendingDraws->renderStepCount(); }
66 
67     void clear(const SkColor4f& clearColor);
68     void discard();
69 
70     void recordDraw(const Renderer* renderer,
71                     const Transform& localToDevice,
72                     const Geometry& geometry,
73                     const Clip& clip,
74                     DrawOrder ordering,
75                     const PaintParams* paint,
76                     const StrokeStyle* stroke);
77 
78     bool recordUpload(Recorder* recorder,
79                       sk_sp<TextureProxy> targetProxy,
80                       const SkColorInfo& srcColorInfo,
81                       const SkColorInfo& dstColorInfo,
82                       const std::vector<MipLevel>& levels,
83                       const SkIRect& dstRect,
84                       std::unique_ptr<ConditionalUploadContext>);
85 
86     // Add a Task that will be executed *before* any of the pending draws and uploads are
87     // executed as part of the next flush(). Dependency
88     void recordDependency(sk_sp<Task>);
89 
90     // Returns the transient path atlas that uses compute to accumulate coverage masks for atlas
91     // draws recorded to this SDC. The atlas gets created lazily upon request. Returns nullptr
92     // if compute path generation is not supported.
93     PathAtlas* getComputePathAtlas(Recorder*);
94 
95     // Moves all accumulated pending recorded operations (draws and uploads), and any other
96     // dependent tasks into the DrawTask currently being built.
97     void flush(Recorder*);
98 
99     // Flushes (if needed) and completes the current DrawTask, returning it to the caller.
100     // Subsequent recorded operations will be added to a new DrawTask.
101     sk_sp<Task> snapDrawTask(Recorder*);
102 
103     // Returns the dst read strategy to use when/if a paint requires a dst read
dstReadStrategy()104     DstReadStrategy dstReadStrategy() const { return fDstReadStrategy; }
105 
106 private:
107     DrawContext(const Caps*, sk_sp<TextureProxy>, const SkImageInfo&, const SkSurfaceProps&);
108 
109     sk_sp<TextureProxy> fTarget;
110     TextureProxyView fReadView;
111     SkImageInfo fImageInfo;
112     const SkSurfaceProps fSurfaceProps;
113 
114     // Does *not* reflect whether a dst read is needed by the DrawLists - simply specifies the
115     // strategy to use should any encountered paint require it.
116     DstReadStrategy fDstReadStrategy;
117 
118     // The in-progress DrawTask that will be snapped and returned when some external requirement
119     // must depend on the contents of this DrawContext's target. As higher-level Skia operations
120     // are recorded, it can be necessary to flush pending draws and uploads into the task list.
121     // This provides a place to reset scratch textures or buffers as their previous state will have
122     // been consumed by the flushed tasks rendering to this DrawContext's target.
123     sk_sp<DrawTask> fCurrentDrawTask;
124 
125     // Stores the most immediately recorded draws and uploads into the DrawContext's target. These
126     // are collected outside of the DrawTask so that encoder switches can be minimized when
127     // flushing.
128     std::unique_ptr<DrawList> fPendingDraws;
129     std::unique_ptr<UploadList> fPendingUploads;
130     // Load and store information for the current pending draws.
131     LoadOp fPendingLoadOp = LoadOp::kLoad;
132     StoreOp fPendingStoreOp = StoreOp::kStore;
133     std::array<float, 4> fPendingClearColor = { 0, 0, 0, 0 };
134 
135     // Accumulates atlas coverage masks generated by compute dispatches that are required by one or
136     // more entries in `fPendingDraws`. When pending draws are snapped into a new DrawPass, a
137     // compute dispatch group gets recorded which schedules the accumulated masks to get drawn into
138     // an atlas texture. The accumulated masks are then cleared which frees up the atlas for
139     // future draws.
140     //
141     // TODO: Currently every PathAtlas contains a single texture. If multiple snapped draw
142     // passes resulted in multiple ComputePathAtlas dispatch groups, the later dispatches would
143     // overwrite the atlas texture since all compute tasks are scheduled before render tasks. This
144     // is currently not an issue since there is only one DrawPass per flush but we may want to
145     // either support one atlas texture per DrawPass or record the dispatches once per
146     // RenderPassTask rather than DrawPass.
147     std::unique_ptr<ComputePathAtlas> fComputePathAtlas;
148 };
149 
150 } // namespace skgpu::graphite
151 
152 #endif // skgpu_graphite_DrawContext_DEFINED
153