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 50 virtual ~GrDrawTarget() {} 51 52 /** 53 * Empties the draw buffer of any queued up draws. 54 */ 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 */ 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 */ 130 void drawSimpleRect(GrPipelineBuilder* ds, GrColor color, const SkMatrix& viewM, 131 const SkRect& rect) { 132 this->drawRect(ds, color, viewM, rect, NULL, NULL); 133 } 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 */ 203 virtual void purgeResources() {}; 204 205 /////////////////////////////////////////////////////////////////////////// 206 // Draw execution tracking (for font atlases and other resources) 207 class DrawToken { 208 public: 209 DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) : 210 fDrawTarget(drawTarget), fDrawID(drawID) {} 211 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 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 230 GrContext* getContext() { return fContext; } 231 const GrContext* getContext() const { return fContext; } 232 233 GrGpu* getGpu() { 234 SkASSERT(fContext && fContext->getGpu()); 235 return fContext->getGpu(); 236 } 237 const GrGpu* getGpu() const { 238 SkASSERT(fContext && fContext->getGpu()); 239 return fContext->getGpu(); 240 } 241 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 262 bool willBlendWithDst(const GrPrimitiveProcessor* primProc) const { 263 return fPipelineBuilder->willBlendWithDst(primProc); 264 } 265 private: 266 friend class GrDrawTarget; 267 268 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 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: 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 */ 351 GrContext* getContext() { return INHERITED::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 */ 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: 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