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