| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 GrAssert(NULL == fGpu); | 108 GrAssert(NULL == fGpu); |
| 109 | 109 |
| 110 fGpu = GrGpu::Create(backend, backendContext, this); | 110 fGpu = GrGpu::Create(backend, backendContext, this); |
| 111 if (NULL == fGpu) { | 111 if (NULL == fGpu) { |
| 112 return false; | 112 return false; |
| 113 } | 113 } |
| 114 | 114 |
| 115 fDrawState = SkNEW(GrDrawState); | 115 fDrawState = SkNEW(GrDrawState); |
| 116 fGpu->setDrawState(fDrawState); | 116 fGpu->setDrawState(fDrawState); |
| 117 | 117 |
| 118 | |
| 119 fTextureCache = SkNEW_ARGS(GrResourceCache, | 118 fTextureCache = SkNEW_ARGS(GrResourceCache, |
| 120 (MAX_TEXTURE_CACHE_COUNT, | 119 (MAX_TEXTURE_CACHE_COUNT, |
| 121 MAX_TEXTURE_CACHE_BYTES)); | 120 MAX_TEXTURE_CACHE_BYTES)); |
| 122 fTextureCache->setOverbudgetCallback(OverbudgetCB, this); | 121 fTextureCache->setOverbudgetCallback(OverbudgetCB, this); |
| 123 | 122 |
| 124 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); | 123 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); |
| 125 | 124 |
| 126 fLastDrawWasBuffered = kNo_BufferedDraw; | 125 fLastDrawWasBuffered = kNo_BufferedDraw; |
| 127 | 126 |
| 128 fAARectRenderer = SkNEW(GrAARectRenderer); | 127 fAARectRenderer = SkNEW(GrAARectRenderer); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 if (NULL != texture) { | 391 if (NULL != texture) { |
| 393 // Adding a resource could put us overbudget. Try to free up the | 392 // Adding a resource could put us overbudget. Try to free up the |
| 394 // necessary space before adding it. | 393 // necessary space before adding it. |
| 395 fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); | 394 fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); |
| 396 fTextureCache->addResource(resourceKey, texture); | 395 fTextureCache->addResource(resourceKey, texture); |
| 397 } | 396 } |
| 398 | 397 |
| 399 return texture; | 398 return texture; |
| 400 } | 399 } |
| 401 | 400 |
| 401 static GrTexture* create_scratch_texture(GrGpu* gpu, |
| 402 GrResourceCache* textureCache, |
| 403 const GrTextureDesc& desc) { |
| 404 GrTexture* texture = gpu->createTexture(desc, NULL, 0); |
| 405 if (NULL != texture) { |
| 406 GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); |
| 407 // Adding a resource could put us overbudget. Try to free up the |
| 408 // necessary space before adding it. |
| 409 textureCache->purgeAsNeeded(1, texture->sizeInBytes()); |
| 410 // Make the resource exclusive so future 'find' calls don't return it |
| 411 textureCache->addResource(key, texture, GrResourceCache::kHide_Ownership
Flag); |
| 412 } |
| 413 return texture; |
| 414 } |
| 415 |
| 402 GrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, Scra
tchTexMatch match) { | 416 GrTexture* GrContext::lockAndRefScratchTexture(const GrTextureDesc& inDesc, Scra
tchTexMatch match) { |
| 417 |
| 418 GrAssert((inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || |
| 419 !(inDesc.fFlags & kNoStencil_GrTextureFlagBit)); |
| 420 |
| 421 // Renderable A8 targets are not universally supported (e.g., not on ANGLE) |
| 422 GrAssert(this->isConfigRenderable(kAlpha_8_GrPixelConfig) || |
| 423 !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) || |
| 424 (inDesc.fConfig != kAlpha_8_GrPixelConfig)); |
| 425 |
| 426 if (!fGpu->caps()->reuseScratchTextures()) { |
| 427 // If we're never recycling scratch textures we can |
| 428 // always make them the right size |
| 429 return create_scratch_texture(fGpu, fTextureCache, inDesc); |
| 430 } |
| 431 |
| 403 GrTextureDesc desc = inDesc; | 432 GrTextureDesc desc = inDesc; |
| 404 | 433 |
| 405 GrAssert((desc.fFlags & kRenderTarget_GrTextureFlagBit) || | |
| 406 !(desc.fFlags & kNoStencil_GrTextureFlagBit)); | |
| 407 | |
| 408 if (kApprox_ScratchTexMatch == match) { | 434 if (kApprox_ScratchTexMatch == match) { |
| 409 // bin by pow2 with a reasonable min | 435 // bin by pow2 with a reasonable min |
| 410 static const int MIN_SIZE = 16; | 436 static const int MIN_SIZE = 16; |
| 411 desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); | 437 desc.fWidth = GrMax(MIN_SIZE, GrNextPow2(desc.fWidth)); |
| 412 desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); | 438 desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight)); |
| 413 } | 439 } |
| 414 | 440 |
| 415 // Renderable A8 targets are not universally supported (e.g., not on ANGLE) | |
| 416 GrAssert(this->isConfigRenderable(kAlpha_8_GrPixelConfig) || | |
| 417 !(desc.fFlags & kRenderTarget_GrTextureFlagBit) || | |
| 418 (desc.fConfig != kAlpha_8_GrPixelConfig)); | |
| 419 | |
| 420 GrResource* resource = NULL; | 441 GrResource* resource = NULL; |
| 421 int origWidth = desc.fWidth; | 442 int origWidth = desc.fWidth; |
| 422 int origHeight = desc.fHeight; | 443 int origHeight = desc.fHeight; |
| 423 | 444 |
| 424 do { | 445 do { |
| 425 GrResourceKey key = GrTexture::ComputeScratchKey(desc); | 446 GrResourceKey key = GrTexture::ComputeScratchKey(desc); |
| 426 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it | 447 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it |
| 427 resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag
); | 448 resource = fTextureCache->find(key, GrResourceCache::kHide_OwnershipFlag
); |
| 428 if (NULL != resource) { | 449 if (NULL != resource) { |
| 429 resource->ref(); | 450 resource->ref(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 442 } else { | 463 } else { |
| 443 break; | 464 break; |
| 444 } | 465 } |
| 445 | 466 |
| 446 } while (true); | 467 } while (true); |
| 447 | 468 |
| 448 if (NULL == resource) { | 469 if (NULL == resource) { |
| 449 desc.fFlags = inDesc.fFlags; | 470 desc.fFlags = inDesc.fFlags; |
| 450 desc.fWidth = origWidth; | 471 desc.fWidth = origWidth; |
| 451 desc.fHeight = origHeight; | 472 desc.fHeight = origHeight; |
| 452 GrTexture* texture = fGpu->createTexture(desc, NULL, 0); | 473 resource = create_scratch_texture(fGpu, fTextureCache, desc); |
| 453 if (NULL != texture) { | |
| 454 GrResourceKey key = GrTexture::ComputeScratchKey(texture->desc()); | |
| 455 // Adding a resource could put us overbudget. Try to free up the | |
| 456 // necessary space before adding it. | |
| 457 fTextureCache->purgeAsNeeded(1, texture->sizeInBytes()); | |
| 458 // Make the resource exclusive so future 'find' calls don't return i
t | |
| 459 fTextureCache->addResource(key, texture, GrResourceCache::kHide_Owne
rshipFlag); | |
| 460 resource = texture; | |
| 461 } | |
| 462 } | 474 } |
| 463 | 475 |
| 464 return static_cast<GrTexture*>(resource); | 476 return static_cast<GrTexture*>(resource); |
| 465 } | 477 } |
| 466 | 478 |
| 467 void GrContext::addExistingTextureToCache(GrTexture* texture) { | 479 void GrContext::addExistingTextureToCache(GrTexture* texture) { |
| 468 | 480 |
| 469 if (NULL == texture) { | 481 if (NULL == texture) { |
| 470 return; | 482 return; |
| 471 } | 483 } |
| 472 | 484 |
| 473 // This texture should already have a cache entry since it was once | 485 // This texture should already have a cache entry since it was once |
| 474 // attached | 486 // attached |
| 475 GrAssert(NULL != texture->getCacheEntry()); | 487 GrAssert(NULL != texture->getCacheEntry()); |
| 476 | 488 |
| 477 // Conceptually, the cache entry is going to assume responsibility | 489 // Conceptually, the cache entry is going to assume responsibility |
| 478 // for the creation ref. | 490 // for the creation ref. |
| 479 GrAssert(1 == texture->getRefCnt()); | 491 GrAssert(1 == texture->getRefCnt()); |
| 480 | 492 |
| 481 // Since this texture came from an AutoScratchTexture it should | 493 // Since this texture came from an AutoScratchTexture it should |
| 482 // still be in the exclusive pile | 494 // still be in the exclusive pile |
| 483 fTextureCache->makeNonExclusive(texture->getCacheEntry()); | 495 fTextureCache->makeNonExclusive(texture->getCacheEntry()); |
| 484 | 496 |
| 485 this->purgeCache(); | 497 if (fGpu->caps()->reuseScratchTextures()) { |
| 498 this->purgeCache(); |
| 499 } else { |
| 500 // When we aren't reusing textures we know this scratch texture |
| 501 // will never be reused and would be just wasting time in the cache |
| 502 fTextureCache->deleteResource(texture->getCacheEntry()); |
| 503 } |
| 486 } | 504 } |
| 487 | 505 |
| 488 | 506 |
| 489 void GrContext::unlockScratchTexture(GrTexture* texture) { | 507 void GrContext::unlockScratchTexture(GrTexture* texture) { |
| 490 ASSERT_OWNED_RESOURCE(texture); | 508 ASSERT_OWNED_RESOURCE(texture); |
| 491 GrAssert(NULL != texture->getCacheEntry()); | 509 GrAssert(NULL != texture->getCacheEntry()); |
| 492 | 510 |
| 493 // If this is a scratch texture we detached it from the cache | 511 // If this is a scratch texture we detached it from the cache |
| 494 // while it was locked (to avoid two callers simultaneously getting | 512 // while it was locked (to avoid two callers simultaneously getting |
| 495 // the same texture). | 513 // the same texture). |
| 496 if (texture->getCacheEntry()->key().isScratch()) { | 514 if (texture->getCacheEntry()->key().isScratch()) { |
| 497 fTextureCache->makeNonExclusive(texture->getCacheEntry()); | 515 fTextureCache->makeNonExclusive(texture->getCacheEntry()); |
| 498 this->purgeCache(); | 516 this->purgeCache(); |
| 499 } | 517 } |
| 500 | |
| 501 } | 518 } |
| 502 | 519 |
| 503 void GrContext::purgeCache() { | 520 void GrContext::purgeCache() { |
| 504 if (NULL != fTextureCache) { | 521 if (NULL != fTextureCache) { |
| 505 fTextureCache->purgeAsNeeded(); | 522 fTextureCache->purgeAsNeeded(); |
| 506 } | 523 } |
| 507 } | 524 } |
| 508 | 525 |
| 509 bool GrContext::OverbudgetCB(void* data) { | 526 bool GrContext::OverbudgetCB(void* data) { |
| 510 GrAssert(NULL != data); | 527 GrAssert(NULL != data); |
| (...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 return NULL; | 1703 return NULL; |
| 1687 } | 1704 } |
| 1688 } | 1705 } |
| 1689 | 1706 |
| 1690 /////////////////////////////////////////////////////////////////////////////// | 1707 /////////////////////////////////////////////////////////////////////////////// |
| 1691 #if GR_CACHE_STATS | 1708 #if GR_CACHE_STATS |
| 1692 void GrContext::printCacheStats() const { | 1709 void GrContext::printCacheStats() const { |
| 1693 fTextureCache->printStats(); | 1710 fTextureCache->printStats(); |
| 1694 } | 1711 } |
| 1695 #endif | 1712 #endif |
| OLD | NEW |