GrContext.h revision 6006d0f8c4f19d19a12de20826f731f52ac822a7
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 GrContext_DEFINED 9#define GrContext_DEFINED 10 11#include "GrClipData.h" 12#include "GrColor.h" 13#include "GrPaint.h" 14#include "GrPathRendererChain.h" 15#include "GrPoint.h" 16#include "GrRenderTarget.h" 17#include "GrTexture.h" 18#include "SkMatrix.h" 19#include "SkTypes.h" 20 21class GrAARectRenderer; 22class GrAutoScratchTexture; 23class GrDrawState; 24class GrDrawTarget; 25class GrEffect; 26class GrFontCache; 27class GrGpu; 28class GrIndexBuffer; 29class GrIndexBufferAllocPool; 30class GrInOrderDrawBuffer; 31class GrOvalRenderer; 32class GrPath; 33class GrPathRenderer; 34class GrResourceEntry; 35class GrResourceCache; 36class GrStencilBuffer; 37class GrTestTarget; 38class GrTextureParams; 39class GrVertexBuffer; 40class GrVertexBufferAllocPool; 41class GrSoftwarePathRenderer; 42class SkStrokeRec; 43 44class SK_API GrContext : public SkRefCnt { 45public: 46 SK_DECLARE_INST_COUNT(GrContext) 47 48 /** 49 * Creates a GrContext for a backend context. 50 */ 51 static GrContext* Create(GrBackend, GrBackendContext); 52 53 /** 54 * Returns the number of GrContext instances for the current thread. 55 */ 56 static int GetThreadInstanceCount(); 57 58 virtual ~GrContext(); 59 60 /** 61 * The GrContext normally assumes that no outsider is setting state 62 * within the underlying 3D API's context/device/whatever. This call informs 63 * the context that the state was modified and it should resend. Shouldn't 64 * be called frequently for good performance. 65 * The flag bits, state, is dpendent on which backend is used by the 66 * context, either GL or D3D (possible in future). 67 */ 68 void resetContext(uint32_t state = kAll_GrBackendState); 69 70 /** 71 * Callback function to allow classes to cleanup on GrContext destruction. 72 * The 'info' field is filled in with the 'info' passed to addCleanUp. 73 */ 74 typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); 75 76 /** 77 * Add a function to be called from within GrContext's destructor. 78 * This gives classes a chance to free resources held on a per context basis. 79 * The 'info' parameter will be stored and passed to the callback function. 80 */ 81 void addCleanUp(PFCleanUpFunc cleanUp, void* info) { 82 CleanUpData* entry = fCleanUpData.push(); 83 84 entry->fFunc = cleanUp; 85 entry->fInfo = info; 86 } 87 88 /** 89 * Abandons all GPU resources, assumes 3D API state is unknown. Call this 90 * if you have lost the associated GPU context, and thus internal texture, 91 * buffer, etc. references/IDs are now invalid. Should be called even when 92 * GrContext is no longer going to be used for two reasons: 93 * 1) ~GrContext will not try to free the objects in the 3D API. 94 * 2) If you've created GrResources that outlive the GrContext they will 95 * be marked as invalid (GrResource::isValid()) and won't attempt to 96 * free their underlying resource in the 3D API. 97 * Content drawn since the last GrContext::flush() may be lost. 98 */ 99 void contextLost(); 100 101 /** 102 * Similar to contextLost, but makes no attempt to reset state. 103 * Use this method when GrContext destruction is pending, but 104 * the graphics context is destroyed first. 105 */ 106 void contextDestroyed(); 107 108 /** 109 * Frees GPU created by the context. Can be called to reduce GPU memory 110 * pressure. 111 */ 112 void freeGpuResources(); 113 114 /** 115 * Returns the number of bytes of GPU memory hosted by the texture cache. 116 */ 117 size_t getGpuTextureCacheBytes() const; 118 119 /////////////////////////////////////////////////////////////////////////// 120 // Textures 121 122 /** 123 * Creates a new entry, based on the specified key and texture and returns it. The caller owns a 124 * ref on the returned texture which must be balanced by a call to unref. 125 * 126 * @param params The texture params used to draw a texture may help determine 127 * the cache entry used. (e.g. different versions may exist 128 * for different wrap modes on GPUs with limited NPOT 129 * texture support). NULL implies clamp wrap modes. 130 * @param desc Description of the texture properties. 131 * @param cacheID Cache-specific properties (e.g., texture gen ID) 132 * @param srcData Pointer to the pixel values. 133 * @param rowBytes The number of bytes between rows of the texture. Zero 134 * implies tightly packed rows. 135 * @param cacheKey (optional) If non-NULL, we'll write the cache key we used to cacheKey. 136 */ 137 GrTexture* createTexture(const GrTextureParams* params, 138 const GrTextureDesc& desc, 139 const GrCacheID& cacheID, 140 void* srcData, 141 size_t rowBytes, 142 GrResourceKey* cacheKey = NULL); 143 144 /** 145 * Search for an entry based on key and dimensions. If found, ref it and return it. The return 146 * value will be NULL if not found. The caller must balance with a call to unref. 147 * 148 * @param desc Description of the texture properties. 149 * @param cacheID Cache-specific properties (e.g., texture gen ID) 150 * @param params The texture params used to draw a texture may help determine 151 * the cache entry used. (e.g. different versions may exist 152 * for different wrap modes on GPUs with limited NPOT 153 * texture support). NULL implies clamp wrap modes. 154 */ 155 GrTexture* findAndRefTexture(const GrTextureDesc& desc, 156 const GrCacheID& cacheID, 157 const GrTextureParams* params); 158 /** 159 * Determines whether a texture is in the cache. If the texture is found it 160 * will not be locked or returned. This call does not affect the priority of 161 * the texture for deletion. 162 */ 163 bool isTextureInCache(const GrTextureDesc& desc, 164 const GrCacheID& cacheID, 165 const GrTextureParams* params) const; 166 167 /** 168 * Enum that determines how closely a returned scratch texture must match 169 * a provided GrTextureDesc. 170 */ 171 enum ScratchTexMatch { 172 /** 173 * Finds a texture that exactly matches the descriptor. 174 */ 175 kExact_ScratchTexMatch, 176 /** 177 * Finds a texture that approximately matches the descriptor. Will be 178 * at least as large in width and height as desc specifies. If desc 179 * specifies that texture is a render target then result will be a 180 * render target. If desc specifies a render target and doesn't set the 181 * no stencil flag then result will have a stencil. Format and aa level 182 * will always match. 183 */ 184 kApprox_ScratchTexMatch 185 }; 186 187 /** 188 * Returns a texture matching the desc. It's contents are unknown. Subsequent 189 * requests with the same descriptor are not guaranteed to return the same 190 * texture. The same texture is guaranteed not be returned again until it is 191 * unlocked. Call must be balanced with an unlockTexture() call. The caller 192 * owns a ref on the returned texture and must balance with a call to unref. 193 * 194 * Textures created by createAndLockTexture() hide the complications of 195 * tiling non-power-of-two textures on APIs that don't support this (e.g. 196 * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on 197 * such an API will create gaps in the tiling pattern. This includes clamp 198 * mode. (This may be addressed in a future update.) 199 */ 200 GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match); 201 202 /** 203 * When done with an entry, call unlockScratchTexture(entry) on it, which returns 204 * it to the cache, where it may be purged. This does not unref the texture. 205 */ 206 void unlockScratchTexture(GrTexture* texture); 207 208 /** 209 * This method should be called whenever a GrTexture is unreffed or 210 * switched from exclusive to non-exclusive. This 211 * gives the resource cache a chance to discard unneeded textures. 212 * Note: this entry point will be removed once totally ref-driven 213 * cache maintenance is implemented 214 */ 215 void purgeCache(); 216 217 /** 218 * Creates a texture that is outside the cache. Does not count against 219 * cache's budget. 220 */ 221 GrTexture* createUncachedTexture(const GrTextureDesc& desc, 222 void* srcData, 223 size_t rowBytes); 224 225 /** 226 * Returns true if the specified use of an indexed texture is supported. 227 * Support may depend upon whether the texture params indicate that the 228 * texture will be tiled. Passing NULL for the texture params indicates 229 * clamp mode. 230 */ 231 bool supportsIndex8PixelConfig(const GrTextureParams*, 232 int width, 233 int height) const; 234 235 /** 236 * Return the current texture cache limits. 237 * 238 * @param maxTextures If non-null, returns maximum number of textures that 239 * can be held in the cache. 240 * @param maxTextureBytes If non-null, returns maximum number of bytes of 241 * texture memory that can be held in the cache. 242 */ 243 void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const; 244 245 /** 246 * Specify the texture cache limits. If the current cache exceeds either 247 * of these, it will be purged (LRU) to keep the cache within these limits. 248 * 249 * @param maxTextures The maximum number of textures that can be held in 250 * the cache. 251 * @param maxTextureBytes The maximum number of bytes of texture memory 252 * that can be held in the cache. 253 */ 254 void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes); 255 256 /** 257 * Return the max width or height of a texture supported by the current GPU. 258 */ 259 int getMaxTextureSize() const; 260 261 /** 262 * Temporarily override the true max texture size. Note: an override 263 * larger then the true max texture size will have no effect. 264 * This entry point is mainly meant for testing texture size dependent 265 * features and is only available if defined outside of Skia (see 266 * bleed GM. 267 */ 268 void setMaxTextureSizeOverride(int maxTextureSizeOverride); 269 270 /////////////////////////////////////////////////////////////////////////// 271 // Render targets 272 273 /** 274 * Sets the render target. 275 * @param target the render target to set. 276 */ 277 void setRenderTarget(GrRenderTarget* target) { 278 fRenderTarget.reset(SkSafeRef(target)); 279 } 280 281 /** 282 * Gets the current render target. 283 * @return the currently bound render target. 284 */ 285 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 286 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } 287 288 GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; } 289 290 /** 291 * Can the provided configuration act as a color render target? 292 */ 293 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const; 294 295 /** 296 * Return the max width or height of a render target supported by the 297 * current GPU. 298 */ 299 int getMaxRenderTargetSize() const; 300 301 /** 302 * Returns the max sample count for a render target. It will be 0 if MSAA 303 * is not supported. 304 */ 305 int getMaxSampleCount() const; 306 307 /////////////////////////////////////////////////////////////////////////// 308 // Backend Surfaces 309 310 /** 311 * Wraps an existing texture with a GrTexture object. 312 * 313 * OpenGL: if the object is a texture Gr may change its GL texture params 314 * when it is drawn. 315 * 316 * @param desc description of the object to create. 317 * 318 * @return GrTexture object or NULL on failure. 319 */ 320 GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc); 321 322 /** 323 * Wraps an existing render target with a GrRenderTarget object. It is 324 * similar to wrapBackendTexture but can be used to draw into surfaces 325 * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that 326 * the client will resolve to a texture). 327 * 328 * @param desc description of the object to create. 329 * 330 * @return GrTexture object or NULL on failure. 331 */ 332 GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc); 333 334 /////////////////////////////////////////////////////////////////////////// 335 // Matrix state 336 337 /** 338 * Gets the current transformation matrix. 339 * @return the current matrix. 340 */ 341 const SkMatrix& getMatrix() const { return fViewMatrix; } 342 343 /** 344 * Sets the transformation matrix. 345 * @param m the matrix to set. 346 */ 347 void setMatrix(const SkMatrix& m) { fViewMatrix = m; } 348 349 /** 350 * Sets the current transformation matrix to identity. 351 */ 352 void setIdentityMatrix() { fViewMatrix.reset(); } 353 354 /** 355 * Concats the current matrix. The passed matrix is applied before the 356 * current matrix. 357 * @param m the matrix to concat. 358 */ 359 void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); } 360 361 362 /////////////////////////////////////////////////////////////////////////// 363 // Clip state 364 /** 365 * Gets the current clip. 366 * @return the current clip. 367 */ 368 const GrClipData* getClip() const { return fClip; } 369 370 /** 371 * Sets the clip. 372 * @param clipData the clip to set. 373 */ 374 void setClip(const GrClipData* clipData) { fClip = clipData; } 375 376 /////////////////////////////////////////////////////////////////////////// 377 // Draws 378 379 /** 380 * Clear the entire or rect of the render target, ignoring any clips. 381 * @param rect the rect to clear or the whole thing if rect is NULL. 382 * @param color the color to clear to. 383 * @param canIgnoreRect allows partial clears to be converted to whole 384 * clears on platforms for which that is cheap 385 * @param target if non-NULL, the render target to clear otherwise clear 386 * the current render target 387 */ 388 void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, 389 GrRenderTarget* target = NULL); 390 391 /** 392 * Draw everywhere (respecting the clip) with the paint. 393 */ 394 void drawPaint(const GrPaint& paint); 395 396 /** 397 * Draw the rect using a paint. 398 * @param paint describes how to color pixels. 399 * @param stroke the stroke information (width, join, cap). 400 * If stroke == NULL, then the rect is filled. 401 * Otherwise, if stroke width == 0, then the stroke 402 * is always a single pixel thick, else the rect is 403 * mitered/beveled stroked based on stroke width. 404 * @param matrix Optional matrix applied to the rect. Applied before 405 * context's matrix or the paint's matrix. 406 * The rects coords are used to access the paint (through texture matrix) 407 */ 408 void drawRect(const GrPaint& paint, 409 const SkRect&, 410 const SkStrokeRec* stroke = NULL, 411 const SkMatrix* matrix = NULL); 412 413 /** 414 * Maps a rect of local coordinates onto the a rect of destination 415 * coordinates. Each rect can optionally be transformed. The localRect 416 * is stretched over the dstRect. The dstRect is transformed by the 417 * context's matrix. Additional optional matrices for both rects can be 418 * provided by parameters. 419 * 420 * @param paint describes how to color pixels. 421 * @param dstRect the destination rect to draw. 422 * @param localRect rect of local coordinates to be mapped onto dstRect 423 * @param dstMatrix Optional matrix to transform dstRect. Applied before context's matrix. 424 * @param localMatrix Optional matrix to transform localRect. 425 */ 426 void drawRectToRect(const GrPaint& paint, 427 const SkRect& dstRect, 428 const SkRect& localRect, 429 const SkMatrix* dstMatrix = NULL, 430 const SkMatrix* localMatrix = NULL); 431 432 /** 433 * Draw a roundrect using a paint. 434 * 435 * @param paint describes how to color pixels. 436 * @param rrect the roundrect to draw 437 * @param stroke the stroke information (width, join, cap) 438 */ 439 void drawRRect(const GrPaint& paint, 440 const SkRRect& rrect, 441 const SkStrokeRec& stroke); 442 443 /** 444 * Draws a path. 445 * 446 * @param paint describes how to color pixels. 447 * @param path the path to draw 448 * @param stroke the stroke information (width, join, cap) 449 */ 450 void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); 451 452 /** 453 * Draws vertices with a paint. 454 * 455 * @param paint describes how to color pixels. 456 * @param primitiveType primitives type to draw. 457 * @param vertexCount number of vertices. 458 * @param positions array of vertex positions, required. 459 * @param texCoords optional array of texture coordinates used 460 * to access the paint. 461 * @param colors optional array of per-vertex colors, supercedes 462 * the paint's color field. 463 * @param indices optional array of indices. If NULL vertices 464 * are drawn non-indexed. 465 * @param indexCount if indices is non-null then this is the 466 * number of indices. 467 */ 468 void drawVertices(const GrPaint& paint, 469 GrPrimitiveType primitiveType, 470 int vertexCount, 471 const GrPoint positions[], 472 const GrPoint texs[], 473 const GrColor colors[], 474 const uint16_t indices[], 475 int indexCount); 476 477 /** 478 * Draws an oval. 479 * 480 * @param paint describes how to color pixels. 481 * @param oval the bounding rect of the oval. 482 * @param stroke the stroke information (width, style) 483 */ 484 void drawOval(const GrPaint& paint, 485 const SkRect& oval, 486 const SkStrokeRec& stroke); 487 488 /////////////////////////////////////////////////////////////////////////// 489 // Misc. 490 491 /** 492 * Flags that affect flush() behavior. 493 */ 494 enum FlushBits { 495 /** 496 * A client may reach a point where it has partially rendered a frame 497 * through a GrContext that it knows the user will never see. This flag 498 * causes the flush to skip submission of deferred content to the 3D API 499 * during the flush. 500 */ 501 kDiscard_FlushBit = 0x2, 502 }; 503 504 /** 505 * Call to ensure all drawing to the context has been issued to the 506 * underlying 3D API. 507 * @param flagsBitfield flags that control the flushing behavior. See 508 * FlushBits. 509 */ 510 void flush(int flagsBitfield = 0); 511 512 /** 513 * These flags can be used with the read/write pixels functions below. 514 */ 515 enum PixelOpsFlags { 516 /** The GrContext will not be flushed. This means that the read or write may occur before 517 previous draws have executed. */ 518 kDontFlush_PixelOpsFlag = 0x1, 519 /** The src for write or dst read is unpremultiplied. This is only respected if both the 520 config src and dst configs are an RGBA/BGRA 8888 format. */ 521 kUnpremul_PixelOpsFlag = 0x2, 522 }; 523 524 /** 525 * Reads a rectangle of pixels from a render target. 526 * @param target the render target to read from. NULL means the current render target. 527 * @param left left edge of the rectangle to read (inclusive) 528 * @param top top edge of the rectangle to read (inclusive) 529 * @param width width of rectangle to read in pixels. 530 * @param height height of rectangle to read in pixels. 531 * @param config the pixel config of the destination buffer 532 * @param buffer memory to read the rectangle into. 533 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly 534 * packed. 535 * @param pixelOpsFlags see PixelOpsFlags enum above. 536 * 537 * @return true if the read succeeded, false if not. The read can fail because of an unsupported 538 * pixel config or because no render target is currently set and NULL was passed for 539 * target. 540 */ 541 bool readRenderTargetPixels(GrRenderTarget* target, 542 int left, int top, int width, int height, 543 GrPixelConfig config, void* buffer, 544 size_t rowBytes = 0, 545 uint32_t pixelOpsFlags = 0); 546 547 /** 548 * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified 549 * rectangle. 550 * @param target the render target to write into. NULL means the current render target. 551 * @param left left edge of the rectangle to write (inclusive) 552 * @param top top edge of the rectangle to write (inclusive) 553 * @param width width of rectangle to write in pixels. 554 * @param height height of rectangle to write in pixels. 555 * @param config the pixel config of the source buffer 556 * @param buffer memory to read the rectangle from. 557 * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly 558 * packed. 559 * @param pixelOpsFlags see PixelOpsFlags enum above. 560 * 561 * @return true if the write succeeded, false if not. The write can fail because of an 562 * unsupported combination of target and pixel configs. 563 */ 564 bool writeRenderTargetPixels(GrRenderTarget* target, 565 int left, int top, int width, int height, 566 GrPixelConfig config, const void* buffer, 567 size_t rowBytes = 0, 568 uint32_t pixelOpsFlags = 0); 569 570 /** 571 * Reads a rectangle of pixels from a texture. 572 * @param texture the texture to read from. 573 * @param left left edge of the rectangle to read (inclusive) 574 * @param top top edge of the rectangle to read (inclusive) 575 * @param width width of rectangle to read in pixels. 576 * @param height height of rectangle to read in pixels. 577 * @param config the pixel config of the destination buffer 578 * @param buffer memory to read the rectangle into. 579 * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly 580 * packed. 581 * @param pixelOpsFlags see PixelOpsFlags enum above. 582 * 583 * @return true if the read succeeded, false if not. The read can fail because of an unsupported 584 * pixel config. 585 */ 586 bool readTexturePixels(GrTexture* texture, 587 int left, int top, int width, int height, 588 GrPixelConfig config, void* buffer, 589 size_t rowBytes = 0, 590 uint32_t pixelOpsFlags = 0); 591 592 /** 593 * Writes a rectangle of pixels to a texture. 594 * @param texture the render target to read from. 595 * @param left left edge of the rectangle to write (inclusive) 596 * @param top top edge of the rectangle to write (inclusive) 597 * @param width width of rectangle to write in pixels. 598 * @param height height of rectangle to write in pixels. 599 * @param config the pixel config of the source buffer 600 * @param buffer memory to read pixels from 601 * @param rowBytes number of bytes between consecutive rows. Zero 602 * means rows are tightly packed. 603 * @param pixelOpsFlags see PixelOpsFlags enum above. 604 * @return true if the write succeeded, false if not. The write can fail because of an 605 * unsupported combination of texture and pixel configs. 606 */ 607 bool writeTexturePixels(GrTexture* texture, 608 int left, int top, int width, int height, 609 GrPixelConfig config, const void* buffer, 610 size_t rowBytes, 611 uint32_t pixelOpsFlags = 0); 612 613 614 /** 615 * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle 616 * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's 617 * bounds. 618 * @param src the texture to copy from. 619 * @param dst the render target to copy to. 620 * @param topLeft the point in src that will be copied to the top-left of dst. If NULL, 621 * (0, 0) will be used. 622 */ 623 void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL); 624 625 /** 626 * Resolves a render target that has MSAA. The intermediate MSAA buffer is 627 * down-sampled to the associated GrTexture (accessible via 628 * GrRenderTarget::asTexture()). Any pending draws to the render target will 629 * be executed before the resolve. 630 * 631 * This is only necessary when a client wants to access the object directly 632 * using the backend API directly. GrContext will detect when it must 633 * perform a resolve to a GrTexture used as the source of a draw or before 634 * reading pixels back from a GrTexture or GrRenderTarget. 635 */ 636 void resolveRenderTarget(GrRenderTarget* target); 637 638#ifdef SK_DEVELOPER 639 void dumpFontCache() const; 640#endif 641 642 /////////////////////////////////////////////////////////////////////////// 643 // Helpers 644 645 class AutoRenderTarget : public ::SkNoncopyable { 646 public: 647 AutoRenderTarget(GrContext* context, GrRenderTarget* target) { 648 fPrevTarget = context->getRenderTarget(); 649 SkSafeRef(fPrevTarget); 650 context->setRenderTarget(target); 651 fContext = context; 652 } 653 AutoRenderTarget(GrContext* context) { 654 fPrevTarget = context->getRenderTarget(); 655 SkSafeRef(fPrevTarget); 656 fContext = context; 657 } 658 ~AutoRenderTarget() { 659 if (NULL != fContext) { 660 fContext->setRenderTarget(fPrevTarget); 661 } 662 SkSafeUnref(fPrevTarget); 663 } 664 private: 665 GrContext* fContext; 666 GrRenderTarget* fPrevTarget; 667 }; 668 669 /** 670 * Save/restore the view-matrix in the context. It can optionally adjust a paint to account 671 * for a coordinate system change. Here is an example of how the paint param can be used: 672 * 673 * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source 674 * geometry positions when the draw is executed. Later on a decision is made to transform the 675 * geometry to device space on the CPU. The effects now need to know that the space in which 676 * the geometry will be specified has changed. 677 * 678 * Note that when restore is called (or in the destructor) the context's matrix will be 679 * restored. However, the paint will not be restored. The caller must make a copy of the 680 * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally 681 * initialized. 682 */ 683 class AutoMatrix : public ::SkNoncopyable { 684 public: 685 AutoMatrix() : fContext(NULL) {} 686 687 ~AutoMatrix() { this->restore(); } 688 689 /** 690 * Initializes by pre-concat'ing the context's current matrix with the preConcat param. 691 */ 692 void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) { 693 SkASSERT(NULL != context); 694 695 this->restore(); 696 697 fContext = context; 698 fMatrix = context->getMatrix(); 699 this->preConcat(preConcat, paint); 700 } 701 702 /** 703 * Sets the context's matrix to identity. Returns false if the inverse matrix is required to 704 * update a paint but the matrix cannot be inverted. 705 */ 706 bool setIdentity(GrContext* context, GrPaint* paint = NULL) { 707 SkASSERT(NULL != context); 708 709 this->restore(); 710 711 if (NULL != paint) { 712 if (!paint->localCoordChangeInverse(context->getMatrix())) { 713 return false; 714 } 715 } 716 fMatrix = context->getMatrix(); 717 fContext = context; 718 context->setIdentityMatrix(); 719 return true; 720 } 721 722 /** 723 * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is 724 * required to update a paint but the matrix cannot be inverted. 725 */ 726 bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) { 727 if (NULL != paint) { 728 if (!this->setIdentity(context, paint)) { 729 return false; 730 } 731 this->preConcat(newMatrix, paint); 732 } else { 733 this->restore(); 734 fContext = context; 735 fMatrix = context->getMatrix(); 736 context->setMatrix(newMatrix); 737 } 738 return true; 739 } 740 741 /** 742 * If this has been initialized then the context's matrix will be further updated by 743 * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged. 744 * The paint is assumed to be relative to the context's matrix at the time this call is 745 * made, not the matrix at the time AutoMatrix was first initialized. In other words, this 746 * performs an incremental update of the paint. 747 */ 748 void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) { 749 if (NULL != paint) { 750 paint->localCoordChange(preConcat); 751 } 752 fContext->concatMatrix(preConcat); 753 } 754 755 /** 756 * Returns false if never initialized or the inverse matrix was required to update a paint 757 * but the matrix could not be inverted. 758 */ 759 bool succeeded() const { return NULL != fContext; } 760 761 /** 762 * If this has been initialized then the context's original matrix is restored. 763 */ 764 void restore() { 765 if (NULL != fContext) { 766 fContext->setMatrix(fMatrix); 767 fContext = NULL; 768 } 769 } 770 771 private: 772 GrContext* fContext; 773 SkMatrix fMatrix; 774 }; 775 776 class AutoClip : public ::SkNoncopyable { 777 public: 778 // This enum exists to require a caller of the constructor to acknowledge that the clip will 779 // initially be wide open. It also could be extended if there are other desirable initial 780 // clip states. 781 enum InitialClip { 782 kWideOpen_InitialClip, 783 }; 784 785 AutoClip(GrContext* context, InitialClip initialState) 786 : fContext(context) { 787 SkASSERT(kWideOpen_InitialClip == initialState); 788 fNewClipData.fClipStack = &fNewClipStack; 789 790 fOldClip = context->getClip(); 791 context->setClip(&fNewClipData); 792 } 793 794 AutoClip(GrContext* context, const SkRect& newClipRect) 795 : fContext(context) 796 , fNewClipStack(newClipRect) { 797 fNewClipData.fClipStack = &fNewClipStack; 798 799 fOldClip = fContext->getClip(); 800 fContext->setClip(&fNewClipData); 801 } 802 803 ~AutoClip() { 804 if (NULL != fContext) { 805 fContext->setClip(fOldClip); 806 } 807 } 808 private: 809 GrContext* fContext; 810 const GrClipData* fOldClip; 811 812 SkClipStack fNewClipStack; 813 GrClipData fNewClipData; 814 }; 815 816 class AutoWideOpenIdentityDraw { 817 public: 818 AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt) 819 : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip) 820 , fAutoRT(ctx, rt) { 821 fAutoMatrix.setIdentity(ctx); 822 // should never fail with no paint param. 823 SkASSERT(fAutoMatrix.succeeded()); 824 } 825 826 private: 827 AutoClip fAutoClip; 828 AutoRenderTarget fAutoRT; 829 AutoMatrix fAutoMatrix; 830 }; 831 832 /////////////////////////////////////////////////////////////////////////// 833 // Functions intended for internal use only. 834 GrGpu* getGpu() { return fGpu; } 835 const GrGpu* getGpu() const { return fGpu; } 836 GrFontCache* getFontCache() { return fFontCache; } 837 GrDrawTarget* getTextTarget(); 838 const GrIndexBuffer* getQuadIndexBuffer() const; 839 840 // Called by tests that draw directly to the context via GrDrawTarget 841 void getTestTarget(GrTestTarget*); 842 843 /** 844 * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is 845 * called to check the cache for a SB that matches an RT's criteria. 846 */ 847 void addStencilBuffer(GrStencilBuffer* sb); 848 GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt); 849 850 GrPathRenderer* getPathRenderer( 851 const SkPath& path, 852 const SkStrokeRec& stroke, 853 const GrDrawTarget* target, 854 bool allowSW, 855 GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, 856 GrPathRendererChain::StencilSupport* stencilSupport = NULL); 857 858 859#if GR_CACHE_STATS 860 void printCacheStats() const; 861#endif 862 863private: 864 // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer. 865 enum BufferedDraw { 866 kYes_BufferedDraw, 867 kNo_BufferedDraw, 868 }; 869 BufferedDraw fLastDrawWasBuffered; 870 871 GrGpu* fGpu; 872 SkMatrix fViewMatrix; 873 SkAutoTUnref<GrRenderTarget> fRenderTarget; 874 const GrClipData* fClip; // TODO: make this ref counted 875 GrDrawState* fDrawState; 876 877 GrResourceCache* fTextureCache; 878 GrFontCache* fFontCache; 879 880 GrPathRendererChain* fPathRendererChain; 881 GrSoftwarePathRenderer* fSoftwarePathRenderer; 882 883 GrVertexBufferAllocPool* fDrawBufferVBAllocPool; 884 GrIndexBufferAllocPool* fDrawBufferIBAllocPool; 885 GrInOrderDrawBuffer* fDrawBuffer; 886 887 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. 888 bool fFlushToReduceCacheSize; 889 890 GrAARectRenderer* fAARectRenderer; 891 GrOvalRenderer* fOvalRenderer; 892 893 bool fDidTestPMConversions; 894 int fPMToUPMConversion; 895 int fUPMToPMConversion; 896 897 struct CleanUpData { 898 PFCleanUpFunc fFunc; 899 void* fInfo; 900 }; 901 902 SkTDArray<CleanUpData> fCleanUpData; 903 904 int fMaxTextureSizeOverride; 905 906 GrContext(); // init must be called after the constructor. 907 bool init(GrBackend, GrBackendContext); 908 909 void setupDrawBuffer(); 910 911 class AutoRestoreEffects; 912 class AutoCheckFlush; 913 /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the 914 /// draw state is left unmodified. 915 GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*); 916 917 void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 918 const SkStrokeRec& stroke); 919 920 GrTexture* createResizedTexture(const GrTextureDesc& desc, 921 const GrCacheID& cacheID, 922 void* srcData, 923 size_t rowBytes, 924 bool filter); 925 926 // Needed so GrTexture's returnToCache helper function can call 927 // addExistingTextureToCache 928 friend class GrTexture; 929 friend class GrStencilAndCoverPathRenderer; 930 931 // Add an existing texture to the texture cache. This is intended solely 932 // for use with textures released from an GrAutoScratchTexture. 933 void addExistingTextureToCache(GrTexture* texture); 934 935 /** 936 * These functions create premul <-> unpremul effects if it is possible to generate a pair 937 * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they 938 * return NULL. 939 */ 940 const GrEffectRef* createPMToUPMEffect(GrTexture* texture, 941 bool swapRAndB, 942 const SkMatrix& matrix); 943 const GrEffectRef* createUPMToPMEffect(GrTexture* texture, 944 bool swapRAndB, 945 const SkMatrix& matrix); 946 947 /** 948 * This callback allows the resource cache to callback into the GrContext 949 * when the cache is still overbudget after a purge. 950 */ 951 static bool OverbudgetCB(void* data); 952 953 /** Creates a new gpu path, based on the specified path and stroke and returns it. 954 * The caller owns a ref on the returned path which must be balanced by a call to unref. 955 * 956 * @param skPath the path geometry. 957 * @param stroke the path stroke. 958 * @return a new path or NULL if the operation is not supported by the backend. 959 */ 960 GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke); 961 962 typedef SkRefCnt INHERITED; 963}; 964 965/** 966 * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria. 967 * Unlocks texture in the destructor. 968 */ 969class GrAutoScratchTexture : public ::SkNoncopyable { 970public: 971 GrAutoScratchTexture() 972 : fContext(NULL) 973 , fTexture(NULL) { 974 } 975 976 GrAutoScratchTexture(GrContext* context, 977 const GrTextureDesc& desc, 978 GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) 979 : fContext(NULL) 980 , fTexture(NULL) { 981 this->set(context, desc, match); 982 } 983 984 ~GrAutoScratchTexture() { 985 this->reset(); 986 } 987 988 void reset() { 989 if (NULL != fContext && NULL != fTexture) { 990 fContext->unlockScratchTexture(fTexture); 991 fTexture->unref(); 992 fTexture = NULL; 993 } 994 } 995 996 /* 997 * When detaching a texture we do not unlock it in the texture cache but 998 * we do set the returnToCache flag. In this way the texture remains 999 * "locked" in the texture cache until it is freed and recycled in 1000 * GrTexture::internal_dispose. In reality, the texture has been removed 1001 * from the cache (because this is in AutoScratchTexture) and by not 1002 * calling unlockScratchTexture we simply don't re-add it. It will be 1003 * reattached in GrTexture::internal_dispose. 1004 * 1005 * Note that the caller is assumed to accept and manage the ref to the 1006 * returned texture. 1007 */ 1008 GrTexture* detach() { 1009 if (NULL == fTexture) { 1010 return NULL; 1011 } 1012 GrTexture* texture = fTexture; 1013 fTexture = NULL; 1014 1015 // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now. 1016 // The cache also has a ref which we are lending to the caller of detach(). When the caller 1017 // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is 1018 // set and re-ref the texture, thereby restoring the cache's ref. 1019 SkASSERT(texture->getRefCnt() > 1); 1020 texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit); 1021 texture->unref(); 1022 SkASSERT(NULL != texture->getCacheEntry()); 1023 1024 return texture; 1025 } 1026 1027 GrTexture* set(GrContext* context, 1028 const GrTextureDesc& desc, 1029 GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) { 1030 this->reset(); 1031 1032 fContext = context; 1033 if (NULL != fContext) { 1034 fTexture = fContext->lockAndRefScratchTexture(desc, match); 1035 if (NULL == fTexture) { 1036 fContext = NULL; 1037 } 1038 return fTexture; 1039 } else { 1040 return NULL; 1041 } 1042 } 1043 1044 GrTexture* texture() { return fTexture; } 1045 1046private: 1047 GrContext* fContext; 1048 GrTexture* fTexture; 1049}; 1050 1051#endif 1052