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