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