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