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