Coverage Report

Created: 2024-09-14 07:19

/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