• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
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_Device_DEFINED
9 #define skgpu_Device_DEFINED
10 
11 #include "src/core/SkDevice.h"
12 
13 #include "experimental/graphite/src/DrawOrder.h"
14 #include "experimental/graphite/src/EnumBitMask.h"
15 #include "experimental/graphite/src/geom/Rect.h"
16 
17 class SkStrokeRec;
18 
19 namespace skgpu {
20 
21 class BoundsManager;
22 class Clip;
23 class Context;
24 class DrawContext;
25 class Recorder;
26 class Shape;
27 class TextureProxy;
28 class Transform;
29 
30 class Device final : public SkBaseDevice  {
31 public:
32     ~Device() override;
33 
34     static sk_sp<Device> Make(Recorder*, const SkImageInfo&);
35     static sk_sp<Device> Make(Recorder*,
36                               sk_sp<TextureProxy>,
37                               sk_sp<SkColorSpace>,
38                               SkColorType,
39                               SkAlphaType);
40 
recorder()41     Recorder* recorder() { return fRecorder; }
42     // This call is triggered from the Recorder on its registered Devices. It is typically called
43     // when the Recorder is abandoned or deleted.
44     void abandonRecorder();
45 
46     // Ensures clip elements are drawn that will clip previous draw calls, snaps all pending work
47     // from the DrawContext as a RenderPassTask and records it in the Device's recorder.
48     void flushPendingWorkToRecorder();
49 
50     bool readPixels(Context*, Recorder*, const SkPixmap& dst, int x, int y);
51 
52 private:
53     class IntersectionTreeSet;
54 
55     // Clipping
onSave()56     void onSave() override {}
onRestore()57     void onRestore() override {}
58 
onClipIsAA()59     bool onClipIsAA() const override { return false; }
onClipIsWideOpen()60     bool onClipIsWideOpen() const override { return true; }
onGetClipType()61     ClipType onGetClipType() const override { return ClipType::kRect; }
62     SkIRect onDevClipBounds() const override;
63 
onClipRect(const SkRect & rect,SkClipOp,bool aa)64     void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {}
onClipRRect(const SkRRect & rrect,SkClipOp,bool aa)65     void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {}
onClipPath(const SkPath & path,SkClipOp,bool aa)66     void onClipPath(const SkPath& path, SkClipOp, bool aa) override {}
67 
68     // Drawing
69     void drawPaint(const SkPaint& paint) override;
70     void drawRect(const SkRect& r, const SkPaint& paint) override;
71     void drawOval(const SkRect& oval, const SkPaint& paint) override;
72     void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
73     void drawPoints(SkCanvas::PointMode mode, size_t count,
74                     const SkPoint[], const SkPaint& paint) override;
75     void drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable = false) override;
76 
77     // No need to specialize drawDRRect, drawArc, drawRegion, drawPatch as the default impls all
78     // route to drawPath, drawRect, or drawVertices as desired.
79 
80     // Pixel management
81     sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
82     SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
83 
84     bool onReadPixels(const SkPixmap&, int x, int y) override;
85 
86     /*
87      * TODO: These functions are not in scope to be implemented yet, but will need to be. Call them
88      * out explicitly so it's easy to keep tabs on how close feature-complete actually is.
89      */
90 
onAsRgnClip(SkRegion *)91     void onAsRgnClip(SkRegion*) const override {}
onClipShader(sk_sp<SkShader>)92     void onClipShader(sk_sp<SkShader>) override {}
onClipRegion(const SkRegion & deviceRgn,SkClipOp)93     void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {}
onReplaceClip(const SkIRect & rect)94     void onReplaceClip(const SkIRect& rect) override {}
95 
96     bool onWritePixels(const SkPixmap&, int x, int y) override;
97 
98     // TODO: This will likely be implemented with the same primitive building block that drawRect
99     // and drawRRect will rely on.
drawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],SkCanvas::QuadAAFlags aaFlags,const SkColor4f & color,SkBlendMode mode)100     void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
101                         SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color,
102                         SkBlendMode mode) override {}
103 
drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[],int count,const SkPoint dstClips[],const SkMatrix preViewMatrices[],const SkSamplingOptions &,const SkPaint &,SkCanvas::SrcRectConstraint)104     void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count,
105                             const SkPoint dstClips[], const SkMatrix preViewMatrices[],
106                             const SkSamplingOptions&, const SkPaint&,
107                             SkCanvas::SrcRectConstraint) override {}
108 
109     // TODO: These image drawing APIs can likely be implemented with the same primitive building
110     // block that drawEdgeAAImageSet will use.
drawImageRect(const SkImage *,const SkRect * src,const SkRect & dst,const SkSamplingOptions &,const SkPaint &,SkCanvas::SrcRectConstraint)111     void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
112                        const SkSamplingOptions&, const SkPaint&,
113                        SkCanvas::SrcRectConstraint) override {}
drawImageLattice(const SkImage *,const SkCanvas::Lattice &,const SkRect & dst,SkFilterMode,const SkPaint &)114     void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
115                           const SkRect& dst, SkFilterMode, const SkPaint&) override {}
drawAtlas(const SkRSXform[],const SkRect[],const SkColor[],int count,sk_sp<SkBlender>,const SkPaint &)116     void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>,
117                    const SkPaint&) override {}
118 
drawDrawable(SkCanvas *,SkDrawable *,const SkMatrix *)119     void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override {}
drawVertices(const SkVertices *,sk_sp<SkBlender>,const SkPaint &)120     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) override {}
drawCustomMesh(SkCustomMesh,sk_sp<SkBlender>,const SkPaint &)121     void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override {}
drawShadow(const SkPath &,const SkDrawShadowRec &)122     void drawShadow(const SkPath&, const SkDrawShadowRec&) override {}
onDrawGlyphRunList(SkCanvas *,const SkGlyphRunList &,const SkPaint &)123     void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {}
124 
drawDevice(SkBaseDevice *,const SkSamplingOptions &,const SkPaint &)125     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {}
drawSpecial(SkSpecialImage *,const SkMatrix & localToDevice,const SkSamplingOptions &,const SkPaint &)126     void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,
127                      const SkSamplingOptions&, const SkPaint&) override {}
128 
129     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
130     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
131     sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false) override;
132 
133     // DrawFlags alters the effects used by drawShape.
134     enum class DrawFlags : unsigned {
135         kNone             = 0b00,
136 
137         // Any SkMaskFilter on the SkPaint passed into drawShape() is ignored.
138         // - drawPaint, drawVertices, drawAtlas
139         // - drawShape after it's applied the mask filter.
140         kIgnoreMaskFilter = 0b01,
141 
142         // Any SkPathEffect on the SkPaint passed into drawShape() is ignored.
143         // - drawPaint, drawImageLattice, drawImageRect, drawEdgeAAImageSet, drawVertices, drawAtlas
144         // - drawShape after it's applied the path effect.
145         kIgnorePathEffect = 0b10,
146     };
147     SKGPU_DECL_MASK_OPS_FRIENDS(DrawFlags);
148 
149     Device(Recorder*, sk_sp<DrawContext>);
150 
151     // Handles applying path effects, mask filters, stroke-and-fill styles, and hairlines.
152     // Ignores geometric style on the paint in favor of explicitly provided SkStrokeRec and flags.
153     void drawShape(const Shape&,
154                    const SkPaint&,
155                    const SkStrokeRec&,
156                    Mask<DrawFlags> = DrawFlags::kNone);
157 
158     // Determines most optimal painters order for a draw of the given shape and style. This computes
159     // the draw's bounds, applying both the style and scissor to the returned bounds. Low-level
160     // renderers must not draw outside of these bounds or decisions made about ordering draw
161     // operations at the Device level can be invalidated. In addition to the scissor test and draw
162     // bounds, this returns the largest compressed painter's order of the clip shapes that affect
163     // the draw (the draw's order must be greater than this value to be rendered/clipped correctly).
164     //
165     // This also records the draw's bounds to any clip elements that affect it so that they are
166     // recorded when popped off the stack, or making an image snapshot of the Device.
167     std::pair<Clip, CompressedPaintersOrder>
168     applyClipToDraw(const Transform&, const Shape&, const SkStrokeRec&, PaintersDepth z);
169 
170     bool needsFlushBeforeDraw(int numNewDraws) const;
171 
172     Recorder* fRecorder;
173     sk_sp<DrawContext> fDC;
174 
175     // Tracks accumulated intersections for ordering dependent use of the color and depth attachment
176     // (i.e. depth-based clipping, and transparent blending)
177     std::unique_ptr<BoundsManager> fColorDepthBoundsManager;
178     // Tracks disjoint stencil indices for all recordered draws
179     std::unique_ptr<IntersectionTreeSet> fDisjointStencilSet;
180 
181     // The max depth value sent to the DrawContext, incremented so each draw has a unique value.
182     PaintersDepth fCurrentDepth;
183 
184     bool fDrawsOverlap;
185 };
186 
187 SKGPU_MAKE_MASK_OPS(Device::DrawFlags)
188 
189 } // namespace skgpu
190 
191 #endif // skgpu_Device_DEFINED
192