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