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 GrRenderTargetContext_DEFINED
9 #define GrRenderTargetContext_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/gpu/GrOpsTask.h"
18 #include "src/gpu/GrPaint.h"
19 #include "src/gpu/GrRenderTargetProxy.h"
20 #include "src/gpu/GrSurfaceContext.h"
21 #include "src/gpu/GrXferProcessor.h"
22 #include "src/gpu/geometry/GrQuad.h"
23 #include "src/gpu/text/GrTextTarget.h"
24 
25 class GrBackendSemaphore;
26 class GrClip;
27 class GrColorSpaceXform;
28 class GrCoverageCountingPathRenderer;
29 class GrDrawingManager;
30 class GrDrawOp;
31 class GrFixedClip;
32 class GrOp;
33 class GrRenderTarget;
34 class GrRenderTargetContextPriv;
35 class GrShape;
36 class GrStyle;
37 class GrTextureProxy;
38 struct GrUserStencilSettings;
39 struct SkDrawShadowRec;
40 class SkGlyphRunList;
41 struct SkIPoint;
42 struct SkIRect;
43 class SkLatticeIter;
44 class SkMatrix;
45 class SkPaint;
46 class SkPath;
47 struct SkPoint;
48 struct SkRect;
49 class SkRegion;
50 class SkRRect;
51 struct SkRSXform;
52 class SkTextBlob;
53 class SkVertices;
54 
55 /**
56  * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
57  */
58 class GrRenderTargetContext : public GrSurfaceContext {
59 public:
60     ~GrRenderTargetContext() override;
61 
62     virtual void drawGlyphRunList(const GrClip&, const SkMatrix& viewMatrix, const SkGlyphRunList&);
63 
64     /**
65      * Provides a perfomance hint that the render target's contents are allowed
66      * to become undefined.
67      */
68     void discard();
69 
70     enum class CanClearFullscreen : bool {
71         kNo = false,
72         kYes = true
73     };
74 
75     /**
76      * Clear the entire or rect of the render target, ignoring any clips.
77      * @param rect  the rect to clear or the whole thing if rect is NULL.
78      * @param color the color to clear to.
79      * @param CanClearFullscreen allows partial clears to be converted to fullscreen clears on
80      *                           tiling platforms where that is an optimization.
81      */
82     void clear(const SkIRect* rect, const SkPMColor4f& color, CanClearFullscreen);
83 
clear(const SkPMColor4f & color)84     void clear(const SkPMColor4f& color) {
85         return this->clear(nullptr, color, CanClearFullscreen::kYes);
86     }
87 
88     /**
89      *  Draw everywhere (respecting the clip) with the paint.
90      */
91     void drawPaint(const GrClip&, GrPaint&&, const SkMatrix& viewMatrix);
92 
93     /**
94      * Draw the rect using a paint.
95      * @param paint        describes how to color pixels.
96      * @param GrAA         Controls whether rect is antialiased
97      * @param viewMatrix   transformation matrix
98      * @param style        The style to apply. Null means fill. Currently path effects are not
99      *                     allowed.
100      * The rects coords are used to access the paint (through texture matrix)
101      */
102     void drawRect(const GrClip&,
103                   GrPaint&& paint,
104                   GrAA,
105                   const SkMatrix& viewMatrix,
106                   const SkRect&,
107                   const GrStyle* style = nullptr);
108 
109     /**
110      * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
111      *
112      * @param paint        describes how to color pixels.
113      * @param GrAA         Controls whether rect is antialiased
114      * @param viewMatrix   transformation matrix which applies to rectToDraw
115      * @param rectToDraw   the rectangle to draw
116      * @param localRect    the rectangle of shader coordinates applied to rectToDraw
117      */
fillRectToRect(const GrClip & clip,GrPaint && paint,GrAA aa,const SkMatrix & viewMatrix,const SkRect & rectToDraw,const SkRect & localRect)118     void fillRectToRect(const GrClip& clip,
119                         GrPaint&& paint,
120                         GrAA aa,
121                         const SkMatrix& viewMatrix,
122                         const SkRect& rectToDraw,
123                         const SkRect& localRect) {
124         this->drawFilledQuad(clip, std::move(paint), aa,
125                              aa == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone,
126                              GrQuad::MakeFromRect(rectToDraw, viewMatrix), GrQuad(localRect));
127     }
128 
129     /**
130      * Fills a rect with a paint and a localMatrix.
131      */
fillRectWithLocalMatrix(const GrClip & clip,GrPaint && paint,GrAA aa,const SkMatrix & viewMatrix,const SkRect & rect,const SkMatrix & localMatrix)132     void fillRectWithLocalMatrix(const GrClip& clip,
133                                  GrPaint&& paint,
134                                  GrAA aa,
135                                  const SkMatrix& viewMatrix,
136                                  const SkRect& rect,
137                                  const SkMatrix& localMatrix) {
138         this->drawFilledQuad(clip, std::move(paint), aa,
139                              aa == GrAA::kYes ? GrQuadAAFlags::kAll : GrQuadAAFlags::kNone,
140                              GrQuad::MakeFromRect(rect, viewMatrix),
141                              GrQuad::MakeFromRect(rect, localMatrix));
142     }
143 
144     /**
145      * Creates an op that draws a fill rect with per-edge control over anti-aliasing.
146      *
147      * This is a specialized version of fillQuadWithEdgeAA, but is kept separate since knowing
148      * the geometry is a rectangle affords more optimizations.
149      */
150     void fillRectWithEdgeAA(const GrClip& clip, GrPaint&& paint, GrAA aa, GrQuadAAFlags edgeAA,
151                             const SkMatrix& viewMatrix, const SkRect& rect,
152                             const SkRect* optionalLocalRect = nullptr) {
153         const SkRect& localRect = optionalLocalRect ? *optionalLocalRect : rect;
154         this->drawFilledQuad(clip, std::move(paint), aa, edgeAA,
155                              GrQuad::MakeFromRect(rect, viewMatrix), GrQuad(localRect));
156     }
157 
158     /**
159      * Similar to fillRectWithEdgeAA but draws an arbitrary 2D convex quadrilateral transformed
160      * by 'viewMatrix', with per-edge control over anti-aliasing. The quad should follow the
161      * ordering used by SkRect::toQuad(), which determines how the edge AA is applied:
162      *  - "top" = points [0] and [1]
163      *  - "right" = points[1] and [2]
164      *  - "bottom" = points[2] and [3]
165      *  - "left" = points[3] and [0]
166      *
167      * The last argument, 'optionalLocalQuad', can be null if no separate local coordinates are
168      * necessary.
169      */
fillQuadWithEdgeAA(const GrClip & clip,GrPaint && paint,GrAA aa,GrQuadAAFlags edgeAA,const SkMatrix & viewMatrix,const SkPoint quad[4],const SkPoint optionalLocalQuad[4])170     void fillQuadWithEdgeAA(const GrClip& clip, GrPaint&& paint, GrAA aa, GrQuadAAFlags edgeAA,
171                             const SkMatrix& viewMatrix, const SkPoint quad[4],
172                             const SkPoint optionalLocalQuad[4]) {
173         const SkPoint* localQuad = optionalLocalQuad ? optionalLocalQuad : quad;
174         this->drawFilledQuad(clip, std::move(paint), aa, edgeAA,
175                              GrQuad::MakeFromSkQuad(quad, viewMatrix),
176                              GrQuad::MakeFromSkQuad(localQuad, SkMatrix::I()));
177     }
178 
179     /** Used with drawQuadSet */
180     struct QuadSetEntry {
181         SkRect fRect;
182         SkPMColor4f fColor; // Overrides any color on the GrPaint
183         SkMatrix fLocalMatrix;
184         GrQuadAAFlags fAAFlags;
185     };
186 
187     // TODO(michaelludwig) - remove if the bulk API is not useful for SkiaRenderer
188     void drawQuadSet(const GrClip& clip, GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix,
189                      const QuadSetEntry[], int cnt);
190 
191     /**
192      * Creates an op that draws a subrectangle of a texture. The passed color is modulated by the
193      * texture's color. 'srcRect' specifies the rectangle of the texture to draw. 'dstRect'
194      * specifies the rectangle to draw in local coords which will be transformed by 'viewMatrix' to
195      * device space.
196      */
drawTexture(const GrClip & clip,sk_sp<GrTextureProxy> proxy,GrColorType srcColorType,GrSamplerState::Filter filter,SkBlendMode mode,const SkPMColor4f & color,const SkRect & srcRect,const SkRect & dstRect,GrAA aa,GrQuadAAFlags edgeAA,SkCanvas::SrcRectConstraint constraint,const SkMatrix & viewMatrix,sk_sp<GrColorSpaceXform> texXform)197     void drawTexture(const GrClip& clip, sk_sp<GrTextureProxy> proxy, GrColorType srcColorType,
198                      GrSamplerState::Filter filter, SkBlendMode mode, const SkPMColor4f& color,
199                      const SkRect& srcRect, const SkRect& dstRect, GrAA aa, GrQuadAAFlags edgeAA,
200                      SkCanvas::SrcRectConstraint constraint, const SkMatrix& viewMatrix,
201                      sk_sp<GrColorSpaceXform> texXform) {
202         const SkRect* domain = constraint == SkCanvas::kStrict_SrcRectConstraint ?
203                 &srcRect : nullptr;
204         this->drawTexturedQuad(clip, std::move(proxy), srcColorType, std::move(texXform), filter,
205                                color, mode, aa, edgeAA, GrQuad::MakeFromRect(dstRect, viewMatrix),
206                                GrQuad(srcRect), domain);
207     }
208 
209     /**
210      * Variant of drawTexture that instead draws the texture applied to 'dstQuad' transformed by
211      * 'viewMatrix', using the 'srcQuad' texture coordinates clamped to the optional 'domain'. If
212      * 'domain' is null, it's equivalent to using the fast src rect constraint. If 'domain' is
213      * provided, the strict src rect constraint is applied using 'domain'.
214      */
drawTextureQuad(const GrClip & clip,sk_sp<GrTextureProxy> proxy,GrColorType srcColorType,GrSamplerState::Filter filter,SkBlendMode mode,const SkPMColor4f & color,const SkPoint srcQuad[4],const SkPoint dstQuad[4],GrAA aa,GrQuadAAFlags edgeAA,const SkRect * domain,const SkMatrix & viewMatrix,sk_sp<GrColorSpaceXform> texXform)215     void drawTextureQuad(const GrClip& clip, sk_sp<GrTextureProxy> proxy, GrColorType srcColorType,
216                          GrSamplerState::Filter filter, SkBlendMode mode, const SkPMColor4f& color,
217                          const SkPoint srcQuad[4], const SkPoint dstQuad[4], GrAA aa,
218                          GrQuadAAFlags edgeAA, const SkRect* domain, const SkMatrix& viewMatrix,
219                          sk_sp<GrColorSpaceXform> texXform) {
220         this->drawTexturedQuad(clip, std::move(proxy), srcColorType, std::move(texXform), filter,
221                                color, mode, aa, edgeAA, GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
222                                GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), domain);
223     }
224 
225     /** Used with drawTextureSet */
226     struct TextureSetEntry {
227         sk_sp<GrTextureProxy> fProxy;
228         GrColorType fSrcColorType;
229         SkRect fSrcRect;
230         SkRect fDstRect;
231         const SkPoint* fDstClipQuad; // Must be null, or point to an array of 4 points
232         const SkMatrix* fPreViewMatrix; // If not null, entry's CTM is 'viewMatrix' * fPreViewMatrix
233         float fAlpha;
234         GrQuadAAFlags fAAFlags;
235     };
236     /**
237      * Draws a set of textures with a shared filter, color, view matrix, color xform, and
238      * texture color xform. The textures must all have the same GrTextureType and GrConfig.
239      *
240      * If any entries provide a non-null fDstClip array, it will be read from immediately based on
241      * fDstClipCount, so the pointer can become invalid after this returns.
242      */
243     void drawTextureSet(const GrClip&, const TextureSetEntry[], int cnt, GrSamplerState::Filter,
244                         SkBlendMode mode, GrAA aa, SkCanvas::SrcRectConstraint,
245                         const SkMatrix& viewMatrix, sk_sp<GrColorSpaceXform> texXform);
246 
247     /**
248      * Draw a roundrect using a paint.
249      *
250      * @param paint       describes how to color pixels.
251      * @param GrAA        Controls whether rrect is antialiased.
252      * @param viewMatrix  transformation matrix
253      * @param rrect       the roundrect to draw
254      * @param style       style to apply to the rrect. Currently path effects are not allowed.
255      */
256     void drawRRect(const GrClip&,
257                    GrPaint&&,
258                    GrAA,
259                    const SkMatrix& viewMatrix,
260                    const SkRRect& rrect,
261                    const GrStyle& style);
262 
263     /**
264      * Use a fast method to render the ambient and spot shadows for a path.
265      * Will return false if not possible for the given path.
266      *
267      * @param viewMatrix   transformation matrix
268      * @param path         the path to shadow
269      * @param rec          parameters for shadow rendering
270      */
271     bool drawFastShadow(const GrClip&,
272                         const SkMatrix& viewMatrix,
273                         const SkPath& path,
274                         const SkDrawShadowRec& rec);
275 
276     /**
277      * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
278      * undefined if outer does not contain inner.
279      *
280      * @param paint        describes how to color pixels.
281      * @param GrAA         Controls whether rrects edges are antialiased
282      * @param viewMatrix   transformation matrix
283      * @param outer        the outer roundrect
284      * @param inner        the inner roundrect
285      */
286     void drawDRRect(const GrClip&,
287                     GrPaint&&,
288                     GrAA,
289                     const SkMatrix& viewMatrix,
290                     const SkRRect& outer,
291                     const SkRRect& inner);
292 
293     /**
294      * Draws a path.
295      *
296      * @param paint         describes how to color pixels.
297      * @param GrAA          Controls whether the path is antialiased.
298      * @param viewMatrix    transformation matrix
299      * @param path          the path to draw
300      * @param style         style to apply to the path.
301      */
302     void drawPath(const GrClip&,
303                   GrPaint&&,
304                   GrAA,
305                   const SkMatrix& viewMatrix,
306                   const SkPath&,
307                   const GrStyle&);
308 
309     /**
310      * Draws a shape.
311      *
312      * @param paint         describes how to color pixels.
313      * @param GrAA          Controls whether the path is antialiased.
314      * @param viewMatrix    transformation matrix
315      * @param shape         the shape to draw
316      */
317     void drawShape(const GrClip&,
318                    GrPaint&&,
319                    GrAA,
320                    const SkMatrix& viewMatrix,
321                    const GrShape&);
322 
323 
324     /**
325      * Draws vertices with a paint.
326      *
327      * @param   paint            describes how to color pixels.
328      * @param   viewMatrix       transformation matrix
329      * @param   vertices         specifies the mesh to draw.
330      * @param   bones            bone deformation matrices.
331      * @param   boneCount        number of bone matrices.
332      * @param   overridePrimType primitive type to draw. If NULL, derive prim type from vertices.
333      */
334     void drawVertices(const GrClip&,
335                       GrPaint&& paint,
336                       const SkMatrix& viewMatrix,
337                       sk_sp<SkVertices> vertices,
338                       const SkVertices::Bone bones[],
339                       int boneCount,
340                       GrPrimitiveType* overridePrimType = nullptr);
341 
342     /**
343      * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
344      * sprite rectangle edges.
345      *
346      * @param   paint           describes how to color pixels.
347      * @param   viewMatrix      transformation matrix
348      * @param   spriteCount     number of sprites.
349      * @param   xform           array of compressed transformation data, required.
350      * @param   texRect         array of texture rectangles used to access the paint.
351      * @param   colors          optional array of per-sprite colors, supercedes
352      *                          the paint's color field.
353      */
354     void drawAtlas(const GrClip&,
355                    GrPaint&& paint,
356                    const SkMatrix& viewMatrix,
357                    int spriteCount,
358                    const SkRSXform xform[],
359                    const SkRect texRect[],
360                    const SkColor colors[]);
361 
362     /**
363      * Draws a region.
364      *
365      * @param paint         describes how to color pixels
366      * @param viewMatrix    transformation matrix
367      * @param aa            should the rects of the region be antialiased.
368      * @param region        the region to be drawn
369      * @param style         style to apply to the region
370      */
371     void drawRegion(const GrClip&,
372                     GrPaint&& paint,
373                     GrAA aa,
374                     const SkMatrix& viewMatrix,
375                     const SkRegion& region,
376                     const GrStyle& style,
377                     const GrUserStencilSettings* ss = nullptr);
378 
379     /**
380      * Draws an oval.
381      *
382      * @param paint         describes how to color pixels.
383      * @param GrAA          Controls whether the oval is antialiased.
384      * @param viewMatrix    transformation matrix
385      * @param oval          the bounding rect of the oval.
386      * @param style         style to apply to the oval. Currently path effects are not allowed.
387      */
388     void drawOval(const GrClip&,
389                   GrPaint&& paint,
390                   GrAA,
391                   const SkMatrix& viewMatrix,
392                   const SkRect& oval,
393                   const GrStyle& style);
394     /**
395      * Draws a partial arc of an oval.
396      *
397      * @param paint         describes how to color pixels.
398      * @param GrGrAA        Controls whether the arc is antialiased.
399      * @param viewMatrix    transformation matrix.
400      * @param oval          the bounding rect of the oval.
401      * @param startAngle    starting angle in degrees.
402      * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
403      * @param useCenter     true means that the implied path begins at the oval center, connects as
404      *                      a line to the point indicated by the start contains the arc indicated by
405      *                      the sweep angle. If false the line beginning at the center point is
406      *                      omitted.
407      * @param style         style to apply to the oval.
408      */
409     void drawArc(const GrClip&,
410                  GrPaint&& paint,
411                  GrAA,
412                  const SkMatrix& viewMatrix,
413                  const SkRect& oval,
414                  SkScalar startAngle,
415                  SkScalar sweepAngle,
416                  bool useCenter,
417                  const GrStyle& style);
418 
419     /**
420      * Draw the image as a set of rects, specified by |iter|.
421      */
422     void drawImageLattice(const GrClip&,
423                           GrPaint&&,
424                           const SkMatrix& viewMatrix,
425                           sk_sp<GrTextureProxy>,
426                           GrColorType srcColorType,
427                           sk_sp<GrColorSpaceXform>,
428                           GrSamplerState::Filter,
429                           std::unique_ptr<SkLatticeIter>,
430                           const SkRect& dst);
431 
432     /**
433      * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height
434      * of the srcRect. The srcRect and dstRect are clipped to the bounds of the src and dst surfaces
435      * respectively.
436      */
437     bool blitTexture(GrTextureProxy* src, GrColorType srcColorType, const SkIRect& srcRect,
438                      const SkIPoint& dstPoint);
439 
440     /**
441      * Adds the necessary signal and wait semaphores and adds the passed in SkDrawable to the
442      * command stream.
443      */
444     void drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>, const SkRect& bounds);
445 
446     using ReadPixelsCallback = SkSurface::ReadPixelsCallback;
447     using ReadPixelsContext = SkSurface::ReadPixelsContext;
448     using RescaleGamma = SkSurface::RescaleGamma;
449 
450     // GPU implementation for SkSurface::asyncRescaleAndReadPixels.
451     void asyncRescaleAndReadPixels(const SkImageInfo& info, const SkIRect& srcRect,
452                                    RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
453                                    ReadPixelsCallback callback, ReadPixelsContext context);
454     // GPU implementation for SkSurface::asyncRescaleAndReadPixelsYUV420.
455     void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
456                                          sk_sp<SkColorSpace> dstColorSpace,
457                                          const SkIRect& srcRect,
458                                          const SkISize& dstSize,
459                                          RescaleGamma rescaleGamma,
460                                          SkFilterQuality rescaleQuality,
461                                          ReadPixelsCallback callback,
462                                          ReadPixelsContext context);
463 
464     /**
465      * After this returns any pending surface IO will be issued to the backend 3D API and
466      * if the surface has MSAA it will be resolved.
467      */
468     GrSemaphoresSubmitted flush(SkSurface::BackendSurfaceAccess access, const GrFlushInfo&);
469 
470     /**
471      *  The next time this GrRenderTargetContext is flushed, the gpu will wait on the passed in
472      *  semaphores before executing any commands.
473      */
474     bool waitOnSemaphores(int numSemaphores, const GrBackendSemaphore waitSemaphores[]);
475 
476     void insertEventMarker(const SkString&);
477 
proxy()478     const GrRenderTargetProxy* proxy() const { return fRenderTargetProxy.get(); }
width()479     int width() const { return fRenderTargetProxy->width(); }
height()480     int height() const { return fRenderTargetProxy->height(); }
numSamples()481     int numSamples() const { return fRenderTargetProxy->numSamples(); }
surfaceProps()482     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
origin()483     GrSurfaceOrigin origin() const { return fRenderTargetProxy->origin(); }
wrapsVkSecondaryCB()484     bool wrapsVkSecondaryCB() const { return fRenderTargetProxy->wrapsVkSecondaryCB(); }
485     GrMipMapped mipMapped() const;
486 
487     // This entry point should only be called if the backing GPU object is known to be
488     // instantiated.
accessRenderTarget()489     GrRenderTarget* accessRenderTarget() { return fRenderTargetProxy->peekRenderTarget(); }
490 
asSurfaceProxy()491     GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); }
asSurfaceProxy()492     const GrSurfaceProxy* asSurfaceProxy() const override { return fRenderTargetProxy.get(); }
asSurfaceProxyRef()493     sk_sp<GrSurfaceProxy> asSurfaceProxyRef() override { return fRenderTargetProxy; }
494 
495     GrTextureProxy* asTextureProxy() override;
496     const GrTextureProxy* asTextureProxy() const override;
497     sk_sp<GrTextureProxy> asTextureProxyRef() override;
498 
asRenderTargetProxy()499     GrRenderTargetProxy* asRenderTargetProxy() override { return fRenderTargetProxy.get(); }
asRenderTargetProxyRef()500     sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() override { return fRenderTargetProxy; }
501 
asRenderTargetContext()502     GrRenderTargetContext* asRenderTargetContext() override { return this; }
503 
504     // Provides access to functions that aren't part of the public API.
505     GrRenderTargetContextPriv priv();
506     const GrRenderTargetContextPriv priv() const;
507 
textTarget()508     GrTextTarget* textTarget() { return fTextTarget.get(); }
509 
510 #if GR_TEST_UTILS
testingOnly_IsInstantiated()511     bool testingOnly_IsInstantiated() const { return fRenderTargetProxy->isInstantiated(); }
testingOnly_SetPreserveOpsOnFullClear()512     void testingOnly_SetPreserveOpsOnFullClear() { fPreserveOpsOnFullClear_TestingOnly = true; }
testingOnly_PeekLastOpsTask()513     GrOpsTask* testingOnly_PeekLastOpsTask() { return fOpsTask.get(); }
514 #endif
515 
516 protected:
517     GrRenderTargetContext(GrRecordingContext*, sk_sp<GrRenderTargetProxy>, GrColorType,
518                           sk_sp<SkColorSpace>, const SkSurfaceProps*, bool managedOpsTask = true);
519 
520     SkDEBUGCODE(void validate() const override;)
521 
522 private:
523     class TextTarget;
524     enum class QuadOptimization;
525 
526     GrAAType chooseAAType(GrAA);
527 
528     friend class GrAtlasTextBlob;               // for access to add[Mesh]DrawOp
529     friend class GrClipStackClip;               // for access to getOpsTask
530     friend class GrOnFlushResourceProvider;     // for access to getOpsTask (http://skbug.com/9357)
531 
532     friend class GrDrawingManager; // for ctor
533     friend class GrRenderTargetContextPriv;
534 
535     // All the path renderers currently make their own ops
536     friend class GrSoftwarePathRenderer;             // for access to add[Mesh]DrawOp
537     friend class GrAAConvexPathRenderer;             // for access to add[Mesh]DrawOp
538     friend class GrDashLinePathRenderer;             // for access to add[Mesh]DrawOp
539     friend class GrAAHairLinePathRenderer;           // for access to add[Mesh]DrawOp
540     friend class GrAALinearizingConvexPathRenderer;  // for access to add[Mesh]DrawOp
541     friend class GrSmallPathRenderer;                // for access to add[Mesh]DrawOp
542     friend class GrDefaultPathRenderer;              // for access to add[Mesh]DrawOp
543     friend class GrStencilAndCoverPathRenderer;      // for access to add[Mesh]DrawOp
544     friend class GrTessellatingPathRenderer;         // for access to add[Mesh]DrawOp
545     friend class GrCCPerFlushResources;              // for access to addDrawOp
546     friend class GrCoverageCountingPathRenderer;     // for access to addDrawOp
547     // for a unit test
548     friend void test_draw_op(GrContext*,
549                              GrRenderTargetContext*,
550                              std::unique_ptr<GrFragmentProcessor>,
551                              sk_sp<GrTextureProxy>,
552                              GrColorType);
553 
554     GrOpsTask::CanDiscardPreviousOps canDiscardPreviousOpsOnFullClear() const;
555     void setNeedsStencil(bool useMixedSamplesIfNotMSAA);
556 
557     void internalClear(const GrFixedClip&, const SkPMColor4f&, CanClearFullscreen);
558     void internalStencilClear(const GrFixedClip&, bool insideStencilMask);
559 
560     // Only consumes the GrPaint if successful.
561     bool drawFilledDRRect(const GrClip& clip,
562                           GrPaint&& paint,
563                           GrAA,
564                           const SkMatrix& viewMatrix,
565                           const SkRRect& origOuter,
566                           const SkRRect& origInner);
567 
568     // If the drawn quad's paint is a const blended color, provide it as a non-null pointer to
569     // 'constColor', which enables the draw-as-clear optimization. Otherwise it is assumed the paint
570     // requires some form of shading that invalidates using a clear op.
571     //
572     // The non-const pointers should be the original draw request on input, and will be updated as
573     // appropriate depending on the returned optimization level.
574     //
575     // 'stencilSettings' are provided merely for decision making purposes; When non-null,
576     // optimization strategies that submit special ops are avoided.
577     QuadOptimization attemptQuadOptimization(const GrClip& clip,
578                                              const SkPMColor4f* constColor,
579                                              const GrUserStencilSettings* stencilSettings,
580                                              GrAA* aa,
581                                              GrQuadAAFlags* edgeFlags,
582                                              GrQuad* deviceQuad,
583                                              GrQuad* localQuad);
584 
585     // If stencil settings, 'ss', are non-null, AA controls MSAA or no AA. If they are null, then AA
586     // can choose between coverage, MSAA as per chooseAAType(). This will always attempt to apply
587     // quad optimizations, so all quad/rect public APIs should rely on this function for consistent
588     // clipping behavior.
589     void drawFilledQuad(const GrClip& clip,
590                         GrPaint&& paint,
591                         GrAA aa,
592                         GrQuadAAFlags edgeFlags,
593                         const GrQuad& deviceQuad,
594                         const GrQuad& localQuad,
595                         const GrUserStencilSettings* ss = nullptr);
596 
597     // Like drawFilledQuad but does not require using a GrPaint or FP for texturing
598     void drawTexturedQuad(const GrClip& clip,
599                           sk_sp<GrTextureProxy> proxy,
600                           GrColorType srcColorType,
601                           sk_sp<GrColorSpaceXform> textureXform,
602                           GrSamplerState::Filter filter,
603                           const SkPMColor4f& color,
604                           SkBlendMode blendMode,
605                           GrAA aa,
606                           GrQuadAAFlags edgeFlags,
607                           const GrQuad& deviceQuad,
608                           const GrQuad& localQuad,
609                           const SkRect* domain = nullptr);
610 
611     void drawShapeUsingPathRenderer(const GrClip&, GrPaint&&, GrAA, const SkMatrix&,
612                                     const GrShape&);
613 
614     void addOp(std::unique_ptr<GrOp>);
615 
616     // Allows caller of addDrawOp to know which op list an op will be added to.
617     using WillAddOpFn = void(GrOp*, uint32_t opsTaskID);
618     // These perform processing specific to GrDrawOp-derived ops before recording them into an
619     // op list. Before adding the op to an op list the WillAddOpFn is called. Note that it
620     // will not be called in the event that the op is discarded. Moreover, the op may merge into
621     // another op after the function is called (either before addDrawOp returns or some time later).
622     void addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>,
623                    const std::function<WillAddOpFn>& = std::function<WillAddOpFn>());
624 
625     // Makes a copy of the proxy if it is necessary for the draw and places the texture that should
626     // be used by GrXferProcessor to access the destination color in 'result'. If the return
627     // value is false then a texture copy could not be made.
628     bool SK_WARN_UNUSED_RESULT setupDstProxy(const GrClip&, const GrOp& op,
629                                              GrXferProcessor::DstProxy* result);
630 
631     class AsyncReadResult;
632 
633     // The async read step of asyncRescaleAndReadPixels()
634     void asyncReadPixels(const SkIRect& rect, SkColorType colorType, ReadPixelsCallback callback,
635                          ReadPixelsContext context);
636 
637     GrOpsTask* getOpsTask();
638 
639     std::unique_ptr<GrTextTarget> fTextTarget;
640     sk_sp<GrRenderTargetProxy> fRenderTargetProxy;
641 
642     // In MDB-mode the GrOpsTask can be closed by some other renderTargetContext that has picked
643     // it up. For this reason, the GrOpsTask should only ever be accessed via 'getOpsTask'.
644     sk_sp<GrOpsTask> fOpsTask;
645 
646     SkSurfaceProps fSurfaceProps;
647     bool fManagedOpsTask;
648 
649     int fNumStencilSamples = 0;
650 #if GR_TEST_UTILS
651     bool fPreserveOpsOnFullClear_TestingOnly = false;
652 #endif
653 
654     typedef GrSurfaceContext INHERITED;
655 };
656 
657 #endif
658