• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
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 SurfaceDrawContext_v1_DEFINED
9 #define SurfaceDrawContext_v1_DEFINED
10 
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkDrawable.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/core/SkSurface.h"
15 #include "include/core/SkSurfaceProps.h"
16 #include "include/private/base/SkTArray.h"
17 #include "include/private/gpu/ganesh/GrTypesPriv.h"
18 #include "src/core/SkDevice.h"
19 #include "src/gpu/ganesh/GrPaint.h"
20 #include "src/gpu/ganesh/GrRenderTargetProxy.h"
21 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
22 #include "src/gpu/ganesh/GrXferProcessor.h"
23 #include "src/gpu/ganesh/SurfaceFillContext.h"
24 #include "src/gpu/ganesh/geometry/GrQuad.h"
25 #include "src/gpu/ganesh/ops/OpsTask.h"
26 
27 class GrBackendSemaphore;
28 class GrClip;
29 class GrColorSpaceXform;
30 class GrDrawOp;
31 class GrDstProxyView;
32 class GrHardClip;
33 class GrOp;
34 struct GrQuadSetEntry;
35 class GrRenderTarget;
36 class GrStyledShape;
37 class GrStyle;
38 class GrTextureProxy;
39 struct GrTextureSetEntry;
40 struct GrUserStencilSettings;
41 struct SkDrawShadowRec;
42 struct SkIPoint;
43 struct SkIRect;
44 class SkLatticeIter;
45 class SkMatrix;
46 class SkPaint;
47 class SkPath;
48 struct SkPoint;
49 struct SkRect;
50 class SkRegion;
51 class SkRRect;
52 struct SkRSXform;
53 class SkTextBlob;
54 class SkVertices;
55 
56 namespace sktext {
57 class GlyphRunList;
58 }
59 
60 namespace skgpu::ganesh {
61 
62 /**
63  * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
64  */
65 class SurfaceDrawContext final : public SurfaceFillContext {
66 public:
67     static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
68                                                     GrColorType,
69                                                     sk_sp<GrSurfaceProxy>,
70                                                     sk_sp<SkColorSpace>,
71                                                     GrSurfaceOrigin,
72                                                     const SkSurfaceProps&);
73 
74     /* Uses the default texture format for the color type */
75     static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
76                                                     GrColorType,
77                                                     sk_sp<SkColorSpace>,
78                                                     SkBackingFit,
79                                                     SkISize dimensions,
80                                                     const SkSurfaceProps&,
81                                                     std::string_view label,
82                                                     int sampleCnt = 1,
83                                                     skgpu::Mipmapped = skgpu::Mipmapped::kNo,
84                                                     skgpu::Protected = skgpu::Protected::kNo,
85                                                     GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin,
86                                                     skgpu::Budgeted = skgpu::Budgeted::kYes);
87 
88     /**
89      * Takes custom swizzles rather than determining swizzles from color type and format.
90      * It will have color type kUnknown.
91      */
92     static std::unique_ptr<SurfaceDrawContext> Make(GrRecordingContext*,
93                                                     sk_sp<SkColorSpace>,
94                                                     SkBackingFit,
95                                                     SkISize dimensions,
96                                                     const GrBackendFormat&,
97                                                     int sampleCnt,
98                                                     skgpu::Mipmapped,
99                                                     skgpu::Protected,
100                                                     skgpu::Swizzle readSwizzle,
101                                                     skgpu::Swizzle writeSwizzle,
102                                                     GrSurfaceOrigin,
103                                                     skgpu::Budgeted,
104                                                     const SkSurfaceProps&,
105                                                     std::string_view label);
106 
107     // Same as previous factory but will try to use fallback GrColorTypes if the one passed in
108     // fails. The fallback GrColorType will have at least the number of channels and precision per
109     // channel as the passed in GrColorType. It may also swizzle the changes (e.g., BGRA -> RGBA).
110     // SRGB-ness will be preserved.
111     static std::unique_ptr<SurfaceDrawContext> MakeWithFallback(
112             GrRecordingContext*,
113             GrColorType,
114             sk_sp<SkColorSpace>,
115             SkBackingFit,
116             SkISize dimensions,
117             const SkSurfaceProps&,
118             int sampleCnt,
119             skgpu::Mipmapped,
120             skgpu::Protected,
121             GrSurfaceOrigin = kBottomLeft_GrSurfaceOrigin,
122             skgpu::Budgeted = skgpu::Budgeted::kYes);
123 
124     // Creates a SurfaceDrawContext that wraps the passed in GrBackendTexture.
125     static std::unique_ptr<SurfaceDrawContext> MakeFromBackendTexture(
126             GrRecordingContext*,
127             GrColorType,
128             sk_sp<SkColorSpace>,
129             const GrBackendTexture&,
130             int sampleCnt,
131             GrSurfaceOrigin,
132             const SkSurfaceProps&,
133             sk_sp<skgpu::RefCntedCallback> releaseHelper);
134 
135     SurfaceDrawContext(GrRecordingContext*,
136                        GrSurfaceProxyView readView,
137                        GrSurfaceProxyView writeView,
138                        GrColorType,
139                        sk_sp<SkColorSpace>,
140                        const SkSurfaceProps&);
141 
142     ~SurfaceDrawContext() override;
143 
144     /**
145      *  Draw everywhere (respecting the clip) with the paint.
146      */
147     void drawPaint(const GrClip*, GrPaint&&, const SkMatrix& viewMatrix);
148 
149     /**
150      * Draw the rect using a paint.
151      * @param paint        describes how to color pixels.
152      * @param GrAA         Controls whether rect is antialiased
153      * @param viewMatrix   transformation matrix
154      * @param style        The style to apply. Null means fill. Currently path effects are not
155      *                     allowed.
156      * The rects coords are used to access the paint (through texture matrix)
157      */
158     void drawRect(const GrClip*,
159                   GrPaint&& paint,
160                   GrAA,
161                   const SkMatrix& viewMatrix,
162                   const SkRect&,
163                   const GrStyle* style = nullptr);
164 
165     /**
166      * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
167      *
168      * @param GrPaint      describes how to color pixels.
169      * @param GrAA         Controls whether rect is antialiased
170      * @param SkMatrix     transformation matrix which applies to rectToDraw
171      * @param rectToDraw   the rectangle to draw
172      * @param localRect    the rectangle of shader coordinates applied to rectToDraw
173      */
174     void fillRectToRect(const GrClip*,
175                         GrPaint&&,
176                         GrAA,
177                         const SkMatrix&,
178                         const SkRect& rectToDraw,
179                         const SkRect& localRect);
180 
181     /**
182      * Fills a block of pixels with a paint and a localMatrix, respecting the clip.
183      */
fillPixelsWithLocalMatrix(const GrClip * clip,GrPaint && paint,const SkIRect & bounds,const SkMatrix & localMatrix)184     void fillPixelsWithLocalMatrix(const GrClip* clip,
185                                    GrPaint&& paint,
186                                    const SkIRect& bounds,
187                                    const SkMatrix& localMatrix) {
188         SkRect rect = SkRect::Make(bounds);
189         DrawQuad quad{GrQuad::MakeFromRect(rect, SkMatrix::I()),
190                       GrQuad::MakeFromRect(rect, localMatrix), GrQuadAAFlags::kNone};
191         this->drawFilledQuad(clip, std::move(paint), &quad);
192     }
193 
194     /**
195      * Creates an op that draws a fill rect with per-edge control over anti-aliasing.
196      *
197      * This is a specialized version of fillQuadWithEdgeAA, but is kept separate since knowing
198      * the geometry is a rectangle affords more optimizations.
199      */
200     void fillRectWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA,
201                             const SkMatrix& viewMatrix, const SkRect& rect,
202                             const SkRect* optionalLocalRect = nullptr) {
203         if (edgeAA == GrQuadAAFlags::kAll) {
204             this->fillRectToRect(clip, std::move(paint), GrAA::kYes, viewMatrix, rect,
205                                  (optionalLocalRect) ? *optionalLocalRect : rect);
206             return;
207         }
208         const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect;
209         DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect), edgeAA};
210         this->drawFilledQuad(clip, std::move(paint), &quad);
211     }
212 
213     /**
214      * Similar to fillRectWithEdgeAA but draws an arbitrary 2D convex quadrilateral transformed
215      * by 'viewMatrix', with per-edge control over anti-aliasing. The quad should follow the
216      * ordering used by SkRect::toQuad(), which determines how the edge AA is applied:
217      *  - "top" = points [0] and [1]
218      *  - "right" = points[1] and [2]
219      *  - "bottom" = points[2] and [3]
220      *  - "left" = points[3] and [0]
221      *
222      * The last argument, 'optionalLocalQuad', can be null if no separate local coordinates are
223      * necessary.
224      */
fillQuadWithEdgeAA(const GrClip * clip,GrPaint && paint,GrQuadAAFlags edgeAA,const SkMatrix & viewMatrix,const SkPoint points[4],const SkPoint optionalLocalPoints[4])225     void fillQuadWithEdgeAA(const GrClip* clip, GrPaint&& paint, GrQuadAAFlags edgeAA,
226                             const SkMatrix& viewMatrix, const SkPoint points[4],
227                             const SkPoint optionalLocalPoints[4]) {
228         const SkPoint* localPoints = optionalLocalPoints ? optionalLocalPoints : points;
229         DrawQuad quad{GrQuad::MakeFromSkQuad(points, viewMatrix),
230                       GrQuad::MakeFromSkQuad(localPoints, SkMatrix::I()), edgeAA};
231         this->drawFilledQuad(clip, std::move(paint), &quad);
232     }
233 
234     // TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer
235     void drawQuadSet(const GrClip* clip, GrPaint&& paint, const SkMatrix& viewMatrix,
236                      const GrQuadSetEntry[], int cnt);
237 
238     /**
239      * Creates an op that draws a subrectangle of a texture. The passed color is modulated by the
240      * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect'
241      * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to
242      * device space.
243      */
244     void drawTexture(const GrClip*,
245                      GrSurfaceProxyView,
246                      SkAlphaType,
247                      GrSamplerState::Filter,
248                      GrSamplerState::MipmapMode,
249                      SkBlendMode,
250                      const SkPMColor4f&,
251                      const SkRect& srcRect,
252                      const SkRect& dstRect,
253                      GrQuadAAFlags,
254                      SkCanvas::SrcRectConstraint,
255                      const SkMatrix&,
256                      sk_sp<GrColorSpaceXform>);
257 
258     /**
259      * Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by
260      * 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'subset'. If
261      * 'subset' is null, it's equivalent to using the fast src rect constraint. If 'subset' is
262      * provided, the strict src rect constraint is applied using 'subset'.
263      */
drawTextureQuad(const GrClip * clip,GrSurfaceProxyView view,GrColorType srcColorType,SkAlphaType srcAlphaType,GrSamplerState::Filter filter,GrSamplerState::MipmapMode mm,SkBlendMode mode,const SkPMColor4f & color,const SkPoint srcQuad[4],const SkPoint dstQuad[4],GrQuadAAFlags edgeAA,const SkRect * subset,const SkMatrix & viewMatrix,sk_sp<GrColorSpaceXform> texXform)264     void drawTextureQuad(const GrClip* clip,
265                          GrSurfaceProxyView view,
266                          GrColorType srcColorType,
267                          SkAlphaType srcAlphaType,
268                          GrSamplerState::Filter filter,
269                          GrSamplerState::MipmapMode mm,
270                          SkBlendMode mode,
271                          const SkPMColor4f& color,
272                          const SkPoint srcQuad[4],
273                          const SkPoint dstQuad[4],
274                          GrQuadAAFlags edgeAA,
275                          const SkRect* subset,
276                          const SkMatrix& viewMatrix,
277                          sk_sp<GrColorSpaceXform> texXform) {
278         DrawQuad quad{GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
279                       GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), edgeAA};
280         this->drawTexturedQuad(clip, std::move(view), srcAlphaType, std::move(texXform), filter, mm,
281                                color, mode, &quad, subset);
282     }
283 
284     /**
285      * Draws a set of textures with a shared filter, color, view matrix, color xform, and
286      * texture color xform. The textures must all have the same GrTextureType and GrConfig.
287      *
288      * If any entries provide a non-null fDstClip array, it will be read from immediately based on
289      * fDstClipCount, so the pointer can become invalid after this returns.
290      *
291      * 'proxRunCnt' is the number of proxy changes encountered in the entry array. Technically this
292      * can be inferred from the array within this function, but the information is already known
293      * by SkGpuDevice, so no need to incur another iteration over the array.
294      */
295     void drawTextureSet(const GrClip*,
296                         GrTextureSetEntry[],
297                         int cnt,
298                         int proxyRunCnt,
299                         GrSamplerState::Filter,
300                         GrSamplerState::MipmapMode,
301                         SkBlendMode mode,
302                         SkCanvas::SrcRectConstraint,
303                         const SkMatrix& viewMatrix,
304                         sk_sp<GrColorSpaceXform> texXform);
305 
306     /**
307      * Draw a roundrect using a paint.
308      *
309      * @param paint       describes how to color pixels.
310      * @param GrAA        Controls whether rrect is antialiased.
311      * @param viewMatrix  transformation matrix
312      * @param rrect       the roundrect to draw
313      * @param style       style to apply to the rrect. Currently path effects are not allowed.
314      */
315     void drawRRect(const GrClip*,
316                    GrPaint&&,
317                    GrAA,
318                    const SkMatrix& viewMatrix,
319                    const SkRRect& rrect,
320                    const GrStyle& style);
321 
322     /**
323      * Use a fast method to render the ambient and spot shadows for a path.
324      * Will return false if not possible for the given path.
325      *
326      * @param viewMatrix   transformation matrix
327      * @param path         the path to shadow
328      * @param rec          parameters for shadow rendering
329      */
330     bool drawFastShadow(const GrClip*,
331                         const SkMatrix& viewMatrix,
332                         const SkPath& path,
333                         const SkDrawShadowRec& rec);
334 
335     /**
336      * Draws a path.
337      *
338      * @param paint         describes how to color pixels.
339      * @param GrAA          Controls whether the path is antialiased.
340      * @param viewMatrix    transformation matrix
341      * @param path          the path to draw
342      * @param style         style to apply to the path.
343      */
344     void drawPath(const GrClip*,
345                   GrPaint&&,
346                   GrAA,
347                   const SkMatrix& viewMatrix,
348                   const SkPath&,
349                   const GrStyle&);
350 
351     /**
352      * Draws a shape.
353      *
354      * @param paint         describes how to color pixels.
355      * @param GrAA          Controls whether the path is antialiased.
356      * @param viewMatrix    transformation matrix
357      * @param shape         the shape to draw
358      */
359     void drawShape(const GrClip*,
360                    GrPaint&&,
361                    GrAA,
362                    const SkMatrix& viewMatrix,
363                    GrStyledShape&&);
364 
365     /**
366      * Draws vertices with a paint.
367      *
368      * @param   paint            describes how to color pixels.
369      * @param   viewMatrix       transformation matrix
370      * @param   vertices         specifies the mesh to draw.
371      * @param   overridePrimType primitive type to draw. If NULL, derive prim type from vertices.
372      * @param   skipColorXform   if true, do not apply a color space transfer function
373      */
374     void drawVertices(const GrClip*,
375                       GrPaint&& paint,
376                       const SkMatrix& viewMatrix,
377                       sk_sp<SkVertices> vertices,
378                       GrPrimitiveType* overridePrimType = nullptr,
379                       bool skipColorXform = false);
380 
381     /**
382      * Draws a custom mesh with a paint.
383      *
384      * @param   paint      describes how to color pixels.
385      * @param   viewMatrix transformation matrix
386      * @param   mesh       the mesh to draw.
387      * @param   children   child effects referenced by SkMesh shaders
388      */
389     void drawMesh(const GrClip*,
390                   GrPaint&& paint,
391                   const SkMatrix& viewMatrix,
392                   const SkMesh& mesh,
393                   skia_private::TArray<std::unique_ptr<GrFragmentProcessor>> children);
394 
395     /**
396      * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
397      * sprite rectangle edges.
398      *
399      * @param   paint           describes how to color pixels.
400      * @param   viewMatrix      transformation matrix
401      * @param   spriteCount     number of sprites.
402      * @param   xform           array of compressed transformation data, required.
403      * @param   texRect         array of texture rectangles used to access the paint.
404      * @param   colors          optional array of per-sprite colors, supercedes
405      *                          the paint's color field.
406      */
407     void drawAtlas(const GrClip*,
408                    GrPaint&& paint,
409                    const SkMatrix& viewMatrix,
410                    int spriteCount,
411                    const SkRSXform xform[],
412                    const SkRect texRect[],
413                    const SkColor colors[]);
414 
415     /**
416      * Draws a region.
417      *
418      * @param paint         describes how to color pixels
419      * @param viewMatrix    transformation matrix
420      * @param aa            should the rects of the region be antialiased.
421      * @param region        the region to be drawn
422      * @param style         style to apply to the region
423      */
424     void drawRegion(const GrClip*,
425                     GrPaint&& paint,
426                     GrAA aa,
427                     const SkMatrix& viewMatrix,
428                     const SkRegion& region,
429                     const GrStyle& style,
430                     const GrUserStencilSettings* ss = nullptr);
431 
432     /**
433      * Draws an oval.
434      *
435      * @param paint         describes how to color pixels.
436      * @param GrAA          Controls whether the oval is antialiased.
437      * @param viewMatrix    transformation matrix
438      * @param oval          the bounding rect of the oval.
439      * @param style         style to apply to the oval. Currently path effects are not allowed.
440      */
441     void drawOval(const GrClip*,
442                   GrPaint&& paint,
443                   GrAA,
444                   const SkMatrix& viewMatrix,
445                   const SkRect& oval,
446                   const GrStyle& style);
447 
448     /**
449      * Draws a partial arc of an oval.
450      *
451      * @param paint         describes how to color pixels.
452      * @param GrGrAA        Controls whether the arc is antialiased.
453      * @param viewMatrix    transformation matrix.
454      * @param oval          the bounding rect of the oval.
455      * @param startAngle    starting angle in degrees.
456      * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
457      * @param useCenter     true means that the implied path begins at the oval center, connects as
458      *                      a line to the point indicated by the start contains the arc indicated by
459      *                      the sweep angle. If false the line beginning at the center point is
460      *                      omitted.
461      * @param style         style to apply to the oval.
462      */
463     void drawArc(const GrClip*,
464                  GrPaint&& paint,
465                  GrAA,
466                  const SkMatrix& viewMatrix,
467                  const SkArc& arc,
468                  const GrStyle& style);
469 
470     /**
471      * Draw the image as a set of rects, specified by |iter|.
472      */
473     void drawImageLattice(const GrClip*,
474                           GrPaint&&,
475                           const SkMatrix& viewMatrix,
476                           GrSurfaceProxyView,
477                           SkAlphaType alphaType,
478                           sk_sp<GrColorSpaceXform>,
479                           GrSamplerState::Filter,
480                           std::unique_ptr<SkLatticeIter>,
481                           const SkRect& dst);
482 
483     /**
484      * Draw the text specified by the GlyphRunList.
485      *
486      * @param viewMatrix      transformation matrix
487      * @param glyphRunList    text, text positions, and paint.
488      */
489     void drawGlyphRunList(SkCanvas*,
490                           const GrClip*,
491                           const SkMatrix& viewMatrix,
492                           const sktext::GlyphRunList& glyphRunList,
493                           SkStrikeDeviceInfo strikeDeviceInfo,
494                           const SkPaint& paint);
495 
496     /**
497      * Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
498      * command stream.
499      */
500     void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds);
501 
502     // called to note the last clip drawn to the stencil buffer.
503     // TODO: remove after clipping overhaul.
504     void setLastClip(uint32_t clipStackGenID,
505                      const SkIRect& devClipBounds,
506                      int numClipAnalyticElements);
507 
508     // called to determine if we have to render the clip into SB.
509     // TODO: remove after clipping overhaul.
510     bool mustRenderClip(uint32_t clipStackGenID,
511                         const SkIRect& devClipBounds,
512                         int numClipAnalyticElements);
513 
clearStencilClip(const SkIRect & scissor,bool insideStencilMask)514     void clearStencilClip(const SkIRect& scissor, bool insideStencilMask) {
515         this->internalStencilClear(&scissor, insideStencilMask);
516     }
517 
518     // While this can take a general clip, since ClipStack relies on this function, it must take
519     // care to only provide hard clips or we could get stuck in a loop. The general clip is needed
520     // so that path renderers can use this function.
521     void stencilRect(const GrClip* clip,
522                      const GrUserStencilSettings* ss,
523                      GrPaint&& paint,
524                      GrAA doStencilMSAA,
525                      const SkMatrix& viewMatrix,
526                      const SkRect& rect,
527                      const SkMatrix* localMatrix = nullptr) {
528         // Since this provides stencil settings to drawFilledQuad, it performs a different AA type
529         // resolution compared to regular rect draws, which is the main reason it remains separate.
530         DrawQuad quad{GrQuad::MakeFromRect(rect, viewMatrix),
531                       localMatrix ? GrQuad::MakeFromRect(rect, *localMatrix) : GrQuad(rect),
532                       doStencilMSAA == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone};
533         this->drawFilledQuad(clip, std::move(paint), &quad, ss);
534     }
535 
536     // Fills the user stencil bits with a non-zero value at every sample inside the path. This will
537     // likely be implemented with a Redbook algorithm, but it is not guaranteed. The samples being
538     // rendered to must be zero initially.
539     bool stencilPath(const GrHardClip*,
540                      GrAA doStencilMSAA,
541                      const SkMatrix& viewMatrix,
542                      const SkPath&);
543 
544     /**
545      * Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings
546      * for each color sample written.
547      */
548     bool drawAndStencilPath(const GrHardClip*,
549                             const GrUserStencilSettings*,
550                             SkRegion::Op op,
551                             bool invert,
552                             GrAA doStencilMSAA,
553                             const SkMatrix& viewMatrix,
554                             const SkPath&);
555 
556     skgpu::Budgeted isBudgeted() const;
557 
558     int maxWindowRectangles() const;
559 
560     /*
561      * This unique ID will not change for a given SurfaceDrawContext. However, it is _NOT_
562      * guaranteed to match the uniqueID of the underlying GrRenderTarget - beware!
563      */
uniqueID()564     GrSurfaceProxy::UniqueID uniqueID() const { return this->asSurfaceProxy()->uniqueID(); }
565 
566     // Allows caller of addDrawOp to know which op list an op will be added to.
567     using WillAddOpFn = void(GrOp*, uint32_t opsTaskID);
568     // These perform processing specific to GrDrawOp-derived ops before recording them into an
569     // op list. Before adding the op to an op list the WillAddOpFn is called. Note that it
570     // will not be called in the event that the op is discarded. Moreover, the op may merge into
571     // another op after the function is called (either before addDrawOp returns or some time later).
572     //
573     // If the clip pointer is null, no clipping will be performed.
574     void addDrawOp(const GrClip*,
575                    GrOp::Owner,
576                    const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());
addDrawOp(GrOp::Owner op)577     void addDrawOp(GrOp::Owner op) { this->addDrawOp(nullptr, std::move(op)); }
578 
refsWrappedObjects()579     bool refsWrappedObjects() const { return this->asRenderTargetProxy()->refsWrappedObjects(); }
580 
581     /**
582      *  The next time this SurfaceDrawContext is flushed, the gpu will wait on the passed in
583      *  semaphores before executing any commands.
584      */
585     bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
586                           bool deleteSemaphoresAfterWait);
587 
numSamples()588     int numSamples() const { return this->asRenderTargetProxy()->numSamples(); }
surfaceProps()589     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
canUseDynamicMSAA()590     bool canUseDynamicMSAA() const { return fCanUseDynamicMSAA; }
wrapsVkSecondaryCB()591     bool wrapsVkSecondaryCB() const { return this->asRenderTargetProxy()->wrapsVkSecondaryCB(); }
592 
alwaysAntialias()593     bool alwaysAntialias() const {
594         return fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag;
595     }
596 
chooseAA(const SkPaint & paint)597     GrAA chooseAA(const SkPaint& paint) {
598         return GrAA(paint.isAntiAlias() || this->alwaysAntialias());
599     }
600 
chooseAAType(GrAA aa)601     GrAAType chooseAAType(GrAA aa) {
602         if (this->numSamples() > 1 || fCanUseDynamicMSAA) {
603             // Always trigger DMSAA when it's available. The coverage ops that know how to handle
604             // both single and multisample targets without popping will do so without calling
605             // chooseAAType.
606             return GrAAType::kMSAA;
607         }
608         return (aa == GrAA::kYes) ? GrAAType::kCoverage : GrAAType::kNone;
609     }
610 
611     // This entry point should only be called if the backing GPU object is known to be
612     // instantiated.
accessRenderTarget()613     GrRenderTarget* accessRenderTarget() { return this->asSurfaceProxy()->peekRenderTarget(); }
614 
615 #if defined(GR_TEST_UTILS)
testingOnly_SetPreserveOpsOnFullClear()616     void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
617 #endif
618 
619     void drawStrokedLine(const GrClip*, GrPaint&&, GrAA, const SkMatrix&, const SkPoint[2],
620                          const SkStrokeRec&);
621 
622 private:
623     enum class QuadOptimization;
624 
625     void willReplaceOpsTask(OpsTask* prevTask, OpsTask* nextTask) override;
626 
627     OpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const override;
628     void setNeedsStencil();
629 
630     void internalStencilClear(const SkIRect* scissor, bool insideStencilMask);
631 
632     // 'stencilSettings' are provided merely for decision making purposes; When non-null,
633     // optimization strategies that submit special ops are avoided.
634     //
635     // 'quad' should be the original draw request on input, and will be updated as
636     // appropriate depending on the returned optimization level.
637     //
638     // If kSubmitted is returned, the provided paint was consumed. Otherwise it is left unchanged.
639     QuadOptimization attemptQuadOptimization(const GrClip* clip,
640                                              const GrUserStencilSettings* stencilSettings,
641                                              DrawQuad* quad,
642                                              GrPaint* paint);
643 
644     // The overall AA policy is determined by the quad's edge flags: kNone is no AA, and anything
645     // else uses some form of anti-aliasing. If 'ss' is non-null, that will be MSAA; otherwise it's
646     // MSAA or analytic coverage per chooseAAType(). This will always attempt to apply
647     // quad optimizations, so all quad/rect public APIs should rely on this function for consistent
648     // clipping behavior. 'quad' will be modified in place to reflect final rendered geometry.
649     void drawFilledQuad(const GrClip* clip,
650                         GrPaint&& paint,
651                         DrawQuad* quad,
652                         const GrUserStencilSettings* ss = nullptr);
653 
654     // Like drawFilledQuad but does not require using a GrPaint or FP for texturing.
655     // 'quad' may be modified in place to reflect final geometry.
656     void drawTexturedQuad(const GrClip* clip,
657                           GrSurfaceProxyView proxyView,
658                           SkAlphaType alphaType,
659                           sk_sp<GrColorSpaceXform> textureXform,
660                           GrSamplerState::Filter filter,
661                           GrSamplerState::MipmapMode,
662                           const SkPMColor4f& color,
663                           SkBlendMode blendMode,
664                           DrawQuad* quad,
665                           const SkRect* subset = nullptr);
666 
667     // Tries to detect if the given shape is a simple, and draws it without path rendering if
668     // we know how.
669     bool drawSimpleShape(const GrClip*, GrPaint*, GrAA, const SkMatrix&, const GrStyledShape&);
670 
671     // If 'attemptDrawSimple' is true, of if the original shape is marked as having been simplfied,
672     // this will attempt to re-route through drawSimpleShape() to see if we can avoid path rendering
673     // one more time.
674     void drawShapeUsingPathRenderer(const GrClip*, GrPaint&&, GrAA, const SkMatrix&,
675                                     GrStyledShape&&, bool attemptDrawSimple = false);
676 
677     // Makes a copy of the proxy if it is necessary for the draw and places the texture that should
678     // be used by GrXferProcessor to access the destination color in 'result'. If the return
679     // value is false then a texture copy could not be made.
680     //
681     // The op should have already had setClippedBounds called on it.
682     [[nodiscard]] bool setupDstProxyView(const SkRect& opBounds,
683                                          bool opRequiresMSAA,
684                                          GrDstProxyView* result);
685 
686     OpsTask* replaceOpsTaskIfModifiesColor();
687 
688     const SkSurfaceProps fSurfaceProps;
689     const bool fCanUseDynamicMSAA;
690 
691     bool fNeedsStencil = false;
692 
693 #if defined(GR_TEST_UTILS)
694     bool fPreserveOpsOnFullClear_TestingOnly = false;
695 #endif
696 };
697 
698 }  // namespace skgpu::ganesh
699 
700 #endif // SurfaceDrawContext_v1_DEFINED
701