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