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 "GrClipData.h" 12 #include "GrDrawState.h" 13 #include "GrIndexBuffer.h" 14 15 #include "SkClipStack.h" 16 #include "SkMatrix.h" 17 #include "SkPath.h" 18 #include "SkTArray.h" 19 #include "SkTLazy.h" 20 #include "SkTypes.h" 21 #include "SkXfermode.h" 22 23 class GrClipData; 24 class GrDrawTargetCaps; 25 class GrPath; 26 class GrVertexBuffer; 27 class SkStrokeRec; 28 29 class GrDrawTarget : public SkRefCnt { 30 protected: 31 class DrawInfo; 32 33 public: 34 SK_DECLARE_INST_COUNT(GrDrawTarget) 35 36 /////////////////////////////////////////////////////////////////////////// 37 38 // The context may not be fully constructed and should not be used during GrDrawTarget 39 // construction. 40 GrDrawTarget(GrContext* context); 41 virtual ~GrDrawTarget(); 42 43 /** 44 * Gets the capabilities of the draw target. 45 */ caps()46 const GrDrawTargetCaps* caps() const { return fCaps.get(); } 47 48 /** 49 * Sets the current clip to the region specified by clip. All draws will be 50 * clipped against this clip if kClip_StateBit is enabled. 51 * 52 * Setting the clip may (or may not) zero out the client's stencil bits. 53 * 54 * @param description of the clipping region 55 */ 56 void setClip(const GrClipData* clip); 57 58 /** 59 * Gets the current clip. 60 * 61 * @return the clip. 62 */ 63 const GrClipData* getClip() const; 64 65 /** 66 * Sets the draw state object for the draw target. Note that this does not 67 * make a copy. The GrDrawTarget will take a reference to passed object. 68 * Passing NULL will cause the GrDrawTarget to use its own internal draw 69 * state object rather than an externally provided one. 70 */ 71 void setDrawState(GrDrawState* drawState); 72 73 /** 74 * Read-only access to the GrDrawTarget's current draw state. 75 */ getDrawState()76 const GrDrawState& getDrawState() const { return *fDrawState; } 77 78 /** 79 * Read-write access to the GrDrawTarget's current draw state. Note that 80 * this doesn't ref. 81 */ drawState()82 GrDrawState* drawState() { return fDrawState; } 83 84 /** 85 * Color alpha and coverage are two inputs to the drawing pipeline. For some 86 * blend modes it is safe to fold the coverage into constant or per-vertex 87 * color alpha value. For other blend modes they must be handled separately. 88 * Depending on features available in the underlying 3D API this may or may 89 * not be possible. 90 * 91 * This function considers the current draw state and the draw target's 92 * capabilities to determine whether coverage can be handled correctly. The 93 * following assumptions are made: 94 * 1. The caller intends to somehow specify coverage. This can be 95 * specified either by enabling a coverage stage on the GrDrawState or 96 * via the vertex layout. 97 * 2. Other than enabling coverage stages or enabling coverage in the 98 * layout, the current configuration of the target's GrDrawState is as 99 * it will be at draw time. 100 */ 101 bool canApplyCoverage() const; 102 103 /** When we're using coverage AA but the blend is incompatible (given gpu 104 * limitations) we should disable AA. */ shouldDisableCoverageAAForBlend()105 bool shouldDisableCoverageAAForBlend() { 106 // Enable below if we should draw with AA even when it produces 107 // incorrect blending. 108 // return false; 109 return !this->canApplyCoverage(); 110 } 111 112 /** 113 * Given the current draw state and hw support, will HW AA lines be used (if 114 * a line primitive type is drawn)? 115 */ 116 bool willUseHWAALines() const; 117 118 /** 119 * There are three types of "sources" of geometry (vertices and indices) for 120 * draw calls made on the target. When performing an indexed draw, the 121 * indices and vertices can use different source types. Once a source is 122 * specified it can be used for multiple draws. However, the time at which 123 * the geometry data is no longer editable depends on the source type. 124 * 125 * Sometimes it is necessary to perform a draw while upstack code has 126 * already specified geometry that it isn't finished with. So there are push 127 * and pop methods. This allows the client to push the sources, draw 128 * something using alternate sources, and then pop to restore the original 129 * sources. 130 * 131 * Aside from pushes and pops, a source remains valid until another source 132 * is set or resetVertexSource / resetIndexSource is called. Drawing from 133 * a reset source is an error. 134 * 135 * The three types of sources are: 136 * 137 * 1. A cpu array (set*SourceToArray). This is useful when the caller 138 * already provided vertex data in a format compatible with a 139 * GrVertexLayout. The data in the array is consumed at the time that 140 * set*SourceToArray is called and subsequent edits to the array will not 141 * be reflected in draws. 142 * 143 * 2. Reserve. This is most useful when the caller has data it must 144 * transform before drawing and is not long-lived. The caller requests 145 * that the draw target make room for some amount of vertex and/or index 146 * data. The target provides ptrs to hold the vertex and/or index data. 147 * 148 * The data is writable up until the next drawIndexed, drawNonIndexed, 149 * drawIndexedInstances, drawRect, copySurface, or pushGeometrySource. At 150 * this point the data is frozen and the ptrs are no longer valid. 151 * 152 * Where the space is allocated and how it is uploaded to the GPU is 153 * subclass-dependent. 154 * 155 * 3. Vertex and Index Buffers. This is most useful for geometry that will 156 * is long-lived. When the data in the buffer is consumed depends on the 157 * GrDrawTarget subclass. For deferred subclasses the caller has to 158 * guarantee that the data is still available in the buffers at playback. 159 * (TODO: Make this more automatic as we have done for read/write pixels) 160 * 161 * The size of each vertex is determined by querying the current GrDrawState. 162 */ 163 164 /** 165 * Reserves space for vertices and/or indices. Zero can be specifed as 166 * either the vertex or index count if the caller desires to only reserve 167 * space for only indices or only vertices. If zero is specifed for 168 * vertexCount then the vertex source will be unmodified and likewise for 169 * indexCount. 170 * 171 * If the function returns true then the reserve suceeded and the vertices 172 * and indices pointers will point to the space created. 173 * 174 * If the target cannot make space for the request then this function will 175 * return false. If vertexCount was non-zero then upon failure the vertex 176 * source is reset and likewise for indexCount. 177 * 178 * The pointers to the space allocated for vertices and indices remain valid 179 * until a drawIndexed, drawNonIndexed, drawIndexedInstances, drawRect, 180 * copySurface, or push/popGeomtrySource is called. At that point logically a 181 * snapshot of the data is made and the pointers are invalid. 182 * 183 * @param vertexCount the number of vertices to reserve space for. Can be 184 * 0. Vertex size is queried from the current GrDrawState. 185 * @param indexCount the number of indices to reserve space for. Can be 0. 186 * @param vertices will point to reserved vertex space if vertexCount is 187 * non-zero. Illegal to pass NULL if vertexCount > 0. 188 * @param indices will point to reserved index space if indexCount is 189 * non-zero. Illegal to pass NULL if indexCount > 0. 190 */ 191 bool reserveVertexAndIndexSpace(int vertexCount, 192 int indexCount, 193 void** vertices, 194 void** indices); 195 196 /** 197 * Provides hints to caller about the number of vertices and indices 198 * that can be allocated cheaply. This can be useful if caller is reserving 199 * space but doesn't know exactly how much geometry is needed. 200 * 201 * Also may hint whether the draw target should be flushed first. This is 202 * useful for deferred targets. 203 * 204 * @param vertexCount in: hint about how many vertices the caller would 205 * like to allocate. Vertex size is queried from the 206 * current GrDrawState. 207 * out: a hint about the number of vertices that can be 208 * allocated cheaply. Negative means no hint. 209 * Ignored if NULL. 210 * @param indexCount in: hint about how many indices the caller would 211 * like to allocate. 212 * out: a hint about the number of indices that can be 213 * allocated cheaply. Negative means no hint. 214 * Ignored if NULL. 215 * 216 * @return true if target should be flushed based on the input values. 217 */ 218 virtual bool geometryHints(int* vertexCount, 219 int* indexCount) const; 220 221 /** 222 * Sets source of vertex data for the next draw. Array must contain 223 * the vertex data when this is called. 224 * 225 * @param vertexArray cpu array containing vertex data. 226 * @param vertexCount the number of vertices in the array. Vertex size is 227 * queried from the current GrDrawState. 228 */ 229 void setVertexSourceToArray(const void* vertexArray, int vertexCount); 230 231 /** 232 * Sets source of index data for the next indexed draw. Array must contain 233 * the indices when this is called. 234 * 235 * @param indexArray cpu array containing index data. 236 * @param indexCount the number of indices in the array. 237 */ 238 void setIndexSourceToArray(const void* indexArray, int indexCount); 239 240 /** 241 * Sets source of vertex data for the next draw. Data does not have to be 242 * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances. 243 * 244 * @param buffer vertex buffer containing vertex data. Must be 245 * unlocked before draw call. Vertex size is queried 246 * from current GrDrawState. 247 */ 248 void setVertexSourceToBuffer(const GrVertexBuffer* buffer); 249 250 /** 251 * Sets source of index data for the next indexed draw. Data does not have 252 * to be in the buffer until drawIndexed. 253 * 254 * @param buffer index buffer containing indices. Must be unlocked 255 * before indexed draw call. 256 */ 257 void setIndexSourceToBuffer(const GrIndexBuffer* buffer); 258 259 /** 260 * Resets vertex source. Drawing from reset vertices is illegal. Set vertex 261 * source to reserved, array, or buffer before next draw. May be able to free 262 * up temporary storage allocated by setVertexSourceToArray or 263 * reserveVertexSpace. 264 */ 265 void resetVertexSource(); 266 267 /** 268 * Resets index source. Indexed Drawing from reset indices is illegal. Set 269 * index source to reserved, array, or buffer before next indexed draw. May 270 * be able to free up temporary storage allocated by setIndexSourceToArray 271 * or reserveIndexSpace. 272 */ 273 void resetIndexSource(); 274 275 /** 276 * Query to find out if the vertex or index source is reserved. 277 */ hasReservedVerticesOrIndices()278 bool hasReservedVerticesOrIndices() const { 279 return kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc || 280 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; 281 } 282 283 /** 284 * Pushes and resets the vertex/index sources. Any reserved vertex / index 285 * data is finalized (i.e. cannot be updated after the matching pop but can 286 * be drawn from). Must be balanced by a pop. 287 */ 288 void pushGeometrySource(); 289 290 /** 291 * Pops the vertex / index sources from the matching push. 292 */ 293 void popGeometrySource(); 294 295 /** 296 * Draws indexed geometry using the current state and current vertex / index 297 * sources. 298 * 299 * @param type The type of primitives to draw. 300 * @param startVertex the vertex in the vertex array/buffer corresponding 301 * to index 0 302 * @param startIndex first index to read from index src. 303 * @param vertexCount one greater than the max index. 304 * @param indexCount the number of index elements to read. The index count 305 * is effectively trimmed to the last completely 306 * specified primitive. 307 * @param devBounds optional bounds hint. This is a promise from the caller, 308 * not a request for clipping. 309 */ 310 void drawIndexed(GrPrimitiveType type, 311 int startVertex, 312 int startIndex, 313 int vertexCount, 314 int indexCount, 315 const SkRect* devBounds = NULL); 316 317 /** 318 * Draws non-indexed geometry using the current state and current vertex 319 * sources. 320 * 321 * @param type The type of primitives to draw. 322 * @param startVertex the vertex in the vertex array/buffer corresponding 323 * to index 0 324 * @param vertexCount one greater than the max index. 325 * @param devBounds optional bounds hint. This is a promise from the caller, 326 * not a request for clipping. 327 */ 328 void drawNonIndexed(GrPrimitiveType type, 329 int startVertex, 330 int vertexCount, 331 const SkRect* devBounds = NULL); 332 333 /** 334 * Draws path into the stencil buffer. The fill must be either even/odd or 335 * winding (not inverse or hairline). It will respect the HW antialias flag 336 * on the draw state (if possible in the 3D API). 337 */ 338 void stencilPath(const GrPath*, SkPath::FillType fill); 339 340 /** 341 * Draws a path. Fill must not be a hairline. It will respect the HW 342 * antialias flag on the draw state (if possible in the 3D API). 343 */ 344 void drawPath(const GrPath*, SkPath::FillType fill); 345 346 /** 347 * Helper function for drawing rects. It performs a geometry src push and pop 348 * and thus will finalize any reserved geometry. 349 * 350 * @param rect the rect to draw 351 * @param matrix optional matrix applied to rect (before viewMatrix) 352 * @param localRect optional rect that specifies local coords to map onto 353 * rect. If NULL then rect serves as the local coords. 354 * @param localMatrix optional matrix applied to localRect. If 355 * srcRect is non-NULL and srcMatrix is non-NULL 356 * then srcRect will be transformed by srcMatrix. 357 * srcMatrix can be NULL when no srcMatrix is desired. 358 */ drawRect(const SkRect & rect,const SkMatrix * matrix,const SkRect * localRect,const SkMatrix * localMatrix)359 void drawRect(const SkRect& rect, 360 const SkMatrix* matrix, 361 const SkRect* localRect, 362 const SkMatrix* localMatrix) { 363 AutoGeometryPush agp(this); 364 this->onDrawRect(rect, matrix, localRect, localMatrix); 365 } 366 367 /** 368 * Helper for drawRect when the caller doesn't need separate local rects or matrices. 369 */ 370 void drawSimpleRect(const SkRect& rect, const SkMatrix* matrix = NULL) { 371 this->drawRect(rect, matrix, NULL, NULL); 372 } 373 void drawSimpleRect(const SkIRect& irect, const SkMatrix* matrix = NULL) { 374 SkRect rect = SkRect::Make(irect); 375 this->drawRect(rect, matrix, NULL, NULL); 376 } 377 378 /** 379 * This call is used to draw multiple instances of some geometry with a 380 * given number of vertices (V) and indices (I) per-instance. The indices in 381 * the index source must have the form i[k+I] == i[k] + V. Also, all indices 382 * i[kI] ... i[(k+1)I-1] must be elements of the range kV ... (k+1)V-1. As a 383 * concrete example, the following index buffer for drawing a series of 384 * quads each as two triangles each satisfies these conditions with V=4 and 385 * I=6: 386 * (0,1,2,0,2,3, 4,5,6,4,6,7, 8,9,10,8,10,11, ...) 387 * 388 * The call assumes that the pattern of indices fills the entire index 389 * source. The size of the index buffer limits the number of instances that 390 * can be drawn by the GPU in a single draw. However, the caller may specify 391 * any (positive) number for instanceCount and if necessary multiple GPU 392 * draws will be issued. Moreover, when drawIndexedInstances is called 393 * multiple times it may be possible for GrDrawTarget to group them into a 394 * single GPU draw. 395 * 396 * @param type the type of primitives to draw 397 * @param instanceCount the number of instances to draw. Each instance 398 * consists of verticesPerInstance vertices indexed by 399 * indicesPerInstance indices drawn as the primitive 400 * type specified by type. 401 * @param verticesPerInstance The number of vertices in each instance (V 402 * in the above description). 403 * @param indicesPerInstance The number of indices in each instance (I 404 * in the above description). 405 * @param devBounds optional bounds hint. This is a promise from the caller, 406 * not a request for clipping. 407 */ 408 void drawIndexedInstances(GrPrimitiveType type, 409 int instanceCount, 410 int verticesPerInstance, 411 int indicesPerInstance, 412 const SkRect* devBounds = NULL); 413 414 /** 415 * Clear the current render target if one isn't passed in. Ignores the 416 * clip and all other draw state (blend mode, stages, etc). Clears the 417 * whole thing if rect is NULL, otherwise just the rect. If canIgnoreRect 418 * is set then the entire render target can be optionally cleared. 419 */ 420 virtual void clear(const SkIRect* rect, 421 GrColor color, 422 bool canIgnoreRect, 423 GrRenderTarget* renderTarget = NULL) = 0; 424 425 /** 426 * Copies a pixel rectangle from one surface to another. This call may finalize 427 * reserved vertex/index data (as though a draw call was made). The src pixels 428 * copied are specified by srcRect. They are copied to a rect of the same 429 * size in dst with top left at dstPoint. If the src rect is clipped by the 430 * src bounds then pixel values in the dst rect corresponding to area clipped 431 * by the src rect are not overwritten. This method can fail and return false 432 * depending on the type of surface, configs, etc, and the backend-specific 433 * limitations. If rect is clipped out entirely by the src or dst bounds then 434 * true is returned since there is no actual copy necessary to succeed. 435 */ 436 bool copySurface(GrSurface* dst, 437 GrSurface* src, 438 const SkIRect& srcRect, 439 const SkIPoint& dstPoint); 440 /** 441 * Function that determines whether a copySurface call would succeed without 442 * performing the copy. 443 */ 444 bool canCopySurface(GrSurface* dst, 445 GrSurface* src, 446 const SkIRect& srcRect, 447 const SkIPoint& dstPoint); 448 449 /** 450 * This is can be called before allocating a texture to be a dst for copySurface. It will 451 * populate the origin, config, and flags fields of the desc such that copySurface is more 452 * likely to succeed and be efficient. 453 */ 454 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc); 455 456 457 /** 458 * Release any resources that are cached but not currently in use. This 459 * is intended to give an application some recourse when resources are low. 460 */ purgeResources()461 virtual void purgeResources() {}; 462 463 /** 464 * For subclass internal use to invoke a call to onDraw(). See DrawInfo below. 465 */ executeDraw(const DrawInfo & info)466 void executeDraw(const DrawInfo& info) { this->onDraw(info); } 467 468 /** 469 * For subclass internal use to invoke a call to onDrawPath(). 470 */ executeDrawPath(const GrPath * path,SkPath::FillType fill,const GrDeviceCoordTexture * dstCopy)471 void executeDrawPath(const GrPath* path, SkPath::FillType fill, 472 const GrDeviceCoordTexture* dstCopy) { 473 this->onDrawPath(path, fill, dstCopy); 474 } 475 476 //////////////////////////////////////////////////////////////////////////// 477 478 /** 479 * See AutoStateRestore below. 480 */ 481 enum ASRInit { 482 kPreserve_ASRInit, 483 kReset_ASRInit 484 }; 485 486 /** 487 * Saves off the current state and restores it in the destructor. It will 488 * install a new GrDrawState object on the target (setDrawState) and restore 489 * the previous one in the destructor. The caller should call drawState() to 490 * get the new draw state after the ASR is installed. 491 * 492 * GrDrawState* state = target->drawState(); 493 * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit). 494 * state->setRenderTarget(rt); // state refers to the GrDrawState set on 495 * // target before asr was initialized. 496 * // Therefore, rt is set on the GrDrawState 497 * // that will be restored after asr's 498 * // destructor rather than target's current 499 * // GrDrawState. 500 */ 501 class AutoStateRestore : public ::SkNoncopyable { 502 public: 503 /** 504 * Default ASR will have no effect unless set() is subsequently called. 505 */ 506 AutoStateRestore(); 507 508 /** 509 * Saves the state on target. The state will be restored when the ASR 510 * is destroyed. If this constructor is used do not call set(). 511 * 512 * @param init Should the newly installed GrDrawState be a copy of the 513 * previous state or a default-initialized GrDrawState. 514 * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's 515 * matrix will be preconcat'ed with the param. All stages will be 516 updated to compensate for the matrix change. If init == kReset 517 then the draw state's matrix will be this matrix. 518 */ 519 AutoStateRestore(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL); 520 521 ~AutoStateRestore(); 522 523 /** 524 * Saves the state on target. The state will be restored when the ASR 525 * is destroyed. This should only be called once per ASR object and only 526 * when the default constructor was used. For nested saves use multiple 527 * ASR objects. 528 * 529 * @param init Should the newly installed GrDrawState be a copy of the 530 * previous state or a default-initialized GrDrawState. 531 * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's 532 * matrix will be preconcat'ed with the param. All stages will be 533 updated to compensate for the matrix change. If init == kReset 534 then the draw state's matrix will be this matrix. 535 */ 536 void set(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL); 537 538 /** 539 * Like set() but makes the view matrix identity. When init is kReset it is as though 540 * NULL was passed to set's viewMatrix param. When init is kPreserve it is as though 541 * the inverse view matrix was passed. If kPreserve is passed and the draw state's matrix 542 * is not invertible then this may fail. 543 */ 544 bool setIdentity(GrDrawTarget* target, ASRInit init); 545 546 private: 547 GrDrawTarget* fDrawTarget; 548 SkTLazy<GrDrawState> fTempState; 549 GrDrawState* fSavedState; 550 }; 551 552 //////////////////////////////////////////////////////////////////////////// 553 554 class AutoReleaseGeometry : public ::SkNoncopyable { 555 public: 556 AutoReleaseGeometry(GrDrawTarget* target, 557 int vertexCount, 558 int indexCount); 559 AutoReleaseGeometry(); 560 ~AutoReleaseGeometry(); 561 bool set(GrDrawTarget* target, 562 int vertexCount, 563 int indexCount); succeeded()564 bool succeeded() const { return NULL != fTarget; } vertices()565 void* vertices() const { SkASSERT(this->succeeded()); return fVertices; } indices()566 void* indices() const { SkASSERT(this->succeeded()); return fIndices; } positions()567 GrPoint* positions() const { 568 return static_cast<GrPoint*>(this->vertices()); 569 } 570 571 private: 572 void reset(); 573 574 GrDrawTarget* fTarget; 575 void* fVertices; 576 void* fIndices; 577 }; 578 579 //////////////////////////////////////////////////////////////////////////// 580 581 class AutoClipRestore : public ::SkNoncopyable { 582 public: AutoClipRestore(GrDrawTarget * target)583 AutoClipRestore(GrDrawTarget* target) { 584 fTarget = target; 585 fClip = fTarget->getClip(); 586 } 587 588 AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip); 589 ~AutoClipRestore()590 ~AutoClipRestore() { 591 fTarget->setClip(fClip); 592 } 593 private: 594 GrDrawTarget* fTarget; 595 const GrClipData* fClip; 596 SkTLazy<SkClipStack> fStack; 597 GrClipData fReplacementClip; 598 }; 599 600 //////////////////////////////////////////////////////////////////////////// 601 602 /** 603 * Saves the geometry src state at construction and restores in the destructor. It also saves 604 * and then restores the vertex attrib state. 605 */ 606 class AutoGeometryPush : public ::SkNoncopyable { 607 public: AutoGeometryPush(GrDrawTarget * target)608 AutoGeometryPush(GrDrawTarget* target) 609 : fAttribRestore(target->drawState()) { 610 SkASSERT(NULL != target); 611 fTarget = target; 612 target->pushGeometrySource(); 613 } 614 ~AutoGeometryPush()615 ~AutoGeometryPush() { fTarget->popGeometrySource(); } 616 617 private: 618 GrDrawTarget* fTarget; 619 GrDrawState::AutoVertexAttribRestore fAttribRestore; 620 }; 621 622 /** 623 * Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default 624 * state regardless of ASRInit value. 625 */ 626 class AutoGeometryAndStatePush : public ::SkNoncopyable { 627 public: 628 AutoGeometryAndStatePush(GrDrawTarget* target, 629 ASRInit init, 630 const SkMatrix* viewMatrix = NULL) fState(target,init,viewMatrix)631 : fState(target, init, viewMatrix) { 632 SkASSERT(NULL != target); 633 fTarget = target; 634 target->pushGeometrySource(); 635 if (kPreserve_ASRInit == init) { 636 target->drawState()->setDefaultVertexAttribs(); 637 } 638 } 639 ~AutoGeometryAndStatePush()640 ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); } 641 642 private: 643 AutoStateRestore fState; 644 GrDrawTarget* fTarget; 645 }; 646 647 /////////////////////////////////////////////////////////////////////////// 648 // Draw execution tracking (for font atlases and other resources) 649 class DrawToken { 650 public: DrawToken(GrDrawTarget * drawTarget,uint32_t drawID)651 DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) : 652 fDrawTarget(drawTarget), fDrawID(drawID) {} 653 isIssued()654 bool isIssued() { return NULL != fDrawTarget && fDrawTarget->isIssued(fDrawID); } 655 656 private: 657 GrDrawTarget* fDrawTarget; 658 uint32_t fDrawID; // this may wrap, but we're doing direct comparison 659 // so that should be okay 660 }; 661 getCurrentDrawToken()662 virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); } 663 664 protected: 665 666 enum GeometrySrcType { 667 kNone_GeometrySrcType, //<! src has not been specified 668 kReserved_GeometrySrcType, //<! src was set using reserve*Space 669 kArray_GeometrySrcType, //<! src was set using set*SourceToArray 670 kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer 671 }; 672 673 struct GeometrySrcState { 674 GeometrySrcType fVertexSrc; 675 union { 676 // valid if src type is buffer 677 const GrVertexBuffer* fVertexBuffer; 678 // valid if src type is reserved or array 679 int fVertexCount; 680 }; 681 682 GeometrySrcType fIndexSrc; 683 union { 684 // valid if src type is buffer 685 const GrIndexBuffer* fIndexBuffer; 686 // valid if src type is reserved or array 687 int fIndexCount; 688 }; 689 690 size_t fVertexSize; 691 }; 692 indexCountInCurrentSource()693 int indexCountInCurrentSource() const { 694 const GeometrySrcState& src = this->getGeomSrc(); 695 switch (src.fIndexSrc) { 696 case kNone_GeometrySrcType: 697 return 0; 698 case kReserved_GeometrySrcType: 699 case kArray_GeometrySrcType: 700 return src.fIndexCount; 701 case kBuffer_GeometrySrcType: 702 return static_cast<int>(src.fIndexBuffer->sizeInBytes() / sizeof(uint16_t)); 703 default: 704 GrCrash("Unexpected Index Source."); 705 return 0; 706 } 707 } 708 709 // This method is called by copySurface The srcRect is guaranteed to be entirely within the 710 // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls 711 // entirely within the dst. The default implementation will draw a rect from the src to the 712 // dst if the src is a texture and the dst is a render target and fail otherwise. 713 virtual bool onCopySurface(GrSurface* dst, 714 GrSurface* src, 715 const SkIRect& srcRect, 716 const SkIPoint& dstPoint); 717 718 // Called to determine whether an onCopySurface call would succeed or not. This is useful for 719 // proxy subclasses to test whether the copy would succeed without executing it yet. Derived 720 // classes must keep this consistent with their implementation of onCopySurface(). The inputs 721 // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src 722 // and dst bounds. 723 virtual bool onCanCopySurface(GrSurface* dst, 724 GrSurface* src, 725 const SkIRect& srcRect, 726 const SkIPoint& dstPoint); 727 getContext()728 GrContext* getContext() { return fContext; } getContext()729 const GrContext* getContext() const { return fContext; } 730 731 // A subclass may override this function if it wishes to be notified when the clip is changed. 732 // The override should call INHERITED::clipWillBeSet(). 733 virtual void clipWillBeSet(const GrClipData* clipData); 734 735 // subclasses must call this in their destructors to ensure all vertex 736 // and index sources have been released (including those held by 737 // pushGeometrySource()) 738 void releaseGeometry(); 739 740 // accessors for derived classes getGeomSrc()741 const GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); } 742 // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert. getVertexSize()743 size_t getVertexSize() const { 744 // the vertex layout is only valid if a vertex source has been specified. 745 SkASSERT(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType); 746 return this->getGeomSrc().fVertexSize; 747 } 748 749 // Subclass must initialize this in its constructor. 750 SkAutoTUnref<const GrDrawTargetCaps> fCaps; 751 752 /** 753 * Used to communicate draws to subclass's onDraw function. 754 */ 755 class DrawInfo { 756 public: DrawInfo(const DrawInfo & di)757 DrawInfo(const DrawInfo& di) { (*this) = di; } 758 DrawInfo& operator =(const DrawInfo& di); 759 primitiveType()760 GrPrimitiveType primitiveType() const { return fPrimitiveType; } startVertex()761 int startVertex() const { return fStartVertex; } startIndex()762 int startIndex() const { return fStartIndex; } vertexCount()763 int vertexCount() const { return fVertexCount; } indexCount()764 int indexCount() const { return fIndexCount; } verticesPerInstance()765 int verticesPerInstance() const { return fVerticesPerInstance; } indicesPerInstance()766 int indicesPerInstance() const { return fIndicesPerInstance; } instanceCount()767 int instanceCount() const { return fInstanceCount; } 768 isIndexed()769 bool isIndexed() const { return fIndexCount > 0; } 770 #ifdef SK_DEBUG 771 bool isInstanced() const; // this version is longer because of asserts 772 #else isInstanced()773 bool isInstanced() const { return fInstanceCount > 0; } 774 #endif 775 776 // adds or remove instances 777 void adjustInstanceCount(int instanceOffset); 778 // shifts the start vertex 779 void adjustStartVertex(int vertexOffset); 780 // shifts the start index 781 void adjustStartIndex(int indexOffset); 782 setDevBounds(const SkRect & bounds)783 void setDevBounds(const SkRect& bounds) { 784 fDevBoundsStorage = bounds; 785 fDevBounds = &fDevBoundsStorage; 786 } getDevBounds()787 const SkRect* getDevBounds() const { return fDevBounds; } 788 789 // NULL if no copy of the dst is needed for the draw. getDstCopy()790 const GrDeviceCoordTexture* getDstCopy() const { 791 if (NULL != fDstCopy.texture()) { 792 return &fDstCopy; 793 } else { 794 return NULL; 795 } 796 } 797 798 private: DrawInfo()799 DrawInfo() { fDevBounds = NULL; } 800 801 friend class GrDrawTarget; 802 803 GrPrimitiveType fPrimitiveType; 804 805 int fStartVertex; 806 int fStartIndex; 807 int fVertexCount; 808 int fIndexCount; 809 810 int fInstanceCount; 811 int fVerticesPerInstance; 812 int fIndicesPerInstance; 813 814 SkRect fDevBoundsStorage; 815 SkRect* fDevBounds; 816 817 GrDeviceCoordTexture fDstCopy; 818 }; 819 820 private: 821 // A subclass can optionally overload this function to be notified before 822 // vertex and index space is reserved. willReserveVertexAndIndexSpace(int vertexCount,int indexCount)823 virtual void willReserveVertexAndIndexSpace(int vertexCount, int indexCount) {} 824 825 // implemented by subclass to allocate space for reserved geom 826 virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0; 827 virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0; 828 // implemented by subclass to handle release of reserved geom space 829 virtual void releaseReservedVertexSpace() = 0; 830 virtual void releaseReservedIndexSpace() = 0; 831 // subclass must consume array contents when set 832 virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) = 0; 833 virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) = 0; 834 // subclass is notified that geom source will be set away from an array 835 virtual void releaseVertexArray() = 0; 836 virtual void releaseIndexArray() = 0; 837 // subclass overrides to be notified just before geo src state is pushed/popped. 838 virtual void geometrySourceWillPush() = 0; 839 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; 840 // subclass called to perform drawing 841 virtual void onDraw(const DrawInfo&) = 0; 842 // Implementation of drawRect. The geometry src and vertex attribs will already 843 // be saved before this is called and restored afterwards. A subclass may override 844 // this to perform more optimal rect rendering. Its draws should be funneled through 845 // one of the public GrDrawTarget draw methods (e.g. drawNonIndexed, 846 // drawIndexedInstances, ...). The base class draws a two triangle fan using 847 // drawNonIndexed from reserved vertex space. 848 virtual void onDrawRect(const SkRect& rect, 849 const SkMatrix* matrix, 850 const SkRect* localRect, 851 const SkMatrix* localMatrix); 852 853 virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0; 854 virtual void onDrawPath(const GrPath*, SkPath::FillType, 855 const GrDeviceCoordTexture* dstCopy) = 0; 856 857 // helpers for reserving vertex and index space. 858 bool reserveVertexSpace(size_t vertexSize, 859 int vertexCount, 860 void** vertices); 861 bool reserveIndexSpace(int indexCount, void** indices); 862 863 // called by drawIndexed and drawNonIndexed. Use a negative indexCount to 864 // indicate non-indexed drawing. 865 bool checkDraw(GrPrimitiveType type, int startVertex, 866 int startIndex, int vertexCount, 867 int indexCount) const; 868 // called when setting a new vert/idx source to unref prev vb/ib 869 void releasePreviousVertexSource(); 870 void releasePreviousIndexSource(); 871 872 // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required 873 // but couldn't be made. Otherwise, returns true. setupDstReadIfNecessary(DrawInfo * info)874 bool setupDstReadIfNecessary(DrawInfo* info) { 875 return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds()); 876 } 877 bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); 878 879 // Check to see if this set of draw commands has been sent out isIssued(uint32_t drawID)880 virtual bool isIssued(uint32_t drawID) { return true; } 881 882 enum { 883 kPreallocGeoSrcStateStackCnt = 4, 884 }; 885 SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack; 886 const GrClipData* fClip; 887 GrDrawState* fDrawState; 888 GrDrawState fDefaultDrawState; 889 // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget. 890 GrContext* fContext; 891 892 typedef SkRefCnt INHERITED; 893 }; 894 895 #endif 896