• 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/SkSurface.h"
12 #include "include/gpu/GrTypes.h"
13 #include "src/core/SkDevice.h"
14 #include "src/gpu/ganesh/ClipStack.h"
15 #include "src/gpu/ganesh/SkGr.h"
16 #include "src/text/gpu/SDFTControl.h"
17 
18 class SkBitmap;
19 class SkLatticeIter;
20 class SkRegion;
21 class SkSpecialImage;
22 class SkSurface;
23 class SkSurface_Gpu;
24 class SkVertices;
25 
26 namespace skgpu::v1 {
27 
28 class SurfaceContext;
29 class SurfaceFillContext;
30 
31 /**
32  *  Subclass of SkBaseDevice, which directs all drawing to the GrGpu owned by the canvas.
33  */
34 class Device final : public SkBaseDevice  {
35 public:
36     enum class InitContents {
37         kClear,
38         kUninit
39     };
40 
41     GrSurfaceProxyView readSurfaceView();
42     GrRenderTargetProxy* targetProxy();
43 
recordingContext()44     GrRecordingContext* recordingContext() const { return fContext.get(); }
45 
46     bool wait(int numSemaphores,
47               const GrBackendSemaphore* waitSemaphores,
48               bool deleteSemaphoresAfterWait);
49 
50     void discard();
51     void resolveMSAA();
52 
53     bool replaceBackingProxy(SkSurface::ContentChangeMode,
54                              sk_sp<GrRenderTargetProxy>,
55                              GrColorType,
56                              sk_sp<SkColorSpace>,
57                              GrSurfaceOrigin,
58                              const SkSurfaceProps&);
59     bool replaceBackingProxy(SkSurface::ContentChangeMode);
60 
61     using RescaleGamma       = SkImage::RescaleGamma;
62     using RescaleMode        = SkImage::RescaleMode;
63     using ReadPixelsCallback = SkImage::ReadPixelsCallback;
64     using ReadPixelsContext  = SkImage::ReadPixelsContext;
65 
66     void asyncRescaleAndReadPixels(const SkImageInfo& info,
67                                    const SkIRect& srcRect,
68                                    RescaleGamma rescaleGamma,
69                                    RescaleMode rescaleMode,
70                                    ReadPixelsCallback callback,
71                                    ReadPixelsContext context);
72 
73     void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
74                                          sk_sp<SkColorSpace> dstColorSpace,
75                                          const SkIRect& srcRect,
76                                          SkISize dstSize,
77                                          RescaleGamma rescaleGamma,
78                                          RescaleMode,
79                                          ReadPixelsCallback callback,
80                                          ReadPixelsContext context);
81 
82     /**
83      * This factory uses the color space, origin, surface properties, and initialization
84      * method along with the provided proxy to create the gpu device.
85      */
86     static sk_sp<Device> Make(GrRecordingContext*,
87                               GrColorType,
88                               sk_sp<GrSurfaceProxy>,
89                               sk_sp<SkColorSpace>,
90                               GrSurfaceOrigin,
91                               const SkSurfaceProps&,
92                               InitContents);
93 
94     /**
95      * This factory uses the budgeted, imageInfo, fit, sampleCount, mipmapped, and isProtected
96      * parameters to create a proxy to back the gpu device. The color space (from the image info),
97      * origin, surface properties, and initialization method are then used (with the created proxy)
98      * to create the device.
99      */
100     static sk_sp<Device> Make(GrRecordingContext*,
101                               skgpu::Budgeted,
102                               const SkImageInfo&,
103                               SkBackingFit,
104                               int sampleCount,
105                               GrMipmapped,
106                               GrProtected,
107                               GrSurfaceOrigin,
108                               const SkSurfaceProps&,
109                               InitContents);
110 
111     ~Device() override;
112 
113     SurfaceDrawContext* surfaceDrawContext();
114     const SurfaceDrawContext* surfaceDrawContext() const;
115     SurfaceFillContext* surfaceFillContext();
116 
117     SkStrikeDeviceInfo strikeDeviceInfo() const override;
118 
119     // set all pixels to 0
120     void clearAll();
121 
122     void drawPaint(const SkPaint& paint) override;
123     void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
124                     const SkPaint& paint) override;
125     void drawRect(const SkRect& r, const SkPaint& paint) override;
126     void drawRRect(const SkRRect& r, const SkPaint& paint) override;
127     void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) override;
128     void drawRegion(const SkRegion& r, const SkPaint& paint) override;
129     void drawOval(const SkRect& oval, const SkPaint& paint) override;
130     void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
131                  bool useCenter, const SkPaint& paint) override;
132     void drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable) override;
133 
134     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override;
135     void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override;
136 #if !defined(SK_ENABLE_OPTIMIZE_SIZE)
137     void drawShadow(const SkPath&, const SkDrawShadowRec&) override;
138 #endif
139     void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>,
140                    const SkPaint&) override;
141 
142     void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
143                        const SkSamplingOptions&, const SkPaint&,
144                        SkCanvas::SrcRectConstraint) override;
145     void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
146                           const SkRect& dst, SkFilterMode, const SkPaint&) override;
147 
148     void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override;
149 
150     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;
151     void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice, const SkSamplingOptions&,
152                      const SkPaint&) override;
153 
154     void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], SkCanvas::QuadAAFlags aaFlags,
155                         const SkColor4f& color, SkBlendMode mode) override;
156     void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, const SkPoint dstClips[],
157                             const SkMatrix[], const SkSamplingOptions&, const SkPaint&,
158                             SkCanvas::SrcRectConstraint) override;
159 
160     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
161     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
162     sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false) override;
163     sk_sp<SkSpecialImage> snapSpecialScaled(const SkIRect& subset, const SkISize& dstDims) override;
164 
165     bool onAccessPixels(SkPixmap*) override;
166 
167     bool android_utils_clipWithStencil() override;
168 
asGaneshDevice()169     Device* asGaneshDevice() override { return this; }
170 
171 protected:
172     bool onReadPixels(const SkPixmap&, int, int) override;
173     bool onWritePixels(const SkPixmap&, int, int) override;
174 
onSave()175     void onSave() override { fClip.save(); }
onRestore()176     void onRestore() override { fClip.restore(); }
177 
178     void onDrawGlyphRunList(SkCanvas*,
179                             const sktext::GlyphRunList&,
180                             const SkPaint& initialPaint,
181                             const SkPaint& drawingPaint) override;
182 
183     sk_sp<sktext::gpu::Slug> convertGlyphRunListToSlug(
184             const sktext::GlyphRunList& glyphRunList,
185             const SkPaint& initialPaint,
186             const SkPaint& drawingPaint) override;
187 
188     void drawSlug(SkCanvas*, const sktext::gpu::Slug* slug, const SkPaint& drawingPaint) override;
189 
onClipRect(const SkRect & rect,SkClipOp op,bool aa)190     void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override {
191         SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
192         fClip.clipRect(this->localToDevice(), rect, GrAA(aa), op);
193     }
onClipRRect(const SkRRect & rrect,SkClipOp op,bool aa)194     void onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) override {
195         SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
196         fClip.clipRRect(this->localToDevice(), rrect, GrAA(aa), op);
197     }
198     void onClipPath(const SkPath& path, SkClipOp op, bool aa) override;
onClipShader(sk_sp<SkShader> shader)199     void onClipShader(sk_sp<SkShader> shader) override {
200         fClip.clipShader(std::move(shader));
201     }
onReplaceClip(const SkIRect & rect)202     void onReplaceClip(const SkIRect& rect) override {
203         // Transform from "global/canvas" coordinates to relative to this device
204         SkRect deviceRect = SkMatrixPriv::MapRect(this->globalToDevice(), SkRect::Make(rect));
205         fClip.replaceClip(deviceRect.round());
206     }
207     void onClipRegion(const SkRegion& globalRgn, SkClipOp op) override;
208     void onAsRgnClip(SkRegion*) const override;
209     ClipType onGetClipType() const override;
210     bool onClipIsAA() const override;
211 
onClipIsWideOpen()212     bool onClipIsWideOpen() const override {
213         return fClip.clipState() == ClipStack::ClipState::kWideOpen;
214     }
onDevClipBounds()215     SkIRect onDevClipBounds() const override { return fClip.getConservativeBounds(); }
216 
217 private:
218     enum class DeviceFlags {
219         kNone      = 0,
220         kNeedClear = 1 << 0,  //!< Surface requires an initial clear
221         kIsOpaque  = 1 << 1,  //!< Hint from client that rendering to this device will be
222         //   opaque even if the config supports alpha.
223     };
224     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(DeviceFlags);
225 
226     static SkImageInfo MakeInfo(SurfaceContext*,  DeviceFlags);
227     static bool CheckAlphaTypeAndGetFlags(SkAlphaType, InitContents, DeviceFlags*);
228 
229     sk_sp<GrRecordingContext> fContext;
230 
231     const sktext::gpu::SDFTControl fSDFTControl;
232 
233     std::unique_ptr<SurfaceDrawContext> fSurfaceDrawContext;
234 
235     ClipStack fClip;
236 
237     static sk_sp<Device> Make(std::unique_ptr<SurfaceDrawContext>,
238                               SkAlphaType,
239                               InitContents);
240 
241     Device(std::unique_ptr<SurfaceDrawContext>, DeviceFlags);
242 
243     SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
244 
245     sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
246 
247     SkImageFilterCache* getImageFilterCache() override;
248 
forceConservativeRasterClip()249     bool forceConservativeRasterClip() const override { return true; }
250 
clip()251     const GrClip* clip() const { return &fClip; }
252 #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG)
253     void testingOnly_drawGlyphRunListWithSlug(SkCanvas* canvas,
254                                               const sktext::GlyphRunList& glyphRunList,
255                                               const SkPaint& initialPaint,
256                                               const SkPaint& drawingPaint);
257 #endif
258 
259 #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_SERIALIZE)
260     void testingOnly_drawGlyphRunListWithSerializedSlug(SkCanvas* canvas,
261                                                         const sktext::GlyphRunList& glyphRunList,
262                                                         const SkPaint& initialPaint,
263                                                         const SkPaint& drawingPaint);
264 #endif
265 
266 #if defined(SK_EXPERIMENTAL_SIMULATE_DRAWGLYPHRUNLIST_WITH_SLUG_STRIKE_SERIALIZE)
267     void testingOnly_drawGlyphRunListWithSerializedSlugAndStrike(
268             SkCanvas* canvas,
269             const sktext::GlyphRunList& glyphRunList,
270             const SkPaint& initialPaint,
271             const SkPaint& drawingPaint);
272 #endif
273 
274     // If not null, dstClip must be contained inside dst and will also respect the edge AA flags.
275     // If 'preViewMatrix' is not null, final CTM will be this->ctm() * preViewMatrix.
276     void drawImageQuad(const SkImage*, const SkRect* src, const SkRect* dst,
277                        const SkPoint dstClip[4], GrQuadAAFlags aaFlags,
278                        const SkMatrix* preViewMatrix, const SkSamplingOptions&,
279                        const SkPaint&, SkCanvas::SrcRectConstraint);
280 
281     // FIXME(michaelludwig) - Should be removed in favor of using drawImageQuad with edge flags to
282     // for every element in the SkLatticeIter.
283     void drawViewLattice(GrSurfaceProxyView,
284                          const GrColorInfo& colorInfo,
285                          std::unique_ptr<SkLatticeIter>,
286                          const SkRect& dst,
287                          SkFilterMode,
288                          const SkPaint&);
289 
290     friend class ::SkSurface_Gpu;      // for access to surfaceProps
291 };
292 
293 GR_MAKE_BITFIELD_CLASS_OPS(Device::DeviceFlags)
294 
295 } // namespace skgpu::v1
296 
297 #endif // skgpu_v1_Device_DEFINED
298