Flutter Engine
The Flutter Engine
Device.h
Go to the documentation of this file.
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_Device_DEFINED
9#define skgpu_graphite_Device_DEFINED
10
14#include "src/core/SkDevice.h"
21
22enum class SkBackingFit;
23class SkStrokeRec;
24
25namespace skgpu::graphite {
26
27class PathAtlas;
28class BoundsManager;
29class Clip;
30class Context;
31class DrawContext;
32enum class DstReadRequirement;
33class Geometry;
34class Image;
35enum class LoadOp : uint8_t;
36class PaintParams;
37class Recorder;
38class Renderer;
39class Shape;
40class StrokeStyle;
41class Task;
42class TextureProxy;
43class TextureProxyView;
44
45class Device final : public SkDevice {
46public:
47 ~Device() override;
48
49 // If 'registerWithRecorder' is false, it is meant to be a short-lived Device that is managed
50 // by the caller within a limited scope (such that it is guaranteed to go out of scope before
51 // the Recorder can be snapped).
54 SkISize deviceSize,
55 const SkColorInfo&,
56 const SkSurfaceProps&,
57 LoadOp initialLoadOp,
58 bool registerWithRecorder=true);
59 // Convenience factory to create the underlying TextureProxy based on the configuration provided
61 const SkImageInfo&,
65 const SkSurfaceProps&,
66 LoadOp initialLoadOp,
67 std::string_view label,
68 bool registerWithRecorder=true);
69
70 Device* asGraphiteDevice() override { return this; }
71
72 Recorder* recorder() const override { return fRecorder; }
73 // This call is triggered from the Recorder on its registered Devices. It is typically called
74 // when the Recorder is abandoned or deleted.
75 void abandonRecorder() { fRecorder = nullptr; }
76
77 // Ensures clip elements are drawn that will clip previous draw calls, snaps all pending work
78 // from the DrawContext as a RenderPassTask and records it in the Device's recorder.
80
82
83 // Flushes any pending work to the recorder and then deregisters and abandons the recorder.
84 void setImmutable() override;
85
86 SkStrikeDeviceInfo strikeDeviceInfo() const override;
87
89 // May be null if target is not sampleable.
91 // Can succeed if target is readable but not sampleable. Assumes 'subset' is contained in bounds
93
94 // True if this Device represents an internal renderable surface that will go out of scope
95 // before the next Recorder snap.
96 // NOTE: Currently, there are two different notions of "scratch" that are being merged together.
97 // 1. Devices whose targets are not instantiated (Device::Make).
98 // 2. Devices that are not registered with the Recorder (Surface::MakeScratch).
99 //
100 // This function reflects notion #1, since the long-term plan will be that all Devices that are
101 // not instantiated will also not be registered with the Recorder. For the time being, due to
102 // shared atlas management, layer-backing Devices need to be registered with the Recorder but
103 // are otherwise the canonical scratch device.
104 //
105 // Existing uses of Surface::MakeScratch() will migrate to using un-instantiated Devices with
106 // the requirement that if the Device's target is being returned in a client-owned object
107 // (e.g. SkImages::MakeWithFilter), that it should then be explicitly instantiated. Once scratch
108 // tasks are fully organized in a graph and not automatically appended to the root task list,
109 // this explicit instantiation will be responsible for moving the scratch tasks to the root list
110 bool isScratchDevice() const;
111
112 // Only used for scratch devices.
114
115 bool useDrawCoverageMaskForMaskFilters() const override { return true; }
116
117 // Clipping
118 void pushClipStack() override { fClip.save(); }
119 void popClipStack() override { fClip.restore(); }
120
121 bool isClipWideOpen() const override {
123 }
124 bool isClipEmpty() const override {
125 return fClip.clipState() == ClipStack::ClipState::kEmpty;
126 }
127 bool isClipRect() const override {
130 }
131
132 bool isClipAntiAliased() const override;
133 SkIRect devClipBounds() const override;
134 void android_utils_clipAsRgn(SkRegion*) const override;
135
136 void clipRect(const SkRect& rect, SkClipOp, bool aa) override;
137 void clipRRect(const SkRRect& rrect, SkClipOp, bool aa) override;
138 void clipPath(const SkPath& path, SkClipOp, bool aa) override;
139
140 void clipRegion(const SkRegion& globalRgn, SkClipOp) override;
141 void replaceClip(const SkIRect& rect) override;
142
143 // Drawing
144 void drawPaint(const SkPaint& paint) override;
145 void drawRect(const SkRect& r, const SkPaint& paint) override;
146 void drawOval(const SkRect& oval, const SkPaint& paint) override;
147 void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
149 const SkPoint[], const SkPaint& paint) override;
150 void drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable = false) override;
151
152 // No need to specialize drawDRRect, drawArc, drawRegion, drawPatch as the default impls all
153 // route to drawPath, drawRect, or drawVertices as desired.
154
155 void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
156 SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color,
157 SkBlendMode mode) override;
158
160 const SkPoint dstClips[], const SkMatrix preViewMatrices[],
161 const SkSamplingOptions&, const SkPaint&,
163
164 void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
165 const SkSamplingOptions&, const SkPaint&,
167
168 void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
170 const SkImage*,
171 const SkRect* src,
172 const SkRect& dst,
173 const SkSamplingOptions&,
174 const SkPaint&,
176 // TODO: Implement these using per-edge AA quads and an inlined image shader program.
178 const SkRect& dst, SkFilterMode, const SkPaint&) override {}
179 void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>,
180 const SkPaint&) override {}
181
182 void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override {}
183 void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override {}
184 void drawShadow(const SkPath&, const SkDrawShadowRec&) override {}
185
186 // Special images and layers
188
189 sk_sp<SkDevice> createDevice(const CreateInfo&, const SkPaint*) override;
190
191 sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false) override;
192
194 const SkSamplingOptions&, const SkPaint&,
197 const SkSamplingOptions&, const SkPaint&) override;
198
199 bool drawBlurredRRect(const SkRRect&, const SkPaint&, float deviceSigma) override;
200
201private:
202 class IntersectionTreeSet;
203
205
206 sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
207 sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
208
209 bool onReadPixels(const SkPixmap&, int x, int y) override;
210
211 bool onWritePixels(const SkPixmap&, int x, int y) override;
212
213 void onDrawGlyphRunList(SkCanvas*, const sktext::GlyphRunList&, const SkPaint&) override;
214
215 void onClipShader(sk_sp<SkShader> shader) override;
216
217 sk_sp<skif::Backend> createImageFilteringBackend(const SkSurfaceProps& surfaceProps,
218 SkColorType colorType) const override;
219
220 // DrawFlags alters the effects used by drawGeometry.
221 //
222 // There is no kIgnoreMaskFilter flag because the Device always ignores the mask filter -- the
223 // mask filter should be handled by the SkCanvas, either with an auto mask filter layer or
224 // being converted to an analytic blur draw.
225 enum class DrawFlags : unsigned {
226 kNone = 0b000,
227
228 // Any SkPathEffect on the SkPaint passed into drawGeometry() is ignored.
229 // - drawPaint, drawImageLattice, drawImageRect, drawEdgeAAImageSet, drawVertices, drawAtlas
230 // - drawGeometry after it's applied the path effect.
231 kIgnorePathEffect = 0b001,
232 };
234
235 // Handles applying path effects, mask filters, stroke-and-fill styles, and hairlines.
236 // Ignores geometric style on the paint in favor of explicitly provided SkStrokeRec and flags.
237 // All overridden SkDevice::draw() functions should bottom-out with calls to drawGeometry().
238 void drawGeometry(const Transform&,
239 const Geometry&,
240 const SkPaint&,
241 const SkStrokeRec&,
243 sk_sp<SkBlender> primitiveBlender = nullptr,
244 bool skipColorXform = false);
245
246 // Like drawGeometry() but is Shape-only, depth-only, fill-only, and lets the ClipStack define
247 // the transform, clip, and DrawOrder (although Device still tracks stencil buffer usage).
248 void drawClipShape(const Transform&, const Shape&, const Clip&, DrawOrder);
249
250 sktext::gpu::AtlasDrawDelegate atlasDelegate();
251 // Handles primitive processing for atlas-based text
252 void drawAtlasSubRun(const sktext::gpu::AtlasSubRun*,
253 SkPoint drawOrigin,
254 const SkPaint& paint,
255 sk_sp<SkRefCnt> subRunStorage,
257
258 sk_sp<sktext::gpu::Slug> convertGlyphRunListToSlug(const sktext::GlyphRunList& glyphRunList,
259 const SkPaint& paint) override;
260
261 void drawSlug(SkCanvas*, const sktext::gpu::Slug* slug, const SkPaint& paint) override;
262
263 // Returns the Renderer to draw the shape in the given style. If SkStrokeRec is a
264 // stroke-and-fill, this returns the Renderer used for the fill portion and it can be assumed
265 // that Renderer::TessellatedStrokes() will be used for the stroke portion.
266 //
267 // Depending on the preferred anti-aliasing quality and platform capabilities (such as compute
268 // shader support), an atlas handler for path rendering may be returned alongside the chosen
269 // Renderer. In that case, all fill, stroke, and stroke-and-fill styles should be rendered with
270 // a single recorded CoverageMask draw and the shape data should be added to the provided atlas
271 // handler to be scheduled for a coverage mask render.
272 //
273 // TODO: Renderers may have fallbacks (e.g. pre-chop large paths, or convert stroke to fill).
274 // Are those handled inside ChooseRenderer() where it can modify the shape, stroke? or does it
275 // return a retry error code? or does drawGeometry() handle all the fallbacks, knowing that
276 // a particular shape type needs to be pre-chopped?
277 // TODO: Move this into a RendererSelector object provided by the Context.
278 std::pair<const Renderer*, PathAtlas*> chooseRenderer(const Transform& localToDevice,
279 const Geometry&,
280 const SkStrokeRec&,
281 bool requireMSAA) const;
282
283 bool needsFlushBeforeDraw(int numNewDraws, DstReadRequirement) const;
284
285 // Flush internal work, such as pending clip draws and atlas uploads, into the Device's DrawTask
286 void internalFlush();
287
288 Recorder* fRecorder;
290 // Scratch devices hold on to their last snapped DrawTask so that they can be directly
291 // referenced when the device image is drawn into some other surface.
292 // NOTE: For now, this task is still added to the root task list when the Device is flushed, but
293 // in the long-term, these scratch draw tasks will only be executed if they are referenced by
294 // some other task chain that makes it to the root list.
295 sk_sp<Task> fLastTask;
296
297 ClipStack fClip;
298
299 // Tracks accumulated intersections for ordering dependent use of the color and depth attachment
300 // (i.e. depth-based clipping, and transparent blending)
301 std::unique_ptr<BoundsManager> fColorDepthBoundsManager;
302 // Tracks disjoint stencil indices for all recordered draws
303 std::unique_ptr<IntersectionTreeSet> fDisjointStencilSet;
304
305 // Lazily updated Transform constructed from localToDevice()'s SkM44
306 Transform fCachedLocalToDevice;
307
308 // The max depth value sent to the DrawContext, incremented so each draw has a unique value.
309 PaintersDepth fCurrentDepth;
310
311 // The DrawContext's target supports MSAA
312 bool fMSAASupported = false;
313
314 // TODO(b/330864257): Clean up once flushPendingWorkToRecorder() doesn't have to be re-entrant
315 bool fIsFlushing = false;
316
317 const sktext::gpu::SDFTControl fSDFTControl;
318
319#if defined(SK_DEBUG)
320 // When not 0, this Device is an unregistered scratch device that is intended to go out of
321 // scope before the Recorder is snapped. Assuming controlling code is valid, that means the
322 // Device's recorder's next recording ID should still be the the recording ID at the time the
323 // Device was created. If not, it means the Device lived too long and may not be flushing tasks
324 // in the expected order.
325 uint32_t fScopedRecordingID = 0;
326#endif
327
328 friend class ClipStack; // for recordDraw
329};
330
331SK_MAKE_BITMASK_OPS(Device::DrawFlags)
332
333} // namespace skgpu::graphite
334
335#endif // skgpu_graphite_Device_DEFINED
int count
Definition: FontMgrTest.cpp:50
SkBackingFit
Definition: SkBackingFit.h:16
SkBlendMode
Definition: SkBlendMode.h:38
SkClipOp
Definition: SkClipOp.h:13
SkColorType
Definition: SkColorType.h:19
uint32_t SkColor
Definition: SkColor.h:37
#define SK_DECL_BITMASK_OPS_FRIENDS(E)
Definition: SkEnumBitMask.h:82
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
SkFilterMode
Shape
Definition: aaxfermodes.cpp:43
SrcRectConstraint
Definition: SkCanvas.h:1541
sk_sp< SkSpecialImage > snapSpecial()
Definition: SkDevice.cpp:320
const SkMatrix & localToDevice() const
Definition: SkDevice.h:179
const SkSurfaceProps & surfaceProps() const
Definition: SkDevice.h:131
Definition: SkMesh.h:263
Definition: SkPath.h:59
sk_sp< SkDevice > createDevice(const CreateInfo &, const SkPaint *) override
Definition: Device.cpp:392
TextureProxyView readSurfaceView() const
Definition: Device.cpp:1688
void abandonRecorder()
Definition: Device.h:75
bool useDrawCoverageMaskForMaskFilters() const override
Definition: Device.h:115
static sk_sp< Device > Make(Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
Definition: Device.cpp:276
void drawRect(const SkRect &r, const SkPaint &paint) override
Definition: Device.cpp:674
sk_sp< SkSurface > makeSurface(const SkImageInfo &, const SkSurfaceProps &) override
Definition: Device.cpp:418
void drawOval(const SkRect &oval, const SkPaint &paint) override
Definition: Device.cpp:735
void clipRRect(const SkRRect &rrect, SkClipOp, bool aa) override
Definition: Device.cpp:583
void drawEdgeAAQuad(const SkRect &rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode) override
Definition: Device.cpp:810
void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp< SkBlender >, const SkPaint &) override
Definition: Device.h:179
Recorder * recorder() const override
Definition: Device.h:72
void android_utils_clipAsRgn(SkRegion *) const override
Definition: Device.cpp:558
void drawPaint(const SkPaint &paint) override
Definition: Device.cpp:639
void drawImageLattice(const SkImage *, const SkCanvas::Lattice &, const SkRect &dst, SkFilterMode, const SkPaint &) override
Definition: Device.h:177
void drawVertices(const SkVertices *, sk_sp< SkBlender >, const SkPaint &, bool) override
Definition: Device.cpp:679
TextureProxy * target()
Definition: Device.cpp:1686
void replaceClip(const SkIRect &rect) override
Definition: Device.cpp:622
bool drawBlurredRRect(const SkRRect &, const SkPaint &, float deviceSigma) override
Definition: Device.cpp:1717
const Transform & localToDeviceTransform()
Definition: Device.cpp:381
bool drawAsTiledImageRect(SkCanvas *, const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition: Device.cpp:691
void drawRRect(const SkRRect &rr, const SkPaint &paint) override
Definition: Device.cpp:749
void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], const SkMatrix preViewMatrices[], const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition: Device.cpp:828
void drawSpecial(SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition: Device.cpp:1558
bool isClipAntiAliased() const override
Definition: Device.cpp:539
void clipRegion(const SkRegion &globalRgn, SkClipOp) override
Definition: Device.cpp:603
SkStrikeDeviceInfo strikeDeviceInfo() const override
Definition: Device.cpp:388
void drawShadow(const SkPath &, const SkDrawShadowRec &) override
Definition: Device.h:184
void drawPath(const SkPath &path, const SkPaint &paint, bool pathIsMutable=false) override
Definition: Device.cpp:754
void flushPendingWorkToRecorder()
Definition: Device.cpp:1465
bool isScratchDevice() const
Definition: Device.cpp:1690
void drawImageRect(const SkImage *, const SkRect *src, const SkRect &dst, const SkSamplingOptions &, const SkPaint &, SkCanvas::SrcRectConstraint) override
Definition: Device.cpp:889
Device * asGraphiteDevice() override
Definition: Device.h:70
void drawMesh(const SkMesh &, sk_sp< SkBlender >, const SkPaint &) override
Definition: Device.h:183
bool isClipRect() const override
Definition: Device.h:127
void drawCoverageMask(const SkSpecialImage *, const SkMatrix &localToDevice, const SkSamplingOptions &, const SkPaint &) override
Definition: Device.cpp:1590
friend class ClipStack
Definition: Device.h:328
void clipRect(const SkRect &rect, SkClipOp, bool aa) override
Definition: Device.cpp:577
void setImmutable() override
Definition: Device.cpp:366
void drawDrawable(SkCanvas *, SkDrawable *, const SkMatrix *) override
Definition: Device.h:182
sk_sp< Image > makeImageCopy(const SkIRect &subset, Budgeted, Mipmapped, SkBackingFit)
Definition: Device.cpp:422
void popClipStack() override
Definition: Device.h:119
SkIRect devClipBounds() const override
Definition: Device.cpp:553
sk_sp< Task > lastDrawTask() const
Definition: Device.cpp:1460
void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint &paint) override
void pushClipStack() override
Definition: Device.h:118
bool isClipWideOpen() const override
Definition: Device.h:121
bool isClipEmpty() const override
Definition: Device.h:124
void clipPath(const SkPath &path, SkClipOp, bool aa) override
Definition: Device.cpp:590
const Paint & paint
Definition: color_source.cc:38
DlColor color
double y
double x
drawSlug(r.slug.get(), r.paint)) DRAW(DrawAtlas
PODArray< SkPoint > dstClips
Definition: SkRecords.h:364
SkRRect rrect
Definition: SkRecords.h:232
SkRect oval
Definition: SkRecords.h:249
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkMatrix > preViewMatrices
Definition: SkRecords.h:365
Clip
Definition: layer.h:53
@ kNone
Definition: layer.h:53
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
CanvasImage Image
Definition: dart_ui.cc:55
dst
Definition: cp.py:12
SK_MAKE_BITMASK_OPS(DawnErrorType)
DstReadRequirement
Definition: Caps.h:64
MonotonicValue< PaintersDepthSequence > PaintersDepth
Definition: DrawOrder.h:86
Budgeted
Definition: GpuTypes.h:35
Mipmapped
Definition: GpuTypes.h:53
std::function< void(const sktext::gpu::AtlasSubRun *subRun, SkPoint drawOrigin, const SkPaint &paint, sk_sp< SkRefCnt > subRunStorage, sktext::gpu::RendererData)> AtlasDrawDelegate
skgpu::graphite::Transform Transform
Definition: SkRect.h:32
Definition: SkSize.h:16
Definition: DM.cpp:1161