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 GrDrawContext_DEFINED
9#define GrDrawContext_DEFINED
10
11#include "GrColor.h"
12#include "GrRenderTarget.h"
13#include "SkRefCnt.h"
14#include "SkSurfaceProps.h"
15#include "../private/GrSingleOwner.h"
16
17class GrAtlasTextContext;
18class GrAuditTrail;
19class GrClip;
20class GrContext;
21class GrDrawBatch;
22class GrDrawPathBatchBase;
23class GrDrawingManager;
24class GrDrawTarget;
25class GrPaint;
26class GrPathProcessor;
27class GrPipelineBuilder;
28class GrRenderTarget;
29class GrStrokeInfo;
30class GrSurface;
31class SkDrawFilter;
32struct SkIPoint;
33struct SkIRect;
34class SkMatrix;
35class SkPaint;
36class SkPath;
37struct SkPoint;
38struct SkRect;
39class SkRRect;
40struct SkRSXform;
41class SkTextBlob;
42
43/*
44 * A helper object to orchestrate draws
45 */
46class SK_API GrDrawContext : public SkRefCnt {
47public:
48    ~GrDrawContext() override;
49
50    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
51
52    // TODO: it is odd that we need both the SkPaint in the following 3 methods.
53    // We should extract the text parameters from SkPaint and pass them separately
54    // akin to GrStrokeInfo (GrTextInfo?)
55    virtual void drawText(const GrClip&,  const GrPaint&, const SkPaint&,
56                          const SkMatrix& viewMatrix, const char text[], size_t byteLength,
57                          SkScalar x, SkScalar y, const SkIRect& clipBounds);
58    virtual void drawPosText(const GrClip&, const GrPaint&, const SkPaint&,
59                             const SkMatrix& viewMatrix, const char text[], size_t byteLength,
60                             const SkScalar pos[], int scalarsPerPosition,
61                             const SkPoint& offset, const SkIRect& clipBounds);
62    virtual void drawTextBlob(const GrClip&, const SkPaint&,
63                              const SkMatrix& viewMatrix, const SkTextBlob*,
64                              SkScalar x, SkScalar y,
65                              SkDrawFilter*, const SkIRect& clipBounds);
66
67    /**
68     * Provides a perfomance hint that the render target's contents are allowed
69     * to become undefined.
70     */
71    void discard();
72
73    /**
74     * Clear the entire or rect of the render target, ignoring any clips.
75     * @param rect  the rect to clear or the whole thing if rect is NULL.
76     * @param color the color to clear to.
77     * @param canIgnoreRect allows partial clears to be converted to whole
78     *                      clears on platforms for which that is cheap
79     */
80    void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect);
81
82    /**
83     *  Draw everywhere (respecting the clip) with the paint.
84     */
85    void drawPaint(const GrClip&, const GrPaint&, const SkMatrix& viewMatrix);
86
87    /**
88     *  Draw the rect using a paint.
89     *  @param paint        describes how to color pixels.
90     *  @param viewMatrix   transformation matrix
91     *  @param strokeInfo   the stroke information (width, join, cap), and.
92     *                      the dash information (intervals, count, phase).
93     *                      If strokeInfo == NULL, then the rect is filled.
94     *                      Otherwise, if stroke width == 0, then the stroke
95     *                      is always a single pixel thick, else the rect is
96     *                      mitered/beveled stroked based on stroke width.
97     *  The rects coords are used to access the paint (through texture matrix)
98     */
99    void drawRect(const GrClip&,
100                  const GrPaint& paint,
101                  const SkMatrix& viewMatrix,
102                  const SkRect&,
103                  const GrStrokeInfo* strokeInfo = NULL);
104
105    /**
106     * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
107     *
108     * @param paint         describes how to color pixels.
109     * @param viewMatrix    transformation matrix which applies to rectToDraw
110     * @param rectToDraw    the rectangle to draw
111     * @param localRect     the rectangle of shader coordinates applied to rectToDraw
112     */
113    void fillRectToRect(const GrClip&,
114                        const GrPaint& paint,
115                        const SkMatrix& viewMatrix,
116                        const SkRect& rectToDraw,
117                        const SkRect& localRect);
118
119    /**
120     * Fills a rect with a paint and a localMatrix.
121     */
122    void fillRectWithLocalMatrix(const GrClip& clip,
123                                 const GrPaint& paint,
124                                 const SkMatrix& viewMatrix,
125                                 const SkRect& rect,
126                                 const SkMatrix& localMatrix);
127
128    /**
129     *  Draw a roundrect using a paint.
130     *
131     *  @param paint        describes how to color pixels.
132     *  @param viewMatrix   transformation matrix
133     *  @param rrect        the roundrect to draw
134     *  @param strokeInfo   the stroke information (width, join, cap) and
135     *                      the dash information (intervals, count, phase).
136     */
137    void drawRRect(const GrClip&,
138                   const GrPaint&,
139                   const SkMatrix& viewMatrix,
140                   const SkRRect& rrect,
141                   const GrStrokeInfo&);
142
143    /**
144     * Draws a path.
145     *
146     * @param paint         describes how to color pixels.
147     * @param viewMatrix    transformation matrix
148     * @param path          the path to draw
149     * @param strokeInfo    the stroke information (width, join, cap) and
150     *                      the dash information (intervals, count, phase).
151     */
152    void drawPath(const GrClip&,
153                  const GrPaint&,
154                  const SkMatrix& viewMatrix,
155                  const SkPath&,
156                  const GrStrokeInfo&);
157
158    /**
159     * Draws vertices with a paint.
160     *
161     * @param   paint           describes how to color pixels.
162     * @param   viewMatrix      transformation matrix
163     * @param   primitiveType   primitives type to draw.
164     * @param   vertexCount     number of vertices.
165     * @param   positions       array of vertex positions, required.
166     * @param   texCoords       optional array of texture coordinates used
167     *                          to access the paint.
168     * @param   colors          optional array of per-vertex colors, supercedes
169     *                          the paint's color field.
170     * @param   indices         optional array of indices. If NULL vertices
171     *                          are drawn non-indexed.
172     * @param   indexCount      if indices is non-null then this is the
173     *                          number of indices.
174     */
175    void drawVertices(const GrClip&,
176                      const GrPaint& paint,
177                      const SkMatrix& viewMatrix,
178                      GrPrimitiveType primitiveType,
179                      int vertexCount,
180                      const SkPoint positions[],
181                      const SkPoint texs[],
182                      const GrColor colors[],
183                      const uint16_t indices[],
184                      int indexCount);
185
186    /**
187     * Draws textured sprites from an atlas with a paint.
188     *
189     * @param   paint           describes how to color pixels.
190     * @param   viewMatrix      transformation matrix
191     * @param   spriteCount     number of sprites.
192     * @param   xform           array of compressed transformation data, required.
193     * @param   texRect         array of texture rectangles used to access the paint.
194     * @param   colors          optional array of per-sprite colors, supercedes
195     *                          the paint's color field.
196     */
197    void drawAtlas(const GrClip&,
198                   const GrPaint& paint,
199                   const SkMatrix& viewMatrix,
200                   int spriteCount,
201                   const SkRSXform xform[],
202                   const SkRect texRect[],
203                   const SkColor colors[]);
204
205    /**
206     * Draws an oval.
207     *
208     * @param paint         describes how to color pixels.
209     * @param viewMatrix    transformation matrix
210     * @param oval          the bounding rect of the oval.
211     * @param strokeInfo    the stroke information (width, join, cap) and
212     *                      the dash information (intervals, count, phase).
213     */
214    void drawOval(const GrClip&,
215                  const GrPaint& paint,
216                  const SkMatrix& viewMatrix,
217                  const SkRect& oval,
218                  const GrStrokeInfo& strokeInfo);
219
220    /**
221     *  Draw the image stretched differentially to fit into dst.
222     *  center is a rect within the image, and logically divides the image
223     *  into 9 sections (3x3). For example, if the middle pixel of a [5x5]
224     *  image is the "center", then the center-rect should be [2, 2, 3, 3].
225     *
226     *  If the dst is >= the image size, then...
227     *  - The 4 corners are not stretched at all.
228     *  - The sides are stretched in only one axis.
229     *  - The center is stretched in both axes.
230     * Else, for each axis where dst < image,
231     *  - The corners shrink proportionally
232     *  - The sides (along the shrink axis) and center are not drawn
233     */
234    void drawImageNine(const GrClip&,
235                       const GrPaint& paint,
236                       const SkMatrix& viewMatrix,
237                       int imageWidth,
238                       int imageHeight,
239                       const SkIRect& center,
240                       const SkRect& dst);
241
242    /**
243     * Draws a batch
244     *
245     * @param paint    describes how to color pixels.
246     * @param batch    the batch to draw
247     */
248    void drawBatch(const GrClip&, const GrPaint&, GrDrawBatch*);
249
250    /**
251     * Draws a path batch. This needs to be separate from drawBatch because we install path stencil
252     * settings late.
253     *
254     * TODO: Figure out a better model that allows us to roll this method into drawBatch.
255     */
256    void drawPathBatch(const GrPipelineBuilder&, GrDrawPathBatchBase*);
257
258    int width() const { return fRenderTarget->width(); }
259    int height() const { return fRenderTarget->height(); }
260    int numColorSamples() const { return fRenderTarget->numColorSamples(); }
261
262    GrRenderTarget* accessRenderTarget() { return fRenderTarget; }
263
264    ///////////////////////////////////////////////////////////////////////////////////////////////
265    // Functions intended for internal use only.
266    void internal_drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch);
267
268protected:
269    GrDrawContext(GrContext*, GrDrawingManager*, GrRenderTarget*,
270                  const SkSurfaceProps* surfaceProps, GrAuditTrail*, GrSingleOwner*);
271
272    GrDrawingManager* drawingManager() { return fDrawingManager; }
273    GrAuditTrail* auditTrail() { return fAuditTrail; }
274    const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
275
276    SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
277    SkDEBUGCODE(void validate() const;)
278
279private:
280    friend class GrAtlasTextBlob; // for access to drawBatch
281    friend class GrDrawingManager; // for ctor
282
283    void internalDrawPath(GrPipelineBuilder*,
284                          const SkMatrix& viewMatrix,
285                          GrColor,
286                          bool useAA,
287                          const SkPath&,
288                          const GrStrokeInfo&);
289
290    // This entry point allows the GrTextContext-derived classes to add their batches to
291    // the drawTarget.
292    void drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* batch);
293
294    GrDrawTarget* getDrawTarget();
295
296    GrDrawingManager*                 fDrawingManager;
297    GrRenderTarget*                   fRenderTarget;
298
299    // In MDB-mode the drawTarget can be closed by some other drawContext that has picked
300    // it up. For this reason, the drawTarget should only ever be accessed via 'getDrawTarget'.
301    GrDrawTarget*                     fDrawTarget;
302    SkAutoTDelete<GrAtlasTextContext> fAtlasTextContext;
303    GrContext*                        fContext;
304
305    SkSurfaceProps                    fSurfaceProps;
306    GrAuditTrail*                     fAuditTrail;
307
308    // In debug builds we guard against improper thread handling
309    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
310};
311
312#endif
313