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 "GrColor.h"
12 #include "GrContext.h"
13 #include "GrPaint.h"
14 #include "GrSurfaceContext.h"
15 #include "GrXferProcessor.h"
16 #include "SkRefCnt.h"
17 #include "SkSurfaceProps.h"
18 #include "../private/GrInstancedPipelineInfo.h"
19 #include "../private/GrRenderTargetProxy.h"
20 
21 class GrClip;
22 class GrDrawingManager;
23 class GrDrawOp;
24 class GrFixedClip;
25 class GrMeshDrawOp;
26 class GrPipelineBuilder;
27 class GrRenderTarget;
28 class GrRenderTargetContextPriv;
29 class GrRenderTargetOpList;
30 class GrStyle;
31 class GrSurface;
32 class GrTextureProxy;
33 struct GrUserStencilSettings;
34 class SkDrawFilter;
35 struct SkIPoint;
36 struct SkIRect;
37 class SkLatticeIter;
38 class SkMatrix;
39 class SkPaint;
40 class SkPath;
41 struct SkPoint;
42 struct SkRect;
43 class SkRegion;
44 class SkRRect;
45 struct SkRSXform;
46 class SkTextBlob;
47 class SkVertices;
48 
49 /**
50  * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
51  */
52 class SK_API GrRenderTargetContext : public GrSurfaceContext {
53 public:
54     ~GrRenderTargetContext() override;
55 
resourceProvider()56     GrResourceProvider* resourceProvider() { return fContext->resourceProvider(); }
57 
58     // We use SkPaint rather than GrPaint here for two reasons:
59     //    * The SkPaint carries extra text settings. If these were extracted to a lighter object
60     //      we could use GrPaint except that
61     //    * SkPaint->GrPaint conversion depends upon whether the glyphs are color or grayscale and
62     //      this can vary within a text run.
63     virtual void drawText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
64                           const char text[], size_t byteLength, SkScalar x, SkScalar y,
65                           const SkIRect& clipBounds);
66     virtual void drawPosText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
67                              const char text[], size_t byteLength, const SkScalar pos[],
68                              int scalarsPerPosition, const SkPoint& offset,
69                              const SkIRect& clipBounds);
70     virtual void drawTextBlob(const GrClip&, const SkPaint&,
71                               const SkMatrix& viewMatrix, const SkTextBlob*,
72                               SkScalar x, SkScalar y,
73                               SkDrawFilter*, const SkIRect& clipBounds);
74 
75     /**
76      * Provides a perfomance hint that the render target's contents are allowed
77      * to become undefined.
78      */
79     void discard();
80 
81     /**
82      * Clear the entire or rect of the render target, ignoring any clips.
83      * @param rect  the rect to clear or the whole thing if rect is NULL.
84      * @param color the color to clear to.
85      * @param canIgnoreRect allows partial clears to be converted to whole
86      *                      clears on platforms for which that is cheap
87      */
88     void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect);
89 
90     /**
91      *  Draw everywhere (respecting the clip) with the paint.
92      */
93     void drawPaint(const GrClip&, GrPaint&&, const SkMatrix& viewMatrix);
94 
95     /**
96      * Draw the rect using a paint.
97      * @param paint        describes how to color pixels.
98      * @param GrAA         Controls whether rect is antialiased
99      * @param viewMatrix   transformation matrix
100      * @param style        The style to apply. Null means fill. Currently path effects are not
101      *                     allowed.
102      * The rects coords are used to access the paint (through texture matrix)
103      */
104     void drawRect(const GrClip&,
105                   GrPaint&& paint,
106                   GrAA,
107                   const SkMatrix& viewMatrix,
108                   const SkRect&,
109                   const GrStyle* style = nullptr);
110 
111     /**
112      * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
113      *
114      * @param paint        describes how to color pixels.
115      * @param GrAA         Controls whether rect is antialiased
116      * @param viewMatrix   transformation matrix which applies to rectToDraw
117      * @param rectToDraw   the rectangle to draw
118      * @param localRect    the rectangle of shader coordinates applied to rectToDraw
119      */
120     void fillRectToRect(const GrClip&,
121                         GrPaint&& paint,
122                         GrAA,
123                         const SkMatrix& viewMatrix,
124                         const SkRect& rectToDraw,
125                         const SkRect& localRect);
126 
127     /**
128      * Fills a rect with a paint and a localMatrix.
129      */
130     void fillRectWithLocalMatrix(const GrClip& clip,
131                                  GrPaint&& paint,
132                                  GrAA,
133                                  const SkMatrix& viewMatrix,
134                                  const SkRect& rect,
135                                  const SkMatrix& localMatrix);
136 
137     /**
138      * Draw a roundrect using a paint.
139      *
140      * @param paint       describes how to color pixels.
141      * @param GrAA        Controls whether rrect is antialiased.
142      * @param viewMatrix  transformation matrix
143      * @param rrect       the roundrect to draw
144      * @param style       style to apply to the rrect. Currently path effects are not allowed.
145      */
146     void drawRRect(const GrClip&,
147                    GrPaint&&,
148                    GrAA,
149                    const SkMatrix& viewMatrix,
150                    const SkRRect& rrect,
151                    const GrStyle& style);
152 
153     /**
154      * Draw a roundrect using a paint and a shadow shader. This is separate from drawRRect
155      * because it uses different underlying geometry and GeometryProcessor
156      *
157      * @param paint        describes how to color pixels.
158      * @param viewMatrix   transformation matrix
159      * @param rrect        the roundrect to draw
160      * @param blurRadius   amount of shadow blur to apply (in device space)
161      * @param style        style to apply to the rrect. Currently path effects are not allowed.
162      */
163     void drawShadowRRect(const GrClip&,
164                          GrPaint&&,
165                          const SkMatrix& viewMatrix,
166                          const SkRRect& rrect,
167                          SkScalar blurRadius,
168                          const GrStyle& style);
169 
170     /**
171      * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
172      * undefined if outer does not contain inner.
173      *
174      * @param paint        describes how to color pixels.
175      * @param GrAA         Controls whether rrects edges are antialiased
176      * @param viewMatrix   transformation matrix
177      * @param outer        the outer roundrect
178      * @param inner        the inner roundrect
179      */
180     void drawDRRect(const GrClip&,
181                     GrPaint&&,
182                     GrAA,
183                     const SkMatrix& viewMatrix,
184                     const SkRRect& outer,
185                     const SkRRect& inner);
186 
187     /**
188      * Draws a path.
189      *
190      * @param paint         describes how to color pixels.
191      * @param GrAA          Controls whether the path is antialiased.
192      * @param viewMatrix    transformation matrix
193      * @param path          the path to draw
194      * @param style         style to apply to the path.
195      */
196     void drawPath(const GrClip&,
197                   GrPaint&&,
198                   GrAA,
199                   const SkMatrix& viewMatrix,
200                   const SkPath&,
201                   const GrStyle& style);
202 
203     enum class ColorArrayType {
204         kPremulGrColor,
205         kSkColor,
206     };
207     /**
208      * Draws vertices with a paint.
209      *
210      * @param   paint           describes how to color pixels.
211      * @param   viewMatrix      transformation matrix
212      * @param   primitiveType   primitives type to draw.
213      * @param   vertexCount     number of vertices.
214      * @param   positions       array of vertex positions, required.
215      * @param   texCoords       optional array of texture coordinates used
216      *                          to access the paint.
217      * @param   colors          optional array of per-vertex colors, supercedes
218      *                          the paint's color field.
219      * @param   indices         optional array of indices. If NULL vertices
220      *                          are drawn non-indexed.
221      * @param   indexCount      if indices is non-null then this is the
222      *                          number of indices.
223      * @param   ColorArrayType  Determines how the color array should be interpreted.
224      */
225     void drawVertices(const GrClip&,
226                       GrPaint&& paint,
227                       const SkMatrix& viewMatrix,
228                       GrPrimitiveType primitiveType,
229                       int vertexCount,
230                       const SkPoint positions[],
231                       const SkPoint texs[],
232                       const uint32_t colors[],
233                       const uint16_t indices[],
234                       int indexCount,
235                       ColorArrayType = ColorArrayType::kPremulGrColor);
236 
237     /**
238      * Draws vertices with a paint.
239      *
240      * @param   paint           describes how to color pixels.
241      * @param   viewMatrix      transformation matrix
242      * @param   veritces        specifies the mesh to draw.
243      * @param   flags           A bitfield of options specified by SkCanvas::VerticesFlags.
244      */
245     void drawVertices(const GrClip&,
246                       GrPaint&& paint,
247                       const SkMatrix& viewMatrix,
248                       sk_sp<SkVertices> vertices);
249 
250     /**
251      * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
252      * sprite rectangle edges.
253      *
254      * @param   paint           describes how to color pixels.
255      * @param   viewMatrix      transformation matrix
256      * @param   spriteCount     number of sprites.
257      * @param   xform           array of compressed transformation data, required.
258      * @param   texRect         array of texture rectangles used to access the paint.
259      * @param   colors          optional array of per-sprite colors, supercedes
260      *                          the paint's color field.
261      */
262     void drawAtlas(const GrClip&,
263                    GrPaint&& paint,
264                    const SkMatrix& viewMatrix,
265                    int spriteCount,
266                    const SkRSXform xform[],
267                    const SkRect texRect[],
268                    const SkColor colors[]);
269 
270     /**
271      * Draws a region.
272      *
273      * @param paint         describes how to color pixels
274      * @param viewMatrix    transformation matrix
275      * @param aa            should the rects of the region be antialiased.
276      * @param region        the region to be drawn
277      * @param style         style to apply to the region
278      */
279     void drawRegion(const GrClip&,
280                     GrPaint&& paint,
281                     GrAA aa,
282                     const SkMatrix& viewMatrix,
283                     const SkRegion& region,
284                     const GrStyle& style);
285 
286     /**
287      * Draws an oval.
288      *
289      * @param paint         describes how to color pixels.
290      * @param GrAA          Controls whether the oval is antialiased.
291      * @param viewMatrix    transformation matrix
292      * @param oval          the bounding rect of the oval.
293      * @param style         style to apply to the oval. Currently path effects are not allowed.
294      */
295     void drawOval(const GrClip&,
296                   GrPaint&& paint,
297                   GrAA,
298                   const SkMatrix& viewMatrix,
299                   const SkRect& oval,
300                   const GrStyle& style);
301     /**
302      * Draws a partial arc of an oval.
303      *
304      * @param paint         describes how to color pixels.
305      * @param GrGrAA        Controls whether the arc is antialiased.
306      * @param viewMatrix    transformation matrix.
307      * @param oval          the bounding rect of the oval.
308      * @param startAngle    starting angle in degrees.
309      * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
310      * @param useCenter     true means that the implied path begins at the oval center, connects as
311      *                      a line to the point indicated by the start contains the arc indicated by
312      *                      the sweep angle. If false the line beginning at the center point is
313      *                      omitted.
314      * @param style         style to apply to the oval.
315      */
316     void drawArc(const GrClip&,
317                  GrPaint&& paint,
318                  GrAA,
319                  const SkMatrix& viewMatrix,
320                  const SkRect& oval,
321                  SkScalar startAngle,
322                  SkScalar sweepAngle,
323                  bool useCenter,
324                  const GrStyle& style);
325 
326     /**
327      * Draw the image as a set of rects, specified by |iter|.
328      */
329     void drawImageLattice(const GrClip&,
330                           GrPaint&& paint,
331                           const SkMatrix& viewMatrix,
332                           int imageWidth,
333                           int imageHeight,
334                           std::unique_ptr<SkLatticeIter> iter,
335                           const SkRect& dst);
336 
337     /**
338      * After this returns any pending surface IO will be issued to the backend 3D API and
339      * if the surface has MSAA it will be resolved.
340      */
341     void prepareForExternalIO();
342 
isStencilBufferMultisampled()343     bool isStencilBufferMultisampled() const {
344         return fRenderTargetProxy->isStencilBufferMultisampled();
345     }
isUnifiedMultisampled()346     bool isUnifiedMultisampled() const { return fRenderTargetProxy->isUnifiedMultisampled(); }
hasMixedSamples()347     bool hasMixedSamples() const { return fRenderTargetProxy->isMixedSampled(); }
348 
caps()349     const GrCaps* caps() const { return fContext->caps(); }
desc()350     const GrSurfaceDesc& desc() const { return fRenderTargetProxy->desc(); }
width()351     int width() const { return fRenderTargetProxy->width(); }
height()352     int height() const { return fRenderTargetProxy->height(); }
config()353     GrPixelConfig config() const { return fRenderTargetProxy->config(); }
numColorSamples()354     int numColorSamples() const { return fRenderTargetProxy->numColorSamples(); }
surfaceProps()355     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
getColorXformFromSRGB()356     GrColorSpaceXform* getColorXformFromSRGB() const { return fColorXformFromSRGB.get(); }
origin()357     GrSurfaceOrigin origin() const { return fRenderTargetProxy->origin(); }
358 
359     bool wasAbandoned() const;
360 
361     GrRenderTarget* instantiate();
362 
accessRenderTarget()363     GrRenderTarget* accessRenderTarget() {
364         // TODO: usage of this entry point needs to be reduced and potentially eliminated
365         // since it ends the deferral of the GrRenderTarget's allocation
366         return fRenderTargetProxy->instantiate(fContext->resourceProvider());
367     }
368 
asSurfaceProxy()369     GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); }
asSurfaceProxy()370     const GrSurfaceProxy* asSurfaceProxy() const override { return fRenderTargetProxy.get(); }
asSurfaceProxyRef()371     sk_sp<GrSurfaceProxy> asSurfaceProxyRef() override { return fRenderTargetProxy; }
372 
373     GrTextureProxy* asTextureProxy() override;
374     sk_sp<GrTextureProxy> asTextureProxyRef() override;
375 
asRenderTargetProxy()376     GrRenderTargetProxy* asRenderTargetProxy() override { return fRenderTargetProxy.get(); }
asRenderTargetProxyRef()377     sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() override { return fRenderTargetProxy; }
378 
asRenderTargetContext()379     GrRenderTargetContext* asRenderTargetContext() override { return this; }
380 
asTexture()381     sk_sp<GrTexture> asTexture() {
382         if (!this->accessRenderTarget()) {
383             return nullptr;
384         }
385 
386         // TODO: usage of this entry point needs to be reduced and potentially eliminated
387         // since it ends the deferral of the GrRenderTarget's allocation
388         // It's usage should migrate to asTextureProxyRef
389         return sk_ref_sp(this->accessRenderTarget()->asTexture());
390     }
391 
392     // Provides access to functions that aren't part of the public API.
393     GrRenderTargetContextPriv priv();
394     const GrRenderTargetContextPriv priv() const;
395 
396     bool isWrapped_ForTesting() const;
397 
398 protected:
399     GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTargetProxy>,
400                           sk_sp<SkColorSpace>, const SkSurfaceProps*, GrAuditTrail*,
401                           GrSingleOwner*);
402 
SkDEBUGCODE(void validate ()const;)403     SkDEBUGCODE(void validate() const;)
404 
405 private:
406     inline GrAAType decideAAType(GrAA aa, bool allowMixedSamples = false) {
407         if (GrAA::kNo == aa) {
408             return GrAAType::kNone;
409         }
410         if (this->isUnifiedMultisampled()) {
411             return GrAAType::kMSAA;
412         }
413         if (allowMixedSamples && this->isStencilBufferMultisampled()) {
414             return GrAAType::kMixedSamples;
415         }
416         return GrAAType::kCoverage;
417     }
418 
419     friend class GrAtlasTextBlob;               // for access to add[Mesh]DrawOp
420     friend class GrStencilAndCoverTextContext;  // for access to add[Mesh]DrawOp
421 
422     friend class GrDrawingManager; // for ctor
423     friend class GrRenderTargetContextPriv;
424     friend class GrSWMaskHelper;  // for access to add[Mesh]DrawOp
425 
426     // All the path renderers currently make their own ops
427     friend class GrSoftwarePathRenderer;             // for access to add[Mesh]DrawOp
428     friend class GrAAConvexPathRenderer;             // for access to add[Mesh]DrawOp
429     friend class GrDashLinePathRenderer;             // for access to add[Mesh]DrawOp
430     friend class GrAAHairLinePathRenderer;           // for access to add[Mesh]DrawOp
431     friend class GrAALinearizingConvexPathRenderer;  // for access to add[Mesh]DrawOp
432     friend class GrSmallPathRenderer;                // for access to add[Mesh]DrawOp
433     friend class GrDefaultPathRenderer;              // for access to add[Mesh]DrawOp
434     friend class GrMSAAPathRenderer;                 // for access to add[Mesh]DrawOp
435     friend class GrStencilAndCoverPathRenderer;      // for access to add[Mesh]DrawOp
436     friend class GrTessellatingPathRenderer;         // for access to add[Mesh]DrawOp
437     // for a unit test
438     friend void test_draw_op(GrRenderTargetContext*,
439                              sk_sp<GrFragmentProcessor>, sk_sp<GrTextureProxy>);
440 
441     void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
442 
443     // Only consumes the GrPaint if successful.
444     bool drawFilledDRRect(const GrClip& clip,
445                           GrPaint&& paint,
446                           GrAA,
447                           const SkMatrix& viewMatrix,
448                           const SkRRect& origOuter,
449                           const SkRRect& origInner);
450 
451     // Only consumes the GrPaint if successful.
452     bool drawFilledRect(const GrClip& clip,
453                         GrPaint&& paint,
454                         GrAA,
455                         const SkMatrix& viewMatrix,
456                         const SkRect& rect,
457                         const GrUserStencilSettings* ss);
458 
459     void drawNonAAFilledRect(const GrClip&,
460                              GrPaint&&,
461                              const SkMatrix& viewMatrix,
462                              const SkRect& rect,
463                              const SkRect* localRect,
464                              const SkMatrix* localMatrix,
465                              const GrUserStencilSettings* ss,
466                              GrAAType hwOrNoneAAType);
467 
468     void internalDrawPath(
469             const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&);
470 
471     bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
472     bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
473                       size_t dstRowBytes, int x, int y, uint32_t flags) override;
474     bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
475                        size_t srcRowBytes, int x, int y, uint32_t flags) override;
476 
477     // These perform processing specific to Gr[Mesh]DrawOp-derived ops before recording them into
478     // the op list. They return the id of the opList to which the op was added, or 0, if it was
479     // dropped (e.g., due to clipping).
480     uint32_t addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>);
481     uint32_t addMeshDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrMeshDrawOp>);
482 
483     // Makes a copy of the dst if it is necessary for the draw and returns the texture that should
484     // be used by GrXferProcessor to access the destination color. If the texture is nullptr then
485     // a texture copy could not be made.
486     void setupDstTexture(GrRenderTarget*, const GrClip&, const SkRect& opBounds,
487                          GrXferProcessor::DstTexture*);
488 
489 
490     GrRenderTargetOpList* getOpList();
491 
492     sk_sp<GrRenderTargetProxy>        fRenderTargetProxy;
493 
494     // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
495     // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
496     GrRenderTargetOpList*             fOpList;
497     GrInstancedPipelineInfo           fInstancedPipelineInfo;
498 
499     sk_sp<GrColorSpaceXform>          fColorXformFromSRGB;
500     SkSurfaceProps                    fSurfaceProps;
501 
502     typedef GrSurfaceContext INHERITED;
503 };
504 
505 #endif
506