GrRenderTargetContext.h revision d7cda9a6f050c30e65b0744b3cfb45cecdc40834
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 GrLegacyMeshDrawOp;
26class GrPipelineBuilder;
27class GrRenderTarget;
28class GrRenderTargetContextPriv;
29class GrRenderTargetOpList;
30class GrStyle;
31class GrTextureProxy;
32struct GrUserStencilSettings;
33class SkDrawFilter;
34struct SkIPoint;
35struct SkIRect;
36class SkLatticeIter;
37class SkMatrix;
38class SkPaint;
39class SkPath;
40struct SkPoint;
41struct SkRect;
42class SkRegion;
43class SkRRect;
44struct SkRSXform;
45class SkTextBlob;
46class SkVertices;
47
48/**
49 * A helper object to orchestrate commands (draws, etc...) for GrSurfaces that are GrRenderTargets.
50 */
51class SK_API GrRenderTargetContext : public GrSurfaceContext {
52public:
53    ~GrRenderTargetContext() override;
54
55    // MDB TODO: This access is mainly provided for the image filters. Remove it when they
56    // no longer need to pass it to the FragmentProcessor ctors.
57    GrResourceProvider* resourceProvider() { return fContext->resourceProvider(); }
58
59    // We use SkPaint rather than GrPaint here for two reasons:
60    //    * The SkPaint carries extra text settings. If these were extracted to a lighter object
61    //      we could use GrPaint except that
62    //    * SkPaint->GrPaint conversion depends upon whether the glyphs are color or grayscale and
63    //      this can vary within a text run.
64    virtual void drawText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
65                          const char text[], size_t byteLength, SkScalar x, SkScalar y,
66                          const SkIRect& clipBounds);
67    virtual void drawPosText(const GrClip&, const SkPaint&, const SkMatrix& viewMatrix,
68                             const char text[], size_t byteLength, const SkScalar pos[],
69                             int scalarsPerPosition, const SkPoint& offset,
70                             const SkIRect& clipBounds);
71    virtual void drawTextBlob(const GrClip&, const SkPaint&,
72                              const SkMatrix& viewMatrix, const SkTextBlob*,
73                              SkScalar x, SkScalar y,
74                              SkDrawFilter*, const SkIRect& clipBounds);
75
76    /**
77     * Provides a perfomance hint that the render target's contents are allowed
78     * to become undefined.
79     */
80    void discard();
81
82    /**
83     * Clear the entire or rect of the render target, ignoring any clips.
84     * @param rect  the rect to clear or the whole thing if rect is NULL.
85     * @param color the color to clear to.
86     * @param canIgnoreRect allows partial clears to be converted to whole
87     *                      clears on platforms for which that is cheap
88     */
89    void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect);
90
91    /**
92     *  Draw everywhere (respecting the clip) with the paint.
93     */
94    void drawPaint(const GrClip&, GrPaint&&, const SkMatrix& viewMatrix);
95
96    /**
97     * Draw the rect using a paint.
98     * @param paint        describes how to color pixels.
99     * @param GrAA         Controls whether rect is antialiased
100     * @param viewMatrix   transformation matrix
101     * @param style        The style to apply. Null means fill. Currently path effects are not
102     *                     allowed.
103     * The rects coords are used to access the paint (through texture matrix)
104     */
105    void drawRect(const GrClip&,
106                  GrPaint&& paint,
107                  GrAA,
108                  const SkMatrix& viewMatrix,
109                  const SkRect&,
110                  const GrStyle* style = nullptr);
111
112    /**
113     * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
114     *
115     * @param paint        describes how to color pixels.
116     * @param GrAA         Controls whether rect is antialiased
117     * @param viewMatrix   transformation matrix which applies to rectToDraw
118     * @param rectToDraw   the rectangle to draw
119     * @param localRect    the rectangle of shader coordinates applied to rectToDraw
120     */
121    void fillRectToRect(const GrClip&,
122                        GrPaint&& paint,
123                        GrAA,
124                        const SkMatrix& viewMatrix,
125                        const SkRect& rectToDraw,
126                        const SkRect& localRect);
127
128    /**
129     * Fills a rect with a paint and a localMatrix.
130     */
131    void fillRectWithLocalMatrix(const GrClip& clip,
132                                 GrPaint&& paint,
133                                 GrAA,
134                                 const SkMatrix& viewMatrix,
135                                 const SkRect& rect,
136                                 const SkMatrix& localMatrix);
137
138    /**
139     * Draw a roundrect using a paint.
140     *
141     * @param paint       describes how to color pixels.
142     * @param GrAA        Controls whether rrect is antialiased.
143     * @param viewMatrix  transformation matrix
144     * @param rrect       the roundrect to draw
145     * @param style       style to apply to the rrect. Currently path effects are not allowed.
146     */
147    void drawRRect(const GrClip&,
148                   GrPaint&&,
149                   GrAA,
150                   const SkMatrix& viewMatrix,
151                   const SkRRect& rrect,
152                   const GrStyle& style);
153
154    /**
155     * Draw a roundrect using a paint and a shadow shader. This is separate from drawRRect
156     * because it uses different underlying geometry and GeometryProcessor
157     *
158     * @param paint        describes how to color pixels.
159     * @param viewMatrix   transformation matrix
160     * @param rrect        the roundrect to draw
161     * @param blurRadius   amount of shadow blur to apply (in device space)
162     * @param style        style to apply to the rrect. Currently path effects are not allowed.
163     */
164    void drawShadowRRect(const GrClip&,
165                         GrPaint&&,
166                         const SkMatrix& viewMatrix,
167                         const SkRRect& rrect,
168                         SkScalar blurRadius,
169                         const GrStyle& style);
170
171    /**
172     * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
173     * undefined if outer does not contain inner.
174     *
175     * @param paint        describes how to color pixels.
176     * @param GrAA         Controls whether rrects edges are antialiased
177     * @param viewMatrix   transformation matrix
178     * @param outer        the outer roundrect
179     * @param inner        the inner roundrect
180     */
181    void drawDRRect(const GrClip&,
182                    GrPaint&&,
183                    GrAA,
184                    const SkMatrix& viewMatrix,
185                    const SkRRect& outer,
186                    const SkRRect& inner);
187
188    /**
189     * Draws a path.
190     *
191     * @param paint         describes how to color pixels.
192     * @param GrAA          Controls whether the path is antialiased.
193     * @param viewMatrix    transformation matrix
194     * @param path          the path to draw
195     * @param style         style to apply to the path.
196     */
197    void drawPath(const GrClip&,
198                  GrPaint&&,
199                  GrAA,
200                  const SkMatrix& viewMatrix,
201                  const SkPath&,
202                  const GrStyle& style);
203
204    enum class ColorArrayType {
205        kPremulGrColor,
206        kSkColor,
207    };
208    /**
209     * Draws vertices with a paint.
210     *
211     * @param   paint           describes how to color pixels.
212     * @param   viewMatrix      transformation matrix
213     * @param   primitiveType   primitives type to draw.
214     * @param   vertexCount     number of vertices.
215     * @param   positions       array of vertex positions, required.
216     * @param   texCoords       optional array of texture coordinates used
217     *                          to access the paint.
218     * @param   colors          optional array of per-vertex colors, supercedes
219     *                          the paint's color field.
220     * @param   indices         optional array of indices. If NULL vertices
221     *                          are drawn non-indexed.
222     * @param   indexCount      if indices is non-null then this is the
223     *                          number of indices.
224     * @param   ColorArrayType  Determines how the color array should be interpreted.
225     */
226    void drawVertices(const GrClip&,
227                      GrPaint&& paint,
228                      const SkMatrix& viewMatrix,
229                      GrPrimitiveType primitiveType,
230                      int vertexCount,
231                      const SkPoint positions[],
232                      const SkPoint texs[],
233                      const uint32_t colors[],
234                      const uint16_t indices[],
235                      int indexCount,
236                      ColorArrayType = ColorArrayType::kPremulGrColor);
237
238    /**
239     * Draws vertices with a paint.
240     *
241     * @param   paint           describes how to color pixels.
242     * @param   viewMatrix      transformation matrix
243     * @param   veritces        specifies the mesh to draw.
244     * @param   flags           A bitfield of options specified by SkCanvas::VerticesFlags.
245     */
246    void drawVertices(const GrClip&,
247                      GrPaint&& paint,
248                      const SkMatrix& viewMatrix,
249                      sk_sp<SkVertices> vertices);
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* accessRenderTarget() {
363        // TODO: usage of this entry point needs to be reduced and potentially eliminated
364        // since it ends the deferral of the GrRenderTarget's allocation
365        return fRenderTargetProxy->instantiate(fContext->resourceProvider());
366    }
367
368    GrSurfaceProxy* asSurfaceProxy() override { return fRenderTargetProxy.get(); }
369    const GrSurfaceProxy* asSurfaceProxy() const override { return fRenderTargetProxy.get(); }
370    sk_sp<GrSurfaceProxy> asSurfaceProxyRef() override { return fRenderTargetProxy; }
371
372    GrTextureProxy* asTextureProxy() override;
373    sk_sp<GrTextureProxy> asTextureProxyRef() override;
374
375    GrRenderTargetProxy* asRenderTargetProxy() override { return fRenderTargetProxy.get(); }
376    sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() override { return fRenderTargetProxy; }
377
378    GrRenderTargetContext* asRenderTargetContext() override { return this; }
379
380    // Provides access to functions that aren't part of the public API.
381    GrRenderTargetContextPriv priv();
382    const GrRenderTargetContextPriv priv() const;
383
384    bool isWrapped_ForTesting() const;
385
386protected:
387    GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTargetProxy>,
388                          sk_sp<SkColorSpace>, const SkSurfaceProps*, GrAuditTrail*,
389                          GrSingleOwner*);
390
391    SkDEBUGCODE(void validate() const;)
392
393private:
394    inline GrAAType decideAAType(GrAA aa, bool allowMixedSamples = false) {
395        if (GrAA::kNo == aa) {
396            return GrAAType::kNone;
397        }
398        if (this->isUnifiedMultisampled()) {
399            return GrAAType::kMSAA;
400        }
401        if (allowMixedSamples && this->isStencilBufferMultisampled()) {
402            return GrAAType::kMixedSamples;
403        }
404        return GrAAType::kCoverage;
405    }
406
407    friend class GrAtlasTextBlob;               // for access to add[Mesh]DrawOp
408    friend class GrStencilAndCoverTextContext;  // for access to add[Mesh]DrawOp
409
410    friend class GrDrawingManager; // for ctor
411    friend class GrRenderTargetContextPriv;
412    friend class GrSWMaskHelper;  // for access to add[Mesh]DrawOp
413
414    // All the path renderers currently make their own ops
415    friend class GrSoftwarePathRenderer;             // for access to add[Mesh]DrawOp
416    friend class GrAAConvexPathRenderer;             // for access to add[Mesh]DrawOp
417    friend class GrDashLinePathRenderer;             // for access to add[Mesh]DrawOp
418    friend class GrAAHairLinePathRenderer;           // for access to add[Mesh]DrawOp
419    friend class GrAALinearizingConvexPathRenderer;  // for access to add[Mesh]DrawOp
420    friend class GrSmallPathRenderer;                // for access to add[Mesh]DrawOp
421    friend class GrDefaultPathRenderer;              // for access to add[Mesh]DrawOp
422    friend class GrMSAAPathRenderer;                 // for access to add[Mesh]DrawOp
423    friend class GrStencilAndCoverPathRenderer;      // for access to add[Mesh]DrawOp
424    friend class GrTessellatingPathRenderer;         // for access to add[Mesh]DrawOp
425    // for a unit test
426    friend void test_draw_op(GrRenderTargetContext*,
427                             sk_sp<GrFragmentProcessor>, sk_sp<GrTextureProxy>);
428
429    void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
430
431    // Only consumes the GrPaint if successful.
432    bool drawFilledDRRect(const GrClip& clip,
433                          GrPaint&& paint,
434                          GrAA,
435                          const SkMatrix& viewMatrix,
436                          const SkRRect& origOuter,
437                          const SkRRect& origInner);
438
439    // Only consumes the GrPaint if successful.
440    bool drawFilledRect(const GrClip& clip,
441                        GrPaint&& paint,
442                        GrAA,
443                        const SkMatrix& viewMatrix,
444                        const SkRect& rect,
445                        const GrUserStencilSettings* ss);
446
447    void drawNonAAFilledRect(const GrClip&,
448                             GrPaint&&,
449                             const SkMatrix& viewMatrix,
450                             const SkRect& rect,
451                             const SkRect* localRect,
452                             const SkMatrix* localMatrix,
453                             const GrUserStencilSettings* ss,
454                             GrAAType hwOrNoneAAType);
455
456    void internalDrawPath(
457            const GrClip&, GrPaint&&, GrAA, const SkMatrix&, const SkPath&, const GrStyle&);
458
459    bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
460    bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
461                      size_t dstRowBytes, int x, int y, uint32_t flags) override;
462    bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
463                       size_t srcRowBytes, int x, int y, uint32_t flags) override;
464
465    // These perform processing specific to Gr[Mesh]DrawOp-derived ops before recording them into
466    // the op list. They return the id of the opList to which the op was added, or 0, if it was
467    // dropped (e.g., due to clipping).
468    uint32_t addDrawOp(const GrClip&, std::unique_ptr<GrDrawOp>);
469    uint32_t addLegacyMeshDrawOp(GrPipelineBuilder&&, const GrClip&,
470                                 std::unique_ptr<GrLegacyMeshDrawOp>);
471
472    // Makes a copy of the proxy if it is necessary for the draw and places the texture that should
473    // be used by GrXferProcessor to access the destination color in 'result'. If the return
474    // value is false then a texture copy could not be made.
475    bool SK_WARN_UNUSED_RESULT setupDstTexture(GrRenderTargetProxy*,
476                                               const GrClip&,
477                                               const SkRect& opBounds,
478                                               GrXferProcessor::DstTexture* result);
479
480    GrRenderTargetOpList* getOpList();
481
482    sk_sp<GrRenderTargetProxy>        fRenderTargetProxy;
483
484    // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
485    // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
486    GrRenderTargetOpList*             fOpList;
487    GrInstancedPipelineInfo           fInstancedPipelineInfo;
488
489    sk_sp<GrColorSpaceXform>          fColorXformFromSRGB;
490    SkSurfaceProps                    fSurfaceProps;
491
492    typedef GrSurfaceContext INHERITED;
493};
494
495#endif
496