/src/skia/src/gpu/ganesh/Device.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2010 Google Inc. |
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_v1_Device_DEFINED |
9 | | #define skgpu_v1_Device_DEFINED |
10 | | |
11 | | #include "include/core/SkCanvas.h" |
12 | | #include "include/core/SkClipOp.h" |
13 | | #include "include/core/SkColor.h" |
14 | | #include "include/core/SkImage.h" |
15 | | #include "include/core/SkImageInfo.h" |
16 | | #include "include/core/SkRect.h" |
17 | | #include "include/core/SkRefCnt.h" |
18 | | #include "include/core/SkSamplingOptions.h" |
19 | | #include "include/core/SkShader.h" |
20 | | #include "include/core/SkSurface.h" |
21 | | #include "include/gpu/ganesh/GrTypes.h" |
22 | | #include "include/private/base/SkAssert.h" |
23 | | #include "include/private/base/SkMacros.h" |
24 | | #include "src/core/SkDevice.h" |
25 | | #include "src/core/SkMatrixPriv.h" |
26 | | #include "src/gpu/ganesh/ClipStack.h" |
27 | | #include "src/gpu/ganesh/GrColorInfo.h" |
28 | | #include "src/gpu/ganesh/GrSurfaceProxyView.h" |
29 | | #include "src/text/gpu/SubRunControl.h" |
30 | | |
31 | | #include <cstddef> |
32 | | #include <memory> |
33 | | #include <utility> |
34 | | |
35 | | class GrBackendSemaphore; |
36 | | class GrClip; |
37 | | class GrRecordingContext; |
38 | | class GrRenderTargetProxy; |
39 | | class GrSurfaceProxy; |
40 | | class SkBitmap; |
41 | | class SkBlender; |
42 | | class SkColorSpace; |
43 | | class SkDrawable; |
44 | | class SkLatticeIter; |
45 | | class SkMatrix; |
46 | | class SkMesh; |
47 | | class SkPaint; |
48 | | class SkPath; |
49 | | class SkPixmap; |
50 | | class SkRRect; |
51 | | class SkRegion; |
52 | | class SkSpecialImage; |
53 | | class SkSurfaceProps; |
54 | | class SkSurface_Ganesh; |
55 | | class SkVertices; |
56 | | enum SkAlphaType : int; |
57 | | enum SkColorType : int; |
58 | | enum class GrAA : bool; |
59 | | enum class GrColorType; |
60 | | enum class SkBackingFit; |
61 | | enum class SkBlendMode; |
62 | | enum class SkTileMode; |
63 | | struct SkArc; |
64 | | struct SkDrawShadowRec; |
65 | | struct SkISize; |
66 | | struct SkPoint; |
67 | | struct SkRSXform; |
68 | | namespace skgpu { |
69 | | enum class Budgeted : bool; |
70 | | enum class Mipmapped : bool; |
71 | | class TiledTextureUtils; |
72 | | } |
73 | | namespace skif { |
74 | | class Backend; |
75 | | } |
76 | | namespace sktext { |
77 | | class GlyphRunList; |
78 | | namespace gpu { |
79 | | class Slug; |
80 | | }} |
81 | | |
82 | | |
83 | | namespace skgpu::ganesh { |
84 | | |
85 | | class SurfaceContext; |
86 | | class SurfaceFillContext; |
87 | | class SurfaceDrawContext; |
88 | | |
89 | | /** |
90 | | * Subclass of SkDevice, which directs all drawing to the GrGpu owned by the canvas. |
91 | | */ |
92 | | class Device final : public SkDevice { |
93 | | public: |
94 | | enum class InitContents { |
95 | | kClear, |
96 | | kUninit |
97 | | }; |
98 | | |
99 | | GrSurfaceProxyView readSurfaceView(); |
100 | | GrRenderTargetProxy* targetProxy(); |
101 | | |
102 | 267k | GrRecordingContext* recordingContext() const override { return fContext.get(); } |
103 | | |
104 | | bool wait(int numSemaphores, |
105 | | const GrBackendSemaphore* waitSemaphores, |
106 | | bool deleteSemaphoresAfterWait); |
107 | | |
108 | | void discard(); |
109 | | void resolveMSAA(); |
110 | | |
111 | | bool replaceBackingProxy(SkSurface::ContentChangeMode, |
112 | | sk_sp<GrRenderTargetProxy>, |
113 | | GrColorType, |
114 | | sk_sp<SkColorSpace>, |
115 | | GrSurfaceOrigin, |
116 | | const SkSurfaceProps&); |
117 | | bool replaceBackingProxy(SkSurface::ContentChangeMode); |
118 | | |
119 | | using RescaleGamma = SkImage::RescaleGamma; |
120 | | using RescaleMode = SkImage::RescaleMode; |
121 | | using ReadPixelsCallback = SkImage::ReadPixelsCallback; |
122 | | using ReadPixelsContext = SkImage::ReadPixelsContext; |
123 | | |
124 | | void asyncRescaleAndReadPixels(const SkImageInfo& info, |
125 | | const SkIRect& srcRect, |
126 | | RescaleGamma rescaleGamma, |
127 | | RescaleMode rescaleMode, |
128 | | ReadPixelsCallback callback, |
129 | | ReadPixelsContext context); |
130 | | |
131 | | void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, |
132 | | bool readAlpha, |
133 | | sk_sp<SkColorSpace> dstColorSpace, |
134 | | const SkIRect& srcRect, |
135 | | SkISize dstSize, |
136 | | RescaleGamma rescaleGamma, |
137 | | RescaleMode, |
138 | | ReadPixelsCallback callback, |
139 | | ReadPixelsContext context); |
140 | | |
141 | | /** |
142 | | * This factory uses the color space, origin, surface properties, and initialization |
143 | | * method along with the provided proxy to create the gpu device. |
144 | | */ |
145 | | static sk_sp<Device> Make(GrRecordingContext*, |
146 | | GrColorType, |
147 | | sk_sp<GrSurfaceProxy>, |
148 | | sk_sp<SkColorSpace>, |
149 | | GrSurfaceOrigin, |
150 | | const SkSurfaceProps&, |
151 | | InitContents); |
152 | | |
153 | | /** |
154 | | * This factory uses the budgeted, imageInfo, fit, sampleCount, mipmapped, and isProtected |
155 | | * parameters to create a proxy to back the gpu device. The color space (from the image info), |
156 | | * origin, surface properties, and initialization method are then used (with the created proxy) |
157 | | * to create the device. |
158 | | */ |
159 | | static sk_sp<Device> Make(GrRecordingContext*, |
160 | | skgpu::Budgeted, |
161 | | const SkImageInfo&, |
162 | | SkBackingFit, |
163 | | int sampleCount, |
164 | | skgpu::Mipmapped, |
165 | | GrProtected, |
166 | | GrSurfaceOrigin, |
167 | | const SkSurfaceProps&, |
168 | | InitContents); |
169 | | |
170 | | ~Device() override; |
171 | | |
172 | | SurfaceDrawContext* surfaceDrawContext(); |
173 | | const SurfaceDrawContext* surfaceDrawContext() const; |
174 | | SurfaceFillContext* surfaceFillContext(); |
175 | | |
176 | | SkStrikeDeviceInfo strikeDeviceInfo() const override; |
177 | | |
178 | | // set all pixels to 0 |
179 | | void clearAll(); |
180 | | |
181 | | void drawPaint(const SkPaint& paint) override; |
182 | | void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[], |
183 | | const SkPaint& paint) override; |
184 | | void drawRect(const SkRect& r, const SkPaint& paint) override; |
185 | | void drawRRect(const SkRRect& r, const SkPaint& paint) override; |
186 | | void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) override; |
187 | | void drawRegion(const SkRegion& r, const SkPaint& paint) override; |
188 | | void drawOval(const SkRect& oval, const SkPaint& paint) override; |
189 | | void drawArc(const SkArc& arc, const SkPaint& paint) override; |
190 | | void drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable) override; |
191 | | |
192 | | void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; |
193 | | void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override; |
194 | | #if !defined(SK_ENABLE_OPTIMIZE_SIZE) |
195 | | void drawShadow(const SkPath&, const SkDrawShadowRec&) override; |
196 | | #endif |
197 | | void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>, |
198 | | const SkPaint&) override; |
199 | | |
200 | | void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, |
201 | | const SkSamplingOptions&, const SkPaint&, |
202 | | SkCanvas::SrcRectConstraint) override; |
203 | 1.30k | bool shouldDrawAsTiledImageRect() const override { return true; } |
204 | | bool drawAsTiledImageRect(SkCanvas*, |
205 | | const SkImage*, |
206 | | const SkRect* src, |
207 | | const SkRect& dst, |
208 | | const SkSamplingOptions&, |
209 | | const SkPaint&, |
210 | | SkCanvas::SrcRectConstraint) override; |
211 | | void drawImageLattice(const SkImage*, const SkCanvas::Lattice&, |
212 | | const SkRect& dst, SkFilterMode, const SkPaint&) override; |
213 | | |
214 | | void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override; |
215 | | |
216 | | void drawDevice(SkDevice*, const SkSamplingOptions&, const SkPaint&) override; |
217 | | void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice, const SkSamplingOptions&, |
218 | | const SkPaint&, SkCanvas::SrcRectConstraint) override; |
219 | | |
220 | | void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags, |
221 | | const SkColor4f& color, SkBlendMode mode) override; |
222 | | void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[], |
223 | | const SkMatrix preViewMatrices[], const SkSamplingOptions&, |
224 | | const SkPaint&, SkCanvas::SrcRectConstraint) override; |
225 | | |
226 | | // Assumes the src and dst rects have already been optimized to fit the proxy. |
227 | | // Only implemented by the gpu devices. |
228 | | // This method is the lowest level draw used for tiled bitmap draws. It doesn't attempt to |
229 | | // modify its parameters (e.g., adjust src & dst) but just draws the image however it can. It |
230 | | // could, almost, be replaced with a drawEdgeAAImageSet call for the tiled bitmap draw use |
231 | | // case but the extra tilemode requirement and the intermediate parameter processing (e.g., |
232 | | // trying to alter the SrcRectConstraint) currently block that. |
233 | | void drawEdgeAAImage(const SkImage*, |
234 | | const SkRect& src, |
235 | | const SkRect& dst, |
236 | | const SkPoint dstClip[4], |
237 | | SkCanvas::QuadAAFlags, |
238 | | const SkMatrix& localToDevice, |
239 | | const SkSamplingOptions&, |
240 | | const SkPaint&, |
241 | | SkCanvas::SrcRectConstraint, |
242 | | const SkMatrix& srcToDst, |
243 | | SkTileMode); |
244 | | |
245 | | sk_sp<sktext::gpu::Slug> convertGlyphRunListToSlug(const sktext::GlyphRunList& glyphRunList, |
246 | | const SkPaint& paint) override; |
247 | | |
248 | | void drawSlug(SkCanvas*, const sktext::gpu::Slug* slug, const SkPaint& paint) override; |
249 | | |
250 | | sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override; |
251 | | sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override; |
252 | | sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false) override; |
253 | | sk_sp<SkSpecialImage> snapSpecialScaled(const SkIRect& subset, const SkISize& dstDims) override; |
254 | | |
255 | | sk_sp<SkDevice> createDevice(const CreateInfo&, const SkPaint*) override; |
256 | | |
257 | | sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override; |
258 | | |
259 | 0 | Device* asGaneshDevice() override { return this; } |
260 | | |
261 | 281k | SkIRect devClipBounds() const override { return fClip.getConservativeBounds(); } |
262 | | |
263 | 69.8k | void pushClipStack() override { fClip.save(); } |
264 | 69.8k | void popClipStack() override { fClip.restore(); } |
265 | | |
266 | 80.5k | void clipRect(const SkRect& rect, SkClipOp op, bool aa) override { |
267 | 80.5k | SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference); |
268 | 80.5k | fClip.clipRect(this->localToDevice(), rect, GrAA(aa), op); |
269 | 80.5k | } |
270 | 1.96k | void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) override { |
271 | 1.96k | SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference); |
272 | 1.96k | fClip.clipRRect(this->localToDevice(), rrect, GrAA(aa), op); |
273 | 1.96k | } |
274 | | void clipPath(const SkPath& path, SkClipOp op, bool aa) override; |
275 | | |
276 | 0 | void replaceClip(const SkIRect& rect) override { |
277 | | // Transform from "global/canvas" coordinates to relative to this device |
278 | 0 | SkRect deviceRect = SkMatrixPriv::MapRect(this->globalToDevice(), SkRect::Make(rect)); |
279 | 0 | fClip.replaceClip(deviceRect.round()); |
280 | 0 | } |
281 | | void clipRegion(const SkRegion& globalRgn, SkClipOp op) override; |
282 | | |
283 | | bool isClipAntiAliased() const override; |
284 | | |
285 | 270k | bool isClipEmpty() const override { |
286 | 270k | return fClip.clipState() == ClipStack::ClipState::kEmpty; |
287 | 270k | } |
288 | | |
289 | 0 | bool isClipRect() const override { |
290 | 0 | return fClip.clipState() == ClipStack::ClipState::kDeviceRect || |
291 | 0 | fClip.clipState() == ClipStack::ClipState::kWideOpen; |
292 | 0 | } |
293 | | |
294 | 0 | bool isClipWideOpen() const override { |
295 | 0 | return fClip.clipState() == ClipStack::ClipState::kWideOpen; |
296 | 0 | } |
297 | | |
298 | | void android_utils_clipAsRgn(SkRegion*) const override; |
299 | | bool android_utils_clipWithStencil() override; |
300 | | |
301 | | private: |
302 | | enum class DeviceFlags { |
303 | | kNone = 0, |
304 | | kNeedClear = 1 << 0, //!< Surface requires an initial clear |
305 | | kIsOpaque = 1 << 1, //!< Hint from client that rendering to this device will be |
306 | | // opaque even if the config supports alpha. |
307 | | }; |
308 | | SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(DeviceFlags); |
309 | | |
310 | | static SkImageInfo MakeInfo(SurfaceContext*, DeviceFlags); |
311 | | static bool CheckAlphaTypeAndGetFlags(SkAlphaType, InitContents, DeviceFlags*); |
312 | | |
313 | | sk_sp<GrRecordingContext> fContext; |
314 | | |
315 | | const sktext::gpu::SubRunControl fSubRunControl; |
316 | | |
317 | | std::unique_ptr<SurfaceDrawContext> fSurfaceDrawContext; |
318 | | |
319 | | ClipStack fClip; |
320 | | |
321 | | static sk_sp<Device> Make(std::unique_ptr<SurfaceDrawContext>, |
322 | | SkAlphaType, |
323 | | InitContents); |
324 | | |
325 | | Device(std::unique_ptr<SurfaceDrawContext>, DeviceFlags); |
326 | | |
327 | | void onDrawGlyphRunList(SkCanvas*, const sktext::GlyphRunList&, const SkPaint& paint) override; |
328 | | |
329 | | bool onReadPixels(const SkPixmap&, int, int) override; |
330 | | bool onWritePixels(const SkPixmap&, int, int) override; |
331 | | bool onAccessPixels(SkPixmap*) override; |
332 | | |
333 | | sk_sp<skif::Backend> createImageFilteringBackend(const SkSurfaceProps& surfaceProps, |
334 | | SkColorType colorType) const override; |
335 | | |
336 | 0 | void onClipShader(sk_sp<SkShader> shader) override { |
337 | 0 | fClip.clipShader(std::move(shader)); |
338 | 0 | } |
339 | | |
340 | 310k | const GrClip* clip() const { return &fClip; } |
341 | | |
342 | | // If not null, dstClip must be contained inside dst and will also respect the edge AA flags. |
343 | | // If 'preViewMatrix' is not null, final CTM will be this->ctm() * preViewMatrix. |
344 | | void drawImageQuadDirect(const SkImage*, |
345 | | const SkRect& src, |
346 | | const SkRect& dst, |
347 | | const SkPoint dstClip[4], |
348 | | SkCanvas::QuadAAFlags, |
349 | | const SkMatrix* preViewMatrix, |
350 | | const SkSamplingOptions&, |
351 | | const SkPaint&, |
352 | | SkCanvas::SrcRectConstraint); |
353 | | |
354 | | // FIXME(michaelludwig) - Should be removed in favor of using drawImageQuad with edge flags to |
355 | | // for every element in the SkLatticeIter. |
356 | | void drawViewLattice(GrSurfaceProxyView, |
357 | | const GrColorInfo& colorInfo, |
358 | | std::unique_ptr<SkLatticeIter>, |
359 | | const SkRect& dst, |
360 | | SkFilterMode, |
361 | | const SkPaint&); |
362 | | |
363 | | friend class ::SkSurface_Ganesh; // for access to surfaceProps |
364 | | friend class skgpu::TiledTextureUtils; // for access to clip() |
365 | | }; |
366 | | |
367 | | SK_MAKE_BITFIELD_CLASS_OPS(Device::DeviceFlags) |
368 | | |
369 | | } // namespace skgpu::ganesh |
370 | | |
371 | | #endif // skgpu_v1_Device_DEFINED |