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_graphite_Device_DEFINED 9 #define skgpu_graphite_Device_DEFINED 10 11 #include "include/gpu/GpuTypes.h" 12 #include "src/core/SkDevice.h" 13 #include "src/core/SkEnumBitMask.h" 14 #include "src/gpu/graphite/ClipStack_graphite.h" 15 #include "src/gpu/graphite/DrawOrder.h" 16 #include "src/gpu/graphite/geom/Rect.h" 17 #include "src/gpu/graphite/geom/Transform_graphite.h" 18 #include "src/text/gpu/SDFTControl.h" 19 #include "src/text/gpu/SubRunContainer.h" 20 21 class SkStrokeRec; 22 23 namespace sktext::gpu { 24 class AtlasSubRun; 25 enum class Budgeted : bool; 26 } // namespace sktext::gpu 27 28 namespace skgpu::graphite { 29 30 class BoundsManager; 31 class Clip; 32 class Context; 33 class DrawContext; 34 class Geometry; 35 class PaintParams; 36 class Recorder; 37 class Renderer; 38 class Shape; 39 class StrokeStyle; 40 class TextureProxy; 41 class TextureProxyView; 42 43 class Device final : public SkBaseDevice { 44 public: 45 ~Device() override; 46 47 static sk_sp<Device> Make(Recorder*, 48 const SkImageInfo&, 49 skgpu::Budgeted, 50 Mipmapped, 51 const SkSurfaceProps&, 52 bool addInitialClear); 53 static sk_sp<Device> Make(Recorder*, 54 sk_sp<TextureProxy>, 55 const SkColorInfo&, 56 const SkSurfaceProps&, 57 bool addInitialClear); 58 static sk_sp<Device> Make(Recorder* recorder, 59 sk_sp<TextureProxy>, 60 SkISize deviceSize, 61 const SkColorInfo&, 62 const SkSurfaceProps&, 63 bool addInitialClear); 64 asGraphiteDevice()65 Device* asGraphiteDevice() override { return this; } 66 recorder()67 Recorder* recorder() { return fRecorder; } 68 // This call is triggered from the Recorder on its registered Devices. It is typically called 69 // when the Recorder is abandoned or deleted. 70 void abandonRecorder(); 71 72 // Ensures clip elements are drawn that will clip previous draw calls, snaps all pending work 73 // from the DrawContext as a RenderPassTask and records it in the Device's recorder. 74 void flushPendingWorkToRecorder(); 75 76 TextureProxyView createCopy(const SkIRect* subset, Mipmapped); 77 78 void asyncRescaleAndReadPixels(const SkImageInfo& info, 79 SkIRect srcRect, 80 SkImage::RescaleGamma rescaleGamma, 81 SkImage::RescaleMode rescaleMode, 82 SkImage::ReadPixelsCallback callback, 83 SkImage::ReadPixelsContext context); 84 85 void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, 86 sk_sp<SkColorSpace> dstColorSpace, 87 SkIRect srcRect, 88 SkISize dstSize, 89 SkImage::RescaleGamma rescaleGamma, 90 SkImage::RescaleMode, 91 SkImage::ReadPixelsCallback callback, 92 SkImage::ReadPixelsContext context); 93 94 const Transform& localToDeviceTransform(); 95 96 SkStrikeDeviceInfo strikeDeviceInfo() const override; 97 98 TextureProxy* target(); 99 TextureProxyView readSurfaceView() const; 100 101 private: 102 class IntersectionTreeSet; 103 104 // Clipping onSave()105 void onSave() override { fClip.save(); } onRestore()106 void onRestore() override { fClip.restore(); } 107 onClipIsWideOpen()108 bool onClipIsWideOpen() const override { 109 return fClip.clipState() == ClipStack::ClipState::kWideOpen; 110 } 111 bool onClipIsAA() const override; 112 ClipType onGetClipType() const override; 113 SkIRect onDevClipBounds() const override; 114 void onAsRgnClip(SkRegion*) const override; 115 116 void onClipRect(const SkRect& rect, SkClipOp, bool aa) override; 117 void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override; 118 void onClipPath(const SkPath& path, SkClipOp, bool aa) override; 119 120 void onClipShader(sk_sp<SkShader> shader) override; 121 void onClipRegion(const SkRegion& globalRgn, SkClipOp) override; 122 void onReplaceClip(const SkIRect& rect) override; 123 124 // Drawing 125 void drawPaint(const SkPaint& paint) override; 126 void drawRect(const SkRect& r, const SkPaint& paint) override; 127 void drawOval(const SkRect& oval, const SkPaint& paint) override; 128 void drawRRect(const SkRRect& rr, const SkPaint& paint) override; 129 void drawPoints(SkCanvas::PointMode mode, size_t count, 130 const SkPoint[], const SkPaint& paint) override; 131 void drawPath(const SkPath& path, const SkPaint& paint, bool pathIsMutable = false) override; 132 133 // No need to specialize drawDRRect, drawArc, drawRegion, drawPatch as the default impls all 134 // route to drawPath, drawRect, or drawVertices as desired. 135 136 // Pixel management 137 sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override; 138 SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override; 139 140 bool onReadPixels(const SkPixmap&, int x, int y) override; 141 142 bool onWritePixels(const SkPixmap&, int x, int y) override; 143 144 void onDrawGlyphRunList(SkCanvas*, const sktext::GlyphRunList&, 145 const SkPaint&, const SkPaint&) override; 146 147 void drawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], 148 SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color, 149 SkBlendMode mode) override; 150 151 void drawEdgeAAImageSet(const SkCanvas::ImageSetEntry[], int count, 152 const SkPoint dstClips[], const SkMatrix preViewMatrices[], 153 const SkSamplingOptions&, const SkPaint&, 154 SkCanvas::SrcRectConstraint) override; 155 156 void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, 157 const SkSamplingOptions&, const SkPaint&, 158 SkCanvas::SrcRectConstraint) override; 159 160 // TODO: Implement these using per-edge AA quads and an inlined image shader program. drawImageLattice(const SkImage *,const SkCanvas::Lattice &,const SkRect & dst,SkFilterMode,const SkPaint &)161 void drawImageLattice(const SkImage*, const SkCanvas::Lattice&, 162 const SkRect& dst, SkFilterMode, const SkPaint&) override {} drawAtlas(const SkRSXform[],const SkRect[],const SkColor[],int count,sk_sp<SkBlender>,const SkPaint &)163 void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>, 164 const SkPaint&) override {} 165 drawDrawable(SkCanvas *,SkDrawable *,const SkMatrix *)166 void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override {} 167 void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&, bool) override; drawMesh(const SkMesh &,sk_sp<SkBlender>,const SkPaint &)168 void drawMesh(const SkMesh&, sk_sp<SkBlender>, const SkPaint&) override {} drawShadow(const SkPath &,const SkDrawShadowRec &)169 void drawShadow(const SkPath&, const SkDrawShadowRec&) override {} 170 171 void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override; 172 void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice, 173 const SkSamplingOptions&, const SkPaint&) override; 174 175 sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override; 176 sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override; 177 sk_sp<SkSpecialImage> snapSpecial(const SkIRect& subset, bool forceCopy = false) override; 178 179 // DrawFlags alters the effects used by drawShape. 180 enum class DrawFlags : unsigned { 181 kNone = 0b000, 182 183 // Any SkMaskFilter on the SkPaint passed into drawGeometry() is ignored. 184 // - drawPaint, drawVertices, drawAtlas 185 // - drawShape after it's applied the mask filter. 186 kIgnoreMaskFilter = 0b001, 187 188 // Any SkPathEffect on the SkPaint passed into drawGeometry() is ignored. 189 // - drawPaint, drawImageLattice, drawImageRect, drawEdgeAAImageSet, drawVertices, drawAtlas 190 // - drawShape after it's applied the path effect. 191 kIgnorePathEffect = 0b010, 192 }; 193 SK_DECL_BITMASK_OPS_FRIENDS(DrawFlags); 194 195 Device(Recorder*, sk_sp<DrawContext>, bool addInitialClear); 196 197 // Handles applying path effects, mask filters, stroke-and-fill styles, and hairlines. 198 // Ignores geometric style on the paint in favor of explicitly provided SkStrokeRec and flags. 199 // All overridden SkDevice::draw() functions should bottom-out with calls to drawGeometry(). 200 void drawGeometry(const Transform&, 201 const Geometry&, 202 const SkPaint&, 203 const SkStrokeRec&, 204 SkEnumBitMask<DrawFlags> = DrawFlags::kNone, 205 sk_sp<SkBlender> primitiveBlender = nullptr, 206 bool skipColorXform = false); 207 208 // Like drawGeometry() but is Shape-only, depth-only, fill-only, and lets the ClipStack define 209 // the transform, clip, and DrawOrder (although Device still tracks stencil buffer usage). 210 void drawClipShape(const Transform&, const Shape&, const Clip&, DrawOrder); 211 212 // Handles primitive processing for atlas-based text 213 void drawAtlasSubRun(const sktext::gpu::AtlasSubRun*, 214 SkPoint drawOrigin, 215 const SkPaint& paint, 216 sk_sp<SkRefCnt> subRunStorage); 217 218 // Returns the Renderer to draw the shape in the given style. If SkStrokeRec is a 219 // stroke-and-fill, this returns the Renderer used for the fill portion and it can be assumed 220 // that Renderer::TessellatedStrokes() will be used for the stroke portion. 221 // 222 // TODO: Renderers may have fallbacks (e.g. pre-chop large paths, or convert stroke to fill). 223 // Are those handled inside ChooseRenderer() where it can modify the shape, stroke? or does it 224 // return a retry error code? or does drawGeometry() handle all the fallbacks, knowing that 225 // a particular shape type needs to be pre-chopped? 226 // TODO: Move this into a RendererSelector object provided by the Context. 227 const Renderer* chooseRenderer(const Geometry&, 228 const Clip&, 229 const SkStrokeRec&, 230 bool requireMSAA) const; 231 232 bool needsFlushBeforeDraw(int numNewDraws) const; 233 234 Recorder* fRecorder; 235 sk_sp<DrawContext> fDC; 236 237 ClipStack fClip; 238 239 // Tracks accumulated intersections for ordering dependent use of the color and depth attachment 240 // (i.e. depth-based clipping, and transparent blending) 241 std::unique_ptr<BoundsManager> fColorDepthBoundsManager; 242 // Tracks disjoint stencil indices for all recordered draws 243 std::unique_ptr<IntersectionTreeSet> fDisjointStencilSet; 244 245 // Lazily updated Transform constructed from localToDevice()'s SkM44 246 Transform fCachedLocalToDevice; 247 248 // The max depth value sent to the DrawContext, incremented so each draw has a unique value. 249 PaintersDepth fCurrentDepth; 250 251 const sktext::gpu::SDFTControl fSDFTControl; 252 253 bool fDrawsOverlap; 254 255 friend class ClipStack; // for recordDraw 256 friend class sktext::gpu::AtlasSubRun; // for drawAtlasSubRun 257 }; 258 259 SK_MAKE_BITMASK_OPS(Device::DrawFlags) 260 261 } // namespace skgpu::graphite 262 263 #endif // skgpu_graphite_Device_DEFINED 264