• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010 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 GrDrawTarget_DEFINED
9 #define GrDrawTarget_DEFINED
10 
11 #include "GrClip.h"
12 #include "GrClipMaskManager.h"
13 #include "GrContext.h"
14 #include "GrPathProcessor.h"
15 #include "GrPrimitiveProcessor.h"
16 #include "GrIndexBuffer.h"
17 #include "GrPathRendering.h"
18 #include "GrPipelineBuilder.h"
19 #include "GrTraceMarker.h"
20 #include "GrVertexBuffer.h"
21 
22 #include "SkClipStack.h"
23 #include "SkMatrix.h"
24 #include "SkPath.h"
25 #include "SkStrokeRec.h"
26 #include "SkTArray.h"
27 #include "SkTLazy.h"
28 #include "SkTypes.h"
29 #include "SkXfermode.h"
30 
31 class GrClip;
32 class GrDrawTargetCaps;
33 class GrPath;
34 class GrPathRange;
35 class GrPipeline;
36 
37 class GrDrawTarget : public SkRefCnt {
38 public:
39     SK_DECLARE_INST_COUNT(GrDrawTarget)
40 
41     typedef GrPathRange::PathIndexType PathIndexType;
42     typedef GrPathRendering::PathTransformType PathTransformType;
43 
44     ///////////////////////////////////////////////////////////////////////////
45 
46     // The context may not be fully constructed and should not be used during GrDrawTarget
47     // construction.
48     GrDrawTarget(GrContext* context);
49 
~GrDrawTarget()50     virtual ~GrDrawTarget() {}
51 
52     /**
53      * Empties the draw buffer of any queued up draws.
54      */
reset()55     void reset() { this->onReset(); }
56 
57     /**
58      * This plays any queued up draws to its GrGpu target. It also resets this object (i.e. flushing
59      * is destructive).
60      */
61     void flush();
62 
63     /**
64      * Gets the capabilities of the draw target.
65      */
caps()66     const GrDrawTargetCaps* caps() const { return fCaps.get(); }
67 
68     void drawBatch(GrPipelineBuilder*, GrBatch*);
69 
70     /**
71      * Draws path into the stencil buffer. The fill must be either even/odd or
72      * winding (not inverse or hairline). It will respect the HW antialias flag
73      * on the GrPipelineBuilder (if possible in the 3D API).  Note, we will never have an inverse
74      * fill with stencil path
75      */
76     void stencilPath(GrPipelineBuilder*, const GrPathProcessor*, const GrPath*,
77                      GrPathRendering::FillType);
78 
79     /**
80      * Draws a path. Fill must not be a hairline. It will respect the HW
81      * antialias flag on the GrPipelineBuilder (if possible in the 3D API).
82      */
83     void drawPath(GrPipelineBuilder*, const GrPathProcessor*, const GrPath*,
84                   GrPathRendering::FillType);
85 
86     /**
87      * Draws the aggregate path from combining multiple. Note that this will not
88      * always be equivalent to back-to-back calls to drawPath(). It will respect
89      * the HW antialias flag on the GrPipelineBuilder (if possible in the 3D API).
90      *
91      * @param pathRange       Source paths to draw from
92      * @param indices         Array of path indices to draw
93      * @param indexType       Data type of the array elements in indexBuffer
94      * @param transformValues Array of transforms for the individual paths
95      * @param transformType   Type of transforms in transformBuffer
96      * @param count           Number of paths to draw
97      * @param fill            Fill type for drawing all the paths
98      */
99     void drawPaths(GrPipelineBuilder*,
100                    const GrPathProcessor*,
101                    const GrPathRange* pathRange,
102                    const void* indices,
103                    PathIndexType indexType,
104                    const float transformValues[],
105                    PathTransformType transformType,
106                    int count,
107                    GrPathRendering::FillType fill);
108 
109     /**
110      * Helper function for drawing rects.
111      *
112      * @param rect        the rect to draw
113      * @param localRect   optional rect that specifies local coords to map onto
114      *                    rect. If NULL then rect serves as the local coords.
115      * @param localMatrix Optional local matrix. The local coordinates are specified by localRect,
116      *                    or if it is NULL by rect. This matrix applies to the coordinate implied by
117      *                    that rectangle before it is input to GrCoordTransforms that read local
118      *                    coordinates
119      */
120     void drawRect(GrPipelineBuilder* pipelineBuilder,
121                   GrColor color,
122                   const SkMatrix& viewMatrix,
123                   const SkRect& rect,
124                   const SkRect* localRect,
125                   const SkMatrix* localMatrix);
126 
127     /**
128      * Helper for drawRect when the caller doesn't need separate local rects or matrices.
129      */
drawSimpleRect(GrPipelineBuilder * ds,GrColor color,const SkMatrix & viewM,const SkRect & rect)130     void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
131                         const SkRect& rect) {
132         this->drawRect(ds, color, viewM, rect, NULL, NULL);
133     }
drawSimpleRect(GrPipelineBuilder * ds,GrColor color,const SkMatrix & viewM,const SkIRect & irect)134     void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM,
135                         const SkIRect& irect) {
136         SkRect rect = SkRect::Make(irect);
137         this->drawRect(ds, color, viewM, rect, NULL, NULL);
138     }
139 
140 
141     /**
142      * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
143      * thing if rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire
144      * render target can be optionally cleared.
145      */
146     void clear(const SkIRect* rect,
147                GrColor color,
148                bool canIgnoreRect,
149                GrRenderTarget* renderTarget);
150 
151     /**
152      * Discards the contents render target.
153      **/
154     virtual void discard(GrRenderTarget*) = 0;
155 
156     /**
157      * Called at start and end of gpu trace marking
158      * GR_CREATE_GPU_TRACE_MARKER(marker_str, target) will automatically call these at the start
159      * and end of a code block respectively
160      */
161     void addGpuTraceMarker(const GrGpuTraceMarker* marker);
162     void removeGpuTraceMarker(const GrGpuTraceMarker* marker);
163 
164     /**
165      * Takes the current active set of markers and stores them for later use. Any current marker
166      * in the active set is removed from the active set and the targets remove function is called.
167      * These functions do not work as a stack so you cannot call save a second time before calling
168      * restore. Also, it is assumed that when restore is called the current active set of markers
169      * is empty. When the stored markers are added back into the active set, the targets add marker
170      * is called.
171      */
172     void saveActiveTraceMarkers();
173     void restoreActiveTraceMarkers();
174 
175     /**
176      * Copies a pixel rectangle from one surface to another. This call may finalize
177      * reserved vertex/index data (as though a draw call was made). The src pixels
178      * copied are specified by srcRect. They are copied to a rect of the same
179      * size in dst with top left at dstPoint. If the src rect is clipped by the
180      * src bounds then  pixel values in the dst rect corresponding to area clipped
181      * by the src rect are not overwritten. This method can fail and return false
182      * depending on the type of surface, configs, etc, and the backend-specific
183      * limitations. If rect is clipped out entirely by the src or dst bounds then
184      * true is returned since there is no actual copy necessary to succeed.
185      */
186     bool copySurface(GrSurface* dst,
187                      GrSurface* src,
188                      const SkIRect& srcRect,
189                      const SkIPoint& dstPoint);
190     /**
191      * Function that determines whether a copySurface call would succeed without actually
192      * performing the copy.
193      */
194     bool canCopySurface(const GrSurface* dst,
195                         const GrSurface* src,
196                         const SkIRect& srcRect,
197                         const SkIPoint& dstPoint);
198 
199     /**
200      * Release any resources that are cached but not currently in use. This
201      * is intended to give an application some recourse when resources are low.
202      */
purgeResources()203     virtual void purgeResources() {};
204 
205     ///////////////////////////////////////////////////////////////////////////
206     // Draw execution tracking (for font atlases and other resources)
207     class DrawToken {
208     public:
DrawToken(GrDrawTarget * drawTarget,uint32_t drawID)209         DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) :
210                   fDrawTarget(drawTarget), fDrawID(drawID) {}
211 
isIssued()212         bool isIssued() { return fDrawTarget && fDrawTarget->isIssued(fDrawID); }
213 
214     private:
215         GrDrawTarget*  fDrawTarget;
216         uint32_t       fDrawID;   // this may wrap, but we're doing direct comparison
217                                   // so that should be okay
218     };
219 
getCurrentDrawToken()220     virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
221 
222     bool programUnitTest(int maxStages);
223 
224 protected:
225     friend class GrCommandBuilder; // for PipelineInfo
226     friend class GrInOrderCommandBuilder; // for PipelineInfo
227     friend class GrReorderCommandBuilder; // for PipelineInfo
228     friend class GrTargetCommands; // for PipelineInfo
229 
getContext()230     GrContext* getContext() { return fContext; }
getContext()231     const GrContext* getContext() const { return fContext; }
232 
getGpu()233     GrGpu* getGpu() {
234         SkASSERT(fContext && fContext->getGpu());
235         return fContext->getGpu();
236     }
getGpu()237     const GrGpu* getGpu() const {
238         SkASSERT(fContext && fContext->getGpu());
239         return fContext->getGpu();
240     }
241 
getActiveTraceMarkers()242     const GrTraceMarkerSet& getActiveTraceMarkers() { return fActiveTraceMarkers; }
243 
244     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
245     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
246     // needs to be accessed by GLPrograms to setup a correct drawstate
247     bool setupDstReadIfNecessary(const GrPipelineBuilder&,
248                                  const GrProcOptInfo& colorPOI,
249                                  const GrProcOptInfo& coveragePOI,
250                                  GrDeviceCoordTexture* dstCopy,
251                                  const SkRect* drawBounds);
252 
253     struct PipelineInfo {
254         PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
255                      const GrPrimitiveProcessor* primProc,
256                      const SkRect* devBounds, GrDrawTarget* target);
257 
258         PipelineInfo(GrPipelineBuilder* pipelineBuilder, GrScissorState* scissor,
259                      const GrBatch* batch, const SkRect* devBounds,
260                      GrDrawTarget* target);
261 
willBlendWithDstPipelineInfo262         bool willBlendWithDst(const GrPrimitiveProcessor* primProc) const {
263             return fPipelineBuilder->willBlendWithDst(primProc);
264         }
265     private:
266         friend class GrDrawTarget;
267 
mustSkipDrawPipelineInfo268         bool mustSkipDraw() const { return (NULL == fPipelineBuilder); }
269 
270         GrPipelineBuilder*      fPipelineBuilder;
271         GrScissorState*         fScissor;
272         GrProcOptInfo           fColorPOI;
273         GrProcOptInfo           fCoveragePOI;
274         GrDeviceCoordTexture    fDstCopy;
275     };
276 
277     void setupPipeline(const PipelineInfo& pipelineInfo, GrPipeline* pipeline);
278 
279 private:
280     virtual void onReset() = 0;
281 
282     virtual void onFlush() = 0;
283 
284     virtual void onDrawBatch(GrBatch*, const PipelineInfo&) = 0;
285     virtual void onStencilPath(const GrPipelineBuilder&,
286                                const GrPathProcessor*,
287                                const GrPath*,
288                                const GrScissorState&,
289                                const GrStencilSettings&) = 0;
290     virtual void onDrawPath(const GrPathProcessor*,
291                             const GrPath*,
292                             const GrStencilSettings&,
293                             const PipelineInfo&) = 0;
294     virtual void onDrawPaths(const GrPathProcessor*,
295                              const GrPathRange*,
296                              const void* indices,
297                              PathIndexType,
298                              const float transformValues[],
299                              PathTransformType,
300                              int count,
301                              const GrStencilSettings&,
302                              const PipelineInfo&) = 0;
303 
304     virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
305                          GrRenderTarget* renderTarget) = 0;
306 
307     /** The subclass's copy surface implementation. It should assume that any clipping has already
308         been performed on the rect and point and that the GrGpu supports the copy. */
309     virtual void onCopySurface(GrSurface* dst,
310                                GrSurface* src,
311                                const SkIRect& srcRect,
312                                const SkIPoint& dstPoint) = 0;
313 
314     // Check to see if this set of draw commands has been sent out
isIssued(uint32_t drawID)315     virtual bool       isIssued(uint32_t drawID) { return true; }
316     void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
317                                            const GrStencilAttachment*,
318                                            GrStencilSettings*);
319     virtual GrClipMaskManager* clipMaskManager() = 0;
320     virtual bool setupClip(GrPipelineBuilder*,
321                            GrPipelineBuilder::AutoRestoreFragmentProcessors*,
322                            GrPipelineBuilder::AutoRestoreStencil*,
323                            GrScissorState*,
324                            const SkRect* devBounds) = 0;
325 
326     // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
327     GrContext*                                                      fContext;
328     SkAutoTUnref<const GrDrawTargetCaps>                            fCaps;
329     // To keep track that we always have at least as many debug marker adds as removes
330     int                                                             fGpuTraceMarkerCount;
331     GrTraceMarkerSet                                                fActiveTraceMarkers;
332     GrTraceMarkerSet                                                fStoredTraceMarkers;
333     bool                                                            fFlushing;
334 
335     typedef SkRefCnt INHERITED;
336 };
337 
338 /*
339  * This class is JUST for clip mask manager.  Everyone else should just use draw target above.
340  */
341 class GrClipTarget : public GrDrawTarget {
342 public:
GrClipTarget(GrContext * context)343     GrClipTarget(GrContext* context)
344         : INHERITED(context) {
345         fClipMaskManager.setClipTarget(this);
346     }
347 
348     /* Clip mask manager needs access to the context.
349      * TODO we only need a very small subset of context in the CMM.
350      */
getContext()351     GrContext* getContext() { return INHERITED::getContext(); }
getContext()352     const GrContext* getContext() const { return INHERITED::getContext(); }
353 
354     /**
355      * Clip Mask Manager(and no one else) needs to clear private stencil bits.
356      * ClipTarget subclass sets clip bit in the stencil buffer. The subclass
357      * is free to clear the remaining bits to zero if masked clears are more
358      * expensive than clearing all bits.
359      */
360     virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* = NULL) = 0;
361 
362     /**
363      * Release any resources that are cached but not currently in use. This
364      * is intended to give an application some recourse when resources are low.
365      */
purgeResources()366     void purgeResources() override {
367         // The clip mask manager can rebuild all its clip masks so just
368         // get rid of them all.
369         fClipMaskManager.purgeResources();
370     };
371 
372 protected:
373     GrClipMaskManager           fClipMaskManager;
374 
375 private:
clipMaskManager()376     GrClipMaskManager* clipMaskManager() override { return &fClipMaskManager; }
377 
378     virtual bool setupClip(GrPipelineBuilder*,
379                            GrPipelineBuilder::AutoRestoreFragmentProcessors*,
380                            GrPipelineBuilder::AutoRestoreStencil*,
381                            GrScissorState* scissorState,
382                            const SkRect* devBounds) override;
383 
384     typedef GrDrawTarget INHERITED;
385 };
386 
387 #endif
388