xref: /aosp_15_r20/external/skia/src/gpu/ganesh/Device.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 
recordingContext()102     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;
shouldDrawAsTiledImageRect()203     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 
asGaneshDevice()259     Device* asGaneshDevice() override { return this; }
260 
devClipBounds()261     SkIRect devClipBounds() const override { return fClip.getConservativeBounds(); }
262 
pushClipStack()263     void pushClipStack() override { fClip.save(); }
popClipStack()264     void popClipStack() override { fClip.restore(); }
265 
clipRect(const SkRect & rect,SkClipOp op,bool aa)266     void clipRect(const SkRect& rect, SkClipOp op, bool aa) override {
267         SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
268         fClip.clipRect(this->localToDevice(), rect, GrAA(aa), op);
269     }
clipRRect(const SkRRect & rrect,SkClipOp op,bool aa)270     void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) override {
271         SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
272         fClip.clipRRect(this->localToDevice(), rrect, GrAA(aa), op);
273     }
274     void clipPath(const SkPath& path, SkClipOp op, bool aa) override;
275 
replaceClip(const SkIRect & rect)276     void replaceClip(const SkIRect& rect) override {
277         // Transform from "global/canvas" coordinates to relative to this device
278         SkRect deviceRect = SkMatrixPriv::MapRect(this->globalToDevice(), SkRect::Make(rect));
279         fClip.replaceClip(deviceRect.round());
280     }
281     void clipRegion(const SkRegion& globalRgn, SkClipOp op) override;
282 
283     bool isClipAntiAliased() const override;
284 
isClipEmpty()285     bool isClipEmpty() const override {
286         return fClip.clipState() == ClipStack::ClipState::kEmpty;
287     }
288 
isClipRect()289     bool isClipRect() const override {
290         return fClip.clipState() == ClipStack::ClipState::kDeviceRect ||
291                fClip.clipState() == ClipStack::ClipState::kWideOpen;
292     }
293 
isClipWideOpen()294     bool isClipWideOpen() const override {
295         return fClip.clipState() == ClipStack::ClipState::kWideOpen;
296     }
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 
onClipShader(sk_sp<SkShader> shader)336     void onClipShader(sk_sp<SkShader> shader) override {
337         fClip.clipShader(std::move(shader));
338     }
339 
clip()340     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
372