GrRenderTargetContext.h revision 2bf4b3a97b770811d9e0558dbbfbdb57cfafbdb7
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
21class GrClip;
22class GrDrawingManager;
23class GrDrawOp;
24class GrFixedClip;
25class GrMeshDrawOp;
26class GrPipelineBuilder;
27class GrRenderTarget;
28class GrRenderTargetContextPriv;
29class GrRenderTargetOpList;
30class GrStyle;
31class GrSurface;
32class GrTextureProxy;
33struct GrUserStencilSettings;
34class SkDrawFilter;
35struct SkIPoint;
36struct SkIRect;
37class SkLatticeIter;
38class SkMatrix;
39class SkPaint;
40class SkPath;
41struct SkPoint;
42struct SkRect;
43class SkRegion;
44class SkRRect;
45struct SkRSXform;
46class SkTextBlob;
47class SkVertices;
48
49/**
50 * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
51 */
52class SK_API GrRenderTargetContext : public GrSurfaceContext {
53public:
54    ~GrRenderTargetContext() override;
55
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                      uint32_t flags);
250
251    /**
252     * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
253     * sprite rectangle edges.
254     *
255     * @param   paint           describes how to color pixels.
256     * @param   viewMatrix      transformation matrix
257     * @param   spriteCount     number of sprites.
258     * @param   xform           array of compressed transformation data, required.
259     * @param   texRect         array of texture rectangles used to access the paint.
260     * @param   colors          optional array of per-sprite colors, supercedes
261     *                          the paint's color field.
262     */
263    void drawAtlas(const GrClip&,
264                   GrPaint&& paint,
265                   const SkMatrix& viewMatrix,
266                   int spriteCount,
267                   const SkRSXform xform[],
268                   const SkRect texRect[],
269                   const SkColor colors[]);
270
271    /**
272     * Draws a region.
273     *
274     * @param paint         describes how to color pixels
275     * @param viewMatrix    transformation matrix
276     * @param aa            should the rects of the region be antialiased.
277     * @param region        the region to be drawn
278     * @param style         style to apply to the region
279     */
280    void drawRegion(const GrClip&,
281                    GrPaint&& paint,
282                    GrAA aa,
283                    const SkMatrix& viewMatrix,
284                    const SkRegion& region,
285                    const GrStyle& style);
286
287    /**
288     * Draws an oval.
289     *
290     * @param paint         describes how to color pixels.
291     * @param GrAA          Controls whether the oval is antialiased.
292     * @param viewMatrix    transformation matrix
293     * @param oval          the bounding rect of the oval.
294     * @param style         style to apply to the oval. Currently path effects are not allowed.
295     */
296    void drawOval(const GrClip&,
297                  GrPaint&& paint,
298                  GrAA,
299                  const SkMatrix& viewMatrix,
300                  const SkRect& oval,
301                  const GrStyle& style);
302    /**
303     * Draws a partial arc of an oval.
304     *
305     * @param paint         describes how to color pixels.
306     * @param GrGrAA        Controls whether the arc is antialiased.
307     * @param viewMatrix    transformation matrix.
308     * @param oval          the bounding rect of the oval.
309     * @param startAngle    starting angle in degrees.
310     * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
311     * @param useCenter     true means that the implied path begins at the oval center, connects as
312     *                      a line to the point indicated by the start contains the arc indicated by
313     *                      the sweep angle. If false the line beginning at the center point is
314     *                      omitted.
315     * @param style         style to apply to the oval.
316     */
317    void drawArc(const GrClip&,
318                 GrPaint&& paint,
319                 GrAA,
320                 const SkMatrix& viewMatrix,
321                 const SkRect& oval,
322                 SkScalar startAngle,
323                 SkScalar sweepAngle,
324                 bool useCenter,
325                 const GrStyle& style);
326
327    /**
328     * Draw the image as a set of rects, specified by |iter|.
329     */
330    void drawImageLattice(const GrClip&,
331                          GrPaint&& paint,
332                          const SkMatrix& viewMatrix,
333                          int imageWidth,
334                          int imageHeight,
335                          std::unique_ptr<SkLatticeIter> iter,
336                          const SkRect& dst);
337
338    /**
339     * After this returns any pending surface IO will be issued to the backend 3D API and
340     * if the surface has MSAA it will be resolved.
341     */
342    void prepareForExternalIO();
343
344    bool isStencilBufferMultisampled() const {
345        return fRenderTargetProxy->isStencilBufferMultisampled();
346    }
347    bool isUnifiedMultisampled() const { return fRenderTargetProxy->isUnifiedMultisampled(); }
348    bool hasMixedSamples() const { return fRenderTargetProxy->isMixedSampled(); }
349
350    const GrCaps* caps() const { return fContext->caps(); }
351    const GrSurfaceDesc& desc() const { return fRenderTargetProxy->desc(); }
352    int width() const { return fRenderTargetProxy->width(); }
353    int height() const { return fRenderTargetProxy->height(); }
354    GrPixelConfig config() const { return fRenderTargetProxy->config(); }
355    int numColorSamples() const { return fRenderTargetProxy->numColorSamples(); }
356    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
357    GrColorSpaceXform* getColorXformFromSRGB() const { return fColorXformFromSRGB.get(); }
358    GrSurfaceOrigin origin() const { return fRenderTargetProxy->origin(); }
359
360    bool wasAbandoned() const;
361
362    GrRenderTarget* instantiate();
363
364    GrRenderTarget* accessRenderTarget() {
365        // TODO: usage of this entry point needs to be reduced and potentially eliminated
366        // since it ends the deferral of the GrRenderTarget's allocation
367        return fRenderTargetProxy->instantiate(fContext->resourceProvider());
368    }
369
370    GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); }
371    const GrSurfaceProxy* asSurfaceProxy() const override { return fRenderTargetProxy.get(); }
372    sk_sp<GrSurfaceProxy> asSurfaceProxyRef() override { return fRenderTargetProxy; }
373
374    GrTextureProxy* asTextureProxy() override;
375    sk_sp<GrTextureProxy> asTextureProxyRef() override;
376
377    GrRenderTargetProxy* asRenderTargetProxy() override { return fRenderTargetProxy.get(); }
378    sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() override { return fRenderTargetProxy; }
379
380    GrRenderTargetContext* asRenderTargetContext() override { return this; }
381
382    sk_sp<GrTexture> asTexture() {
383        if (!this->accessRenderTarget()) {
384            return nullptr;
385        }
386
387        // TODO: usage of this entry point needs to be reduced and potentially eliminated
388        // since it ends the deferral of the GrRenderTarget's allocation
389        // It's usage should migrate to asTextureProxyRef
390        return sk_ref_sp(this->accessRenderTarget()->asTexture());
391    }
392
393    // Provides access to functions that aren't part of the public API.
394    GrRenderTargetContextPriv priv();
395    const GrRenderTargetContextPriv priv() const;
396
397    bool isWrapped_ForTesting() const;
398
399protected:
400    GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTargetProxy>,
401                          sk_sp<SkColorSpace>, const SkSurfaceProps*, GrAuditTrail*,
402                          GrSingleOwner*);
403
404    SkDEBUGCODE(void validate() const;)
405
406private:
407    inline GrAAType decideAAType(GrAA aa, bool allowMixedSamples = false) {
408        if (GrAA::kNo == aa) {
409            return GrAAType::kNone;
410        }
411        if (this->isUnifiedMultisampled()) {
412            return GrAAType::kMSAA;
413        }
414        if (allowMixedSamples && this->isStencilBufferMultisampled()) {
415            return GrAAType::kMixedSamples;
416        }
417        return GrAAType::kCoverage;
418    }
419
420    friend class GrAtlasTextBlob;               // for access to add[Mesh]DrawOp
421    friend class GrStencilAndCoverTextContext;  // for access to add[Mesh]DrawOp
422
423    friend class GrDrawingManager; // for ctor
424    friend class GrRenderTargetContextPriv;
425    friend class GrSWMaskHelper;  // for access to add[Mesh]DrawOp
426
427    // All the path renderers currently make their own ops
428    friend class GrSoftwarePathRenderer;             // for access to add[Mesh]DrawOp
429    friend class GrAAConvexPathRenderer;             // for access to add[Mesh]DrawOp
430    friend class GrDashLinePathRenderer;             // for access to add[Mesh]DrawOp
431    friend class GrAAHairLinePathRenderer;           // for access to add[Mesh]DrawOp
432    friend class GrAALinearizingConvexPathRenderer;  // for access to add[Mesh]DrawOp
433    friend class GrSmallPathRenderer;                // for access to add[Mesh]DrawOp
434    friend class GrDefaultPathRenderer;              // for access to add[Mesh]DrawOp
435    friend class GrMSAAPathRenderer;                 // for access to add[Mesh]DrawOp
436    friend class GrStencilAndCoverPathRenderer;      // for access to add[Mesh]DrawOp
437    friend class GrTessellatingPathRenderer;         // for access to add[Mesh]DrawOp
438    // for a unit test
439    friend void test_draw_op(GrRenderTargetContext*,
440                             sk_sp<GrFragmentProcessor>, sk_sp<GrTextureProxy>);
441
442    void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
443
444    // Only consumes the GrPaint if successful.
445    bool drawFilledDRRect(const GrClip& clip,
446                          GrPaint&& paint,
447                          GrAA,
448                          const SkMatrix& viewMatrix,
449                          const SkRRect& origOuter,
450                          const SkRRect& origInner);
451
452    // Only consumes the GrPaint if successful.
453    bool drawFilledRect(const GrClip& clip,
454                        GrPaint&& paint,
455                        GrAA,
456                        const SkMatrix& viewMatrix,
457                        const SkRect& rect,
458                        const GrUserStencilSettings* ss);
459
460    void drawNonAAFilledRect(const GrClip&,
461                             GrPaint&&,
462                             const SkMatrix& viewMatrix,
463                             const SkRect& rect,
464                             const SkRect* localRect,
465                             const SkMatrix* localMatrix,
466                             const GrUserStencilSettings* ss,
467                             GrAAType hwOrNoneAAType);
468
469    void internalDrawPath(
470            const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&);
471
472    bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
473    bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
474                      size_t dstRowBytes, int x, int y, uint32_t flags) override;
475    bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
476                       size_t srcRowBytes, int x, int y, uint32_t flags) override;
477
478    // These perform processing specific to Gr[Mesh]DrawOp-derived ops before recording them into
479    // the op list. They return the id of the opList to which the op was added, or 0, if it was
480    // dropped (e.g., due to clipping).
481    uint32_t addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>);
482    uint32_t addMeshDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrMeshDrawOp>);
483
484    // Makes a copy of the dst if it is necessary for the draw and returns the texture that should
485    // be used by GrXferProcessor to access the destination color. If the texture is nullptr then
486    // a texture copy could not be made.
487    void setupDstTexture(GrRenderTarget*, const GrClip&, const SkRect& opBounds,
488                         GrXferProcessor::DstTexture*);
489
490
491    GrRenderTargetOpList* getOpList();
492
493    sk_sp<GrRenderTargetProxy>        fRenderTargetProxy;
494
495    // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
496    // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
497    GrRenderTargetOpList*             fOpList;
498    GrInstancedPipelineInfo           fInstancedPipelineInfo;
499
500    sk_sp<GrColorSpaceXform>          fColorXformFromSRGB;
501    SkSurfaceProps                    fSurfaceProps;
502
503    typedef GrSurfaceContext INHERITED;
504};
505
506#endif
507