| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; | 66 static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 1 << 11; |
| 67 static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; | 67 static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 4; |
| 68 | 68 |
| 69 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) | 69 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) |
| 70 | 70 |
| 71 // Glorified typedef to avoid including GrDrawState.h in GrContext.h | 71 // Glorified typedef to avoid including GrDrawState.h in GrContext.h |
| 72 class GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; | 72 class GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {}; |
| 73 | 73 |
| 74 class GrContext::AutoCheckFlush { | 74 class GrContext::AutoCheckFlush { |
| 75 public: | 75 public: |
| 76 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(NULL != co
ntext); } | 76 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context);
} |
| 77 | 77 |
| 78 ~AutoCheckFlush() { | 78 ~AutoCheckFlush() { |
| 79 if (fContext->fFlushToReduceCacheSize) { | 79 if (fContext->fFlushToReduceCacheSize) { |
| 80 fContext->flush(); | 80 fContext->flush(); |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 GrContext* fContext; | 85 GrContext* fContext; |
| 86 }; | 86 }; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 } | 213 } |
| 214 | 214 |
| 215 void GrContext::resetContext(uint32_t state) { | 215 void GrContext::resetContext(uint32_t state) { |
| 216 fGpu->markContextDirty(state); | 216 fGpu->markContextDirty(state); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void GrContext::freeGpuResources() { | 219 void GrContext::freeGpuResources() { |
| 220 this->flush(); | 220 this->flush(); |
| 221 | 221 |
| 222 fGpu->purgeResources(); | 222 fGpu->purgeResources(); |
| 223 if (NULL != fDrawBuffer) { | 223 if (fDrawBuffer) { |
| 224 fDrawBuffer->purgeResources(); | 224 fDrawBuffer->purgeResources(); |
| 225 } | 225 } |
| 226 | 226 |
| 227 fAARectRenderer->reset(); | 227 fAARectRenderer->reset(); |
| 228 fOvalRenderer->reset(); | 228 fOvalRenderer->reset(); |
| 229 | 229 |
| 230 fResourceCache->purgeAllUnlocked(); | 230 fResourceCache->purgeAllUnlocked(); |
| 231 fFontCache->freeAll(); | 231 fFontCache->freeAll(); |
| 232 fLayerCache->freeAll(); | 232 fLayerCache->freeAll(); |
| 233 // a path renderer may be holding onto resources | 233 // a path renderer may be holding onto resources |
| 234 SkSafeSetNull(fPathRendererChain); | 234 SkSafeSetNull(fPathRendererChain); |
| 235 SkSafeSetNull(fSoftwarePathRenderer); | 235 SkSafeSetNull(fSoftwarePathRenderer); |
| 236 } | 236 } |
| 237 | 237 |
| 238 void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes)
const { | 238 void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes)
const { |
| 239 if (NULL != resourceCount) { | 239 if (resourceCount) { |
| 240 *resourceCount = fResourceCache->getCachedResourceCount(); | 240 *resourceCount = fResourceCache->getCachedResourceCount(); |
| 241 } | 241 } |
| 242 if (NULL != resourceBytes) { | 242 if (resourceBytes) { |
| 243 *resourceBytes = fResourceCache->getCachedResourceBytes(); | 243 *resourceBytes = fResourceCache->getCachedResourceBytes(); |
| 244 } | 244 } |
| 245 } | 245 } |
| 246 | 246 |
| 247 GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, | 247 GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, |
| 248 const SkDeviceProperties& | 248 const SkDeviceProperties& |
| 249 leakyProperties, | 249 leakyProperties, |
| 250 bool enableDistanceFieldFonts) { | 250 bool enableDistanceFieldFonts) { |
| 251 if (fGpu->caps()->pathRenderingSupport()) { | 251 if (fGpu->caps()->pathRenderingSupport()) { |
| 252 if (renderTarget->getStencilBuffer() && renderTarget->isMultisampled())
{ | 252 if (renderTarget->getStencilBuffer() && renderTarget->isMultisampled())
{ |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 | 346 |
| 347 GrTextureDesc rtDesc = desc; | 347 GrTextureDesc rtDesc = desc; |
| 348 rtDesc.fFlags = rtDesc.fFlags | | 348 rtDesc.fFlags = rtDesc.fFlags | |
| 349 kRenderTarget_GrTextureFlagBit | | 349 kRenderTarget_GrTextureFlagBit | |
| 350 kNoStencil_GrTextureFlagBit; | 350 kNoStencil_GrTextureFlagBit; |
| 351 rtDesc.fWidth = GrNextPow2(desc.fWidth); | 351 rtDesc.fWidth = GrNextPow2(desc.fWidth); |
| 352 rtDesc.fHeight = GrNextPow2(desc.fHeight); | 352 rtDesc.fHeight = GrNextPow2(desc.fHeight); |
| 353 | 353 |
| 354 GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); | 354 GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); |
| 355 | 355 |
| 356 if (NULL != texture) { | 356 if (texture) { |
| 357 GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); | 357 GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); |
| 358 GrDrawState* drawState = fGpu->drawState(); | 358 GrDrawState* drawState = fGpu->drawState(); |
| 359 drawState->setRenderTarget(texture->asRenderTarget()); | 359 drawState->setRenderTarget(texture->asRenderTarget()); |
| 360 | 360 |
| 361 // if filtering is not desired then we want to ensure all | 361 // if filtering is not desired then we want to ensure all |
| 362 // texels in the resampled image are copies of texels from | 362 // texels in the resampled image are copies of texels from |
| 363 // the original. | 363 // the original. |
| 364 GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTexturePara
ms::kBilerp_FilterMode : | 364 GrTextureParams params(SkShader::kClamp_TileMode, filter ? GrTexturePara
ms::kBilerp_FilterMode : |
| 365 GrTexturePara
ms::kNone_FilterMode); | 365 GrTexturePara
ms::kNone_FilterMode); |
| 366 drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); | 366 drawState->addColorTextureEffect(clampedTexture, SkMatrix::I(), params); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 391 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); | 391 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); |
| 392 | 392 |
| 393 size_t bpp = GrBytesPerPixel(desc.fConfig); | 393 size_t bpp = GrBytesPerPixel(desc.fConfig); |
| 394 GrAutoMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHe
ight); | 394 GrAutoMalloc<128*128*4> stretchedPixels(bpp * rtDesc.fWidth * rtDesc.fHe
ight); |
| 395 stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, | 395 stretch_image(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, |
| 396 srcData, desc.fWidth, desc.fHeight, bpp); | 396 srcData, desc.fWidth, desc.fHeight, bpp); |
| 397 | 397 |
| 398 size_t stretchedRowBytes = rtDesc.fWidth * bpp; | 398 size_t stretchedRowBytes = rtDesc.fWidth * bpp; |
| 399 | 399 |
| 400 texture = fGpu->createTexture(rtDesc, stretchedPixels.get(), stretchedRo
wBytes); | 400 texture = fGpu->createTexture(rtDesc, stretchedPixels.get(), stretchedRo
wBytes); |
| 401 SkASSERT(NULL != texture); | 401 SkASSERT(texture); |
| 402 } | 402 } |
| 403 | 403 |
| 404 return texture; | 404 return texture; |
| 405 } | 405 } |
| 406 | 406 |
| 407 GrTexture* GrContext::createTexture(const GrTextureParams* params, | 407 GrTexture* GrContext::createTexture(const GrTextureParams* params, |
| 408 const GrTextureDesc& desc, | 408 const GrTextureDesc& desc, |
| 409 const GrCacheID& cacheID, | 409 const GrCacheID& cacheID, |
| 410 const void* srcData, | 410 const void* srcData, |
| 411 size_t rowBytes, | 411 size_t rowBytes, |
| 412 GrResourceKey* cacheKey) { | 412 GrResourceKey* cacheKey) { |
| 413 GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, ca
cheID); | 413 GrResourceKey resourceKey = GrTextureImpl::ComputeKey(fGpu, params, desc, ca
cheID); |
| 414 | 414 |
| 415 GrTexture* texture; | 415 GrTexture* texture; |
| 416 if (GrTextureImpl::NeedsResizing(resourceKey)) { | 416 if (GrTextureImpl::NeedsResizing(resourceKey)) { |
| 417 // We do not know how to resize compressed textures. | 417 // We do not know how to resize compressed textures. |
| 418 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); | 418 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig)); |
| 419 | 419 |
| 420 texture = this->createResizedTexture(desc, cacheID, | 420 texture = this->createResizedTexture(desc, cacheID, |
| 421 srcData, rowBytes, | 421 srcData, rowBytes, |
| 422 GrTextureImpl::NeedsBilerp(resource
Key)); | 422 GrTextureImpl::NeedsBilerp(resource
Key)); |
| 423 } else { | 423 } else { |
| 424 texture = fGpu->createTexture(desc, srcData, rowBytes); | 424 texture = fGpu->createTexture(desc, srcData, rowBytes); |
| 425 } | 425 } |
| 426 | 426 |
| 427 if (NULL != texture) { | 427 if (texture) { |
| 428 // Adding a resource could put us overbudget. Try to free up the | 428 // Adding a resource could put us overbudget. Try to free up the |
| 429 // necessary space before adding it. | 429 // necessary space before adding it. |
| 430 fResourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); | 430 fResourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); |
| 431 fResourceCache->addResource(resourceKey, texture); | 431 fResourceCache->addResource(resourceKey, texture); |
| 432 | 432 |
| 433 if (NULL != cacheKey) { | 433 if (cacheKey) { |
| 434 *cacheKey = resourceKey; | 434 *cacheKey = resourceKey; |
| 435 } | 435 } |
| 436 } | 436 } |
| 437 | 437 |
| 438 return texture; | 438 return texture; |
| 439 } | 439 } |
| 440 | 440 |
| 441 static GrTexture* create_scratch_texture(GrGpu* gpu, | 441 static GrTexture* create_scratch_texture(GrGpu* gpu, |
| 442 GrResourceCache* resourceCache, | 442 GrResourceCache* resourceCache, |
| 443 const GrTextureDesc& desc) { | 443 const GrTextureDesc& desc) { |
| 444 GrTexture* texture = gpu->createTexture(desc, NULL, 0); | 444 GrTexture* texture = gpu->createTexture(desc, NULL, 0); |
| 445 if (NULL != texture) { | 445 if (texture) { |
| 446 GrResourceKey key = GrTextureImpl::ComputeScratchKey(texture->desc()); | 446 GrResourceKey key = GrTextureImpl::ComputeScratchKey(texture->desc()); |
| 447 // Adding a resource could put us overbudget. Try to free up the | 447 // Adding a resource could put us overbudget. Try to free up the |
| 448 // necessary space before adding it. | 448 // necessary space before adding it. |
| 449 resourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); | 449 resourceCache->purgeAsNeeded(1, texture->gpuMemorySize()); |
| 450 // Make the resource exclusive so future 'find' calls don't return it | 450 // Make the resource exclusive so future 'find' calls don't return it |
| 451 resourceCache->addResource(key, texture, GrResourceCache::kHide_Ownershi
pFlag); | 451 resourceCache->addResource(key, texture, GrResourceCache::kHide_Ownershi
pFlag); |
| 452 } | 452 } |
| 453 return texture; | 453 return texture; |
| 454 } | 454 } |
| 455 | 455 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 479 } | 479 } |
| 480 | 480 |
| 481 GrGpuResource* resource = NULL; | 481 GrGpuResource* resource = NULL; |
| 482 int origWidth = desc.fWidth; | 482 int origWidth = desc.fWidth; |
| 483 int origHeight = desc.fHeight; | 483 int origHeight = desc.fHeight; |
| 484 | 484 |
| 485 do { | 485 do { |
| 486 GrResourceKey key = GrTextureImpl::ComputeScratchKey(desc); | 486 GrResourceKey key = GrTextureImpl::ComputeScratchKey(desc); |
| 487 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it | 487 // Ensure we have exclusive access to the texture so future 'find' calls
don't return it |
| 488 resource = fResourceCache->find(key, GrResourceCache::kHide_OwnershipFla
g); | 488 resource = fResourceCache->find(key, GrResourceCache::kHide_OwnershipFla
g); |
| 489 if (NULL != resource) { | 489 if (resource) { |
| 490 resource->ref(); | 490 resource->ref(); |
| 491 break; | 491 break; |
| 492 } | 492 } |
| 493 if (kExact_ScratchTexMatch == match) { | 493 if (kExact_ScratchTexMatch == match) { |
| 494 break; | 494 break; |
| 495 } | 495 } |
| 496 // We had a cache miss and we are in approx mode, relax the fit of the f
lags. | 496 // We had a cache miss and we are in approx mode, relax the fit of the f
lags. |
| 497 | 497 |
| 498 // We no longer try to reuse textures that were previously used as rende
r targets in | 498 // We no longer try to reuse textures that were previously used as rende
r targets in |
| 499 // situations where no RT is needed; doing otherwise can confuse the vid
eo driver and | 499 // situations where no RT is needed; doing otherwise can confuse the vid
eo driver and |
| (...skipping 17 matching lines...) Expand all Loading... |
| 517 } | 517 } |
| 518 | 518 |
| 519 void GrContext::addExistingTextureToCache(GrTexture* texture) { | 519 void GrContext::addExistingTextureToCache(GrTexture* texture) { |
| 520 | 520 |
| 521 if (NULL == texture) { | 521 if (NULL == texture) { |
| 522 return; | 522 return; |
| 523 } | 523 } |
| 524 | 524 |
| 525 // This texture should already have a cache entry since it was once | 525 // This texture should already have a cache entry since it was once |
| 526 // attached | 526 // attached |
| 527 SkASSERT(NULL != texture->getCacheEntry()); | 527 SkASSERT(texture->getCacheEntry()); |
| 528 | 528 |
| 529 // Conceptually, the cache entry is going to assume responsibility | 529 // Conceptually, the cache entry is going to assume responsibility |
| 530 // for the creation ref. Assert refcnt == 1. | 530 // for the creation ref. Assert refcnt == 1. |
| 531 // Except that this also gets called when the texture is prematurely | 531 // Except that this also gets called when the texture is prematurely |
| 532 // abandoned. In that case the ref count may be > 1. | 532 // abandoned. In that case the ref count may be > 1. |
| 533 // SkASSERT(texture->unique()); | 533 // SkASSERT(texture->unique()); |
| 534 | 534 |
| 535 if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget(
)) { | 535 if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) { |
| 536 // Since this texture came from an AutoScratchTexture it should | 536 // Since this texture came from an AutoScratchTexture it should |
| 537 // still be in the exclusive pile. Recycle it. | 537 // still be in the exclusive pile. Recycle it. |
| 538 fResourceCache->makeNonExclusive(texture->getCacheEntry()); | 538 fResourceCache->makeNonExclusive(texture->getCacheEntry()); |
| 539 this->purgeCache(); | 539 this->purgeCache(); |
| 540 } else { | 540 } else { |
| 541 // When we aren't reusing textures we know this scratch texture | 541 // When we aren't reusing textures we know this scratch texture |
| 542 // will never be reused and would be just wasting time in the cache | 542 // will never be reused and would be just wasting time in the cache |
| 543 fResourceCache->makeNonExclusive(texture->getCacheEntry()); | 543 fResourceCache->makeNonExclusive(texture->getCacheEntry()); |
| 544 fResourceCache->deleteResource(texture->getCacheEntry()); | 544 fResourceCache->deleteResource(texture->getCacheEntry()); |
| 545 } | 545 } |
| 546 } | 546 } |
| 547 | 547 |
| 548 void GrContext::unlockScratchTexture(GrTexture* texture) { | 548 void GrContext::unlockScratchTexture(GrTexture* texture) { |
| 549 if (texture->wasDestroyed()) { | 549 if (texture->wasDestroyed()) { |
| 550 if (texture->getCacheEntry()->key().isScratch()) { | 550 if (texture->getCacheEntry()->key().isScratch()) { |
| 551 // This texture was detached from the cache but the cache still had
a ref to it but | 551 // This texture was detached from the cache but the cache still had
a ref to it but |
| 552 // not a pointer to it. This will unref the texture and delete its r
esource cache | 552 // not a pointer to it. This will unref the texture and delete its r
esource cache |
| 553 // entry. | 553 // entry. |
| 554 delete texture->getCacheEntry(); | 554 delete texture->getCacheEntry(); |
| 555 } | 555 } |
| 556 return; | 556 return; |
| 557 } | 557 } |
| 558 | 558 |
| 559 ASSERT_OWNED_RESOURCE(texture); | 559 ASSERT_OWNED_RESOURCE(texture); |
| 560 SkASSERT(NULL != texture->getCacheEntry()); | 560 SkASSERT(texture->getCacheEntry()); |
| 561 | 561 |
| 562 // If this is a scratch texture we detached it from the cache | 562 // If this is a scratch texture we detached it from the cache |
| 563 // while it was locked (to avoid two callers simultaneously getting | 563 // while it was locked (to avoid two callers simultaneously getting |
| 564 // the same texture). | 564 // the same texture). |
| 565 if (texture->getCacheEntry()->key().isScratch()) { | 565 if (texture->getCacheEntry()->key().isScratch()) { |
| 566 if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTar
get()) { | 566 if (fGpu->caps()->reuseScratchTextures() || texture->asRenderTarget()) { |
| 567 fResourceCache->makeNonExclusive(texture->getCacheEntry()); | 567 fResourceCache->makeNonExclusive(texture->getCacheEntry()); |
| 568 this->purgeCache(); | 568 this->purgeCache(); |
| 569 } else if (texture->unique()) { | 569 } else if (texture->unique()) { |
| 570 // Only the cache now knows about this texture. Since we're never | 570 // Only the cache now knows about this texture. Since we're never |
| 571 // reusing scratch textures (in this code path) it would just be | 571 // reusing scratch textures (in this code path) it would just be |
| 572 // wasting time sitting in the cache. | 572 // wasting time sitting in the cache. |
| 573 fResourceCache->makeNonExclusive(texture->getCacheEntry()); | 573 fResourceCache->makeNonExclusive(texture->getCacheEntry()); |
| 574 fResourceCache->deleteResource(texture->getCacheEntry()); | 574 fResourceCache->deleteResource(texture->getCacheEntry()); |
| 575 } else { | 575 } else { |
| 576 // In this case (there is still a non-cache ref) but we don't really | 576 // In this case (there is still a non-cache ref) but we don't really |
| 577 // want to readd it to the cache (since it will never be reused). | 577 // want to readd it to the cache (since it will never be reused). |
| 578 // Instead, give up the cache's ref and leave the decision up to | 578 // Instead, give up the cache's ref and leave the decision up to |
| 579 // addExistingTextureToCache once its ref count reaches 0. For | 579 // addExistingTextureToCache once its ref count reaches 0. For |
| 580 // this to work we need to leave it in the exclusive list. | 580 // this to work we need to leave it in the exclusive list. |
| 581 texture->impl()->setFlag((GrTextureFlags) GrTextureImpl::kReturnToCa
che_FlagBit); | 581 texture->impl()->setFlag((GrTextureFlags) GrTextureImpl::kReturnToCa
che_FlagBit); |
| 582 // Give up the cache's ref to the texture | 582 // Give up the cache's ref to the texture |
| 583 texture->unref(); | 583 texture->unref(); |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 } | 586 } |
| 587 | 587 |
| 588 void GrContext::purgeCache() { | 588 void GrContext::purgeCache() { |
| 589 if (NULL != fResourceCache) { | 589 if (fResourceCache) { |
| 590 fResourceCache->purgeAsNeeded(); | 590 fResourceCache->purgeAsNeeded(); |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 | 593 |
| 594 bool GrContext::OverbudgetCB(void* data) { | 594 bool GrContext::OverbudgetCB(void* data) { |
| 595 SkASSERT(NULL != data); | 595 SkASSERT(data); |
| 596 | 596 |
| 597 GrContext* context = reinterpret_cast<GrContext*>(data); | 597 GrContext* context = reinterpret_cast<GrContext*>(data); |
| 598 | 598 |
| 599 // Flush the InOrderDrawBuffer to possibly free up some textures | 599 // Flush the InOrderDrawBuffer to possibly free up some textures |
| 600 context->fFlushToReduceCacheSize = true; | 600 context->fFlushToReduceCacheSize = true; |
| 601 | 601 |
| 602 return true; | 602 return true; |
| 603 } | 603 } |
| 604 | 604 |
| 605 | 605 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, | 645 bool GrContext::supportsIndex8PixelConfig(const GrTextureParams* params, |
| 646 int width, int height) const { | 646 int width, int height) const { |
| 647 const GrDrawTargetCaps* caps = fGpu->caps(); | 647 const GrDrawTargetCaps* caps = fGpu->caps(); |
| 648 if (!caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { | 648 if (!caps->isConfigTexturable(kIndex_8_GrPixelConfig)) { |
| 649 return false; | 649 return false; |
| 650 } | 650 } |
| 651 | 651 |
| 652 bool isPow2 = SkIsPow2(width) && SkIsPow2(height); | 652 bool isPow2 = SkIsPow2(width) && SkIsPow2(height); |
| 653 | 653 |
| 654 if (!isPow2) { | 654 if (!isPow2) { |
| 655 bool tiled = NULL != params && params->isTiled(); | 655 bool tiled = params && params->isTiled(); |
| 656 if (tiled && !caps->npotTextureTileSupport()) { | 656 if (tiled && !caps->npotTextureTileSupport()) { |
| 657 return false; | 657 return false; |
| 658 } | 658 } |
| 659 } | 659 } |
| 660 return true; | 660 return true; |
| 661 } | 661 } |
| 662 | 662 |
| 663 | 663 |
| 664 //////////////////////////////////////////////////////////////////////////////// | 664 //////////////////////////////////////////////////////////////////////////////// |
| 665 | 665 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 } | 788 } |
| 789 | 789 |
| 790 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { | 790 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { |
| 791 return point.fX >= rect.fLeft && point.fX <= rect.fRight && | 791 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
| 792 point.fY >= rect.fTop && point.fY <= rect.fBottom; | 792 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
| 793 } | 793 } |
| 794 | 794 |
| 795 void GrContext::drawRect(const GrPaint& paint, | 795 void GrContext::drawRect(const GrPaint& paint, |
| 796 const SkRect& rect, | 796 const SkRect& rect, |
| 797 const GrStrokeInfo* strokeInfo) { | 797 const GrStrokeInfo* strokeInfo) { |
| 798 if (NULL != strokeInfo && strokeInfo->isDashed()) { | 798 if (strokeInfo && strokeInfo->isDashed()) { |
| 799 SkPath path; | 799 SkPath path; |
| 800 path.addRect(rect); | 800 path.addRect(rect); |
| 801 this->drawPath(paint, path, *strokeInfo); | 801 this->drawPath(paint, path, *strokeInfo); |
| 802 return; | 802 return; |
| 803 } | 803 } |
| 804 | 804 |
| 805 AutoRestoreEffects are; | 805 AutoRestoreEffects are; |
| 806 AutoCheckFlush acf(this); | 806 AutoCheckFlush acf(this); |
| 807 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf
); | 807 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf
); |
| 808 if (NULL == target) { | 808 if (NULL == target) { |
| 809 return; | 809 return; |
| 810 } | 810 } |
| 811 | 811 |
| 812 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); | 812 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); |
| 813 SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWid
th(); | 813 SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWid
th(); |
| 814 SkMatrix matrix = target->drawState()->getViewMatrix(); | 814 SkMatrix matrix = target->drawState()->getViewMatrix(); |
| 815 | 815 |
| 816 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking | 816 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
| 817 // cases where the RT is fully inside a stroke. | 817 // cases where the RT is fully inside a stroke. |
| 818 if (width < 0) { | 818 if (width < 0) { |
| 819 SkRect rtRect; | 819 SkRect rtRect; |
| 820 target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); | 820 target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); |
| 821 SkRect clipSpaceRTRect = rtRect; | 821 SkRect clipSpaceRTRect = rtRect; |
| 822 bool checkClip = false; | 822 bool checkClip = false; |
| 823 if (NULL != this->getClip()) { | 823 if (this->getClip()) { |
| 824 checkClip = true; | 824 checkClip = true; |
| 825 clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), | 825 clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), |
| 826 SkIntToScalar(this->getClip()->fOrigin.fY)); | 826 SkIntToScalar(this->getClip()->fOrigin.fY)); |
| 827 } | 827 } |
| 828 // Does the clip contain the entire RT? | 828 // Does the clip contain the entire RT? |
| 829 if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpace
RTRect)) { | 829 if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpace
RTRect)) { |
| 830 SkMatrix invM; | 830 SkMatrix invM; |
| 831 if (!matrix.invert(&invM)) { | 831 if (!matrix.invert(&invM)) { |
| 832 return; | 832 return; |
| 833 } | 833 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 static const size_t kPosColorAttribsSize = sizeof(SkPoint) + sizeof(GrColor); | 948 static const size_t kPosColorAttribsSize = sizeof(SkPoint) + sizeof(GrColor); |
| 949 | 949 |
| 950 static void set_vertex_attributes(GrDrawState* drawState, | 950 static void set_vertex_attributes(GrDrawState* drawState, |
| 951 const SkPoint* texCoords, | 951 const SkPoint* texCoords, |
| 952 const GrColor* colors, | 952 const GrColor* colors, |
| 953 int* colorOffset, | 953 int* colorOffset, |
| 954 int* texOffset) { | 954 int* texOffset) { |
| 955 *texOffset = -1; | 955 *texOffset = -1; |
| 956 *colorOffset = -1; | 956 *colorOffset = -1; |
| 957 | 957 |
| 958 if (NULL != texCoords && NULL != colors) { | 958 if (texCoords && colors) { |
| 959 *texOffset = sizeof(SkPoint); | 959 *texOffset = sizeof(SkPoint); |
| 960 *colorOffset = 2*sizeof(SkPoint); | 960 *colorOffset = 2*sizeof(SkPoint); |
| 961 drawState->setVertexAttribs<gPosUVColorAttribs>(3, kPosUVColorAttribsSiz
e); | 961 drawState->setVertexAttribs<gPosUVColorAttribs>(3, kPosUVColorAttribsSiz
e); |
| 962 } else if (NULL != texCoords) { | 962 } else if (texCoords) { |
| 963 *texOffset = sizeof(SkPoint); | 963 *texOffset = sizeof(SkPoint); |
| 964 drawState->setVertexAttribs<gPosUVColorAttribs>(2, kPosUVAttribsSize); | 964 drawState->setVertexAttribs<gPosUVColorAttribs>(2, kPosUVAttribsSize); |
| 965 } else if (NULL != colors) { | 965 } else if (colors) { |
| 966 *colorOffset = sizeof(SkPoint); | 966 *colorOffset = sizeof(SkPoint); |
| 967 drawState->setVertexAttribs<gPosColorAttribs>(2, kPosColorAttribsSize); | 967 drawState->setVertexAttribs<gPosColorAttribs>(2, kPosColorAttribsSize); |
| 968 } else { | 968 } else { |
| 969 drawState->setVertexAttribs<gPosColorAttribs>(1, kPosAttribsSize); | 969 drawState->setVertexAttribs<gPosColorAttribs>(1, kPosAttribsSize); |
| 970 } | 970 } |
| 971 } | 971 } |
| 972 | 972 |
| 973 }; | 973 }; |
| 974 | 974 |
| 975 void GrContext::drawVertices(const GrPaint& paint, | 975 void GrContext::drawVertices(const GrPaint& paint, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 } | 1014 } |
| 1015 curVertex = (void*)((intptr_t)curVertex + VertexStride); | 1015 curVertex = (void*)((intptr_t)curVertex + VertexStride); |
| 1016 } | 1016 } |
| 1017 } else { | 1017 } else { |
| 1018 target->setVertexSourceToArray(positions, vertexCount); | 1018 target->setVertexSourceToArray(positions, vertexCount); |
| 1019 } | 1019 } |
| 1020 | 1020 |
| 1021 // we don't currently apply offscreen AA to this path. Need improved | 1021 // we don't currently apply offscreen AA to this path. Need improved |
| 1022 // management of GrDrawTarget's geometry to avoid copying points per-tile. | 1022 // management of GrDrawTarget's geometry to avoid copying points per-tile. |
| 1023 | 1023 |
| 1024 if (NULL != indices) { | 1024 if (indices) { |
| 1025 target->setIndexSourceToArray(indices, indexCount); | 1025 target->setIndexSourceToArray(indices, indexCount); |
| 1026 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); | 1026 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); |
| 1027 target->resetIndexSource(); | 1027 target->resetIndexSource(); |
| 1028 } else { | 1028 } else { |
| 1029 target->drawNonIndexed(primitiveType, 0, vertexCount); | 1029 target->drawNonIndexed(primitiveType, 0, vertexCount); |
| 1030 } | 1030 } |
| 1031 } | 1031 } |
| 1032 | 1032 |
| 1033 /////////////////////////////////////////////////////////////////////////////// | 1033 /////////////////////////////////////////////////////////////////////////////// |
| 1034 | 1034 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 fFlushToReduceCacheSize = false; | 1331 fFlushToReduceCacheSize = false; |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 bool GrContext::writeTexturePixels(GrTexture* texture, | 1334 bool GrContext::writeTexturePixels(GrTexture* texture, |
| 1335 int left, int top, int width, int height, | 1335 int left, int top, int width, int height, |
| 1336 GrPixelConfig config, const void* buffer, siz
e_t rowBytes, | 1336 GrPixelConfig config, const void* buffer, siz
e_t rowBytes, |
| 1337 uint32_t flags) { | 1337 uint32_t flags) { |
| 1338 ASSERT_OWNED_RESOURCE(texture); | 1338 ASSERT_OWNED_RESOURCE(texture); |
| 1339 | 1339 |
| 1340 if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture
, config)) { | 1340 if ((kUnpremul_PixelOpsFlag & flags) || !fGpu->canWriteTexturePixels(texture
, config)) { |
| 1341 if (NULL != texture->asRenderTarget()) { | 1341 if (texture->asRenderTarget()) { |
| 1342 return this->writeRenderTargetPixels(texture->asRenderTarget(), | 1342 return this->writeRenderTargetPixels(texture->asRenderTarget(), |
| 1343 left, top, width, height, | 1343 left, top, width, height, |
| 1344 config, buffer, rowBytes, flags
); | 1344 config, buffer, rowBytes, flags
); |
| 1345 } else { | 1345 } else { |
| 1346 return false; | 1346 return false; |
| 1347 } | 1347 } |
| 1348 } | 1348 } |
| 1349 | 1349 |
| 1350 if (!(kDontFlush_PixelOpsFlag & flags)) { | 1350 if (!(kDontFlush_PixelOpsFlag & flags)) { |
| 1351 this->flush(); | 1351 this->flush(); |
| 1352 } | 1352 } |
| 1353 | 1353 |
| 1354 return fGpu->writeTexturePixels(texture, left, top, width, height, | 1354 return fGpu->writeTexturePixels(texture, left, top, width, height, |
| 1355 config, buffer, rowBytes); | 1355 config, buffer, rowBytes); |
| 1356 } | 1356 } |
| 1357 | 1357 |
| 1358 bool GrContext::readTexturePixels(GrTexture* texture, | 1358 bool GrContext::readTexturePixels(GrTexture* texture, |
| 1359 int left, int top, int width, int height, | 1359 int left, int top, int width, int height, |
| 1360 GrPixelConfig config, void* buffer, size_t row
Bytes, | 1360 GrPixelConfig config, void* buffer, size_t row
Bytes, |
| 1361 uint32_t flags) { | 1361 uint32_t flags) { |
| 1362 ASSERT_OWNED_RESOURCE(texture); | 1362 ASSERT_OWNED_RESOURCE(texture); |
| 1363 | 1363 |
| 1364 GrRenderTarget* target = texture->asRenderTarget(); | 1364 GrRenderTarget* target = texture->asRenderTarget(); |
| 1365 if (NULL != target) { | 1365 if (target) { |
| 1366 return this->readRenderTargetPixels(target, | 1366 return this->readRenderTargetPixels(target, |
| 1367 left, top, width, height, | 1367 left, top, width, height, |
| 1368 config, buffer, rowBytes, | 1368 config, buffer, rowBytes, |
| 1369 flags); | 1369 flags); |
| 1370 } else { | 1370 } else { |
| 1371 // TODO: make this more efficient for cases where we're reading the enti
re | 1371 // TODO: make this more efficient for cases where we're reading the enti
re |
| 1372 // texture, i.e., use GetTexImage() instead | 1372 // texture, i.e., use GetTexImage() instead |
| 1373 | 1373 |
| 1374 // create scratch rendertarget and read from that | 1374 // create scratch rendertarget and read from that |
| 1375 GrAutoScratchTexture ast; | 1375 GrAutoScratchTexture ast; |
| 1376 GrTextureDesc desc; | 1376 GrTextureDesc desc; |
| 1377 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1377 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1378 desc.fWidth = width; | 1378 desc.fWidth = width; |
| 1379 desc.fHeight = height; | 1379 desc.fHeight = height; |
| 1380 desc.fConfig = config; | 1380 desc.fConfig = config; |
| 1381 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 1381 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 1382 ast.set(this, desc, kExact_ScratchTexMatch); | 1382 ast.set(this, desc, kExact_ScratchTexMatch); |
| 1383 GrTexture* dst = ast.texture(); | 1383 GrTexture* dst = ast.texture(); |
| 1384 if (NULL != dst && NULL != (target = dst->asRenderTarget())) { | 1384 if (dst && (target = dst->asRenderTarget())) { |
| 1385 this->copyTexture(texture, target, NULL); | 1385 this->copyTexture(texture, target, NULL); |
| 1386 return this->readRenderTargetPixels(target, | 1386 return this->readRenderTargetPixels(target, |
| 1387 left, top, width, height, | 1387 left, top, width, height, |
| 1388 config, buffer, rowBytes, | 1388 config, buffer, rowBytes, |
| 1389 flags); | 1389 flags); |
| 1390 } | 1390 } |
| 1391 | 1391 |
| 1392 return false; | 1392 return false; |
| 1393 } | 1393 } |
| 1394 } | 1394 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 // The unpremul flag is only allowed for these two configs. | 1448 // The unpremul flag is only allowed for these two configs. |
| 1449 return false; | 1449 return false; |
| 1450 } | 1450 } |
| 1451 | 1451 |
| 1452 // If the src is a texture and we would have to do conversions after read pi
xels, we instead | 1452 // If the src is a texture and we would have to do conversions after read pi
xels, we instead |
| 1453 // do the conversions by drawing the src to a scratch texture. If we handle
any of the | 1453 // do the conversions by drawing the src to a scratch texture. If we handle
any of the |
| 1454 // conversions in the draw we set the corresponding bool to false so that we
don't reapply it | 1454 // conversions in the draw we set the corresponding bool to false so that we
don't reapply it |
| 1455 // on the read back pixels. | 1455 // on the read back pixels. |
| 1456 GrTexture* src = target->asTexture(); | 1456 GrTexture* src = target->asTexture(); |
| 1457 GrAutoScratchTexture ast; | 1457 GrAutoScratchTexture ast; |
| 1458 if (NULL != src && (swapRAndB || unpremul || flipY)) { | 1458 if (src && (swapRAndB || unpremul || flipY)) { |
| 1459 // Make the scratch a render target because we don't have a robust readT
exturePixels as of | 1459 // Make the scratch a render target because we don't have a robust readT
exturePixels as of |
| 1460 // yet. It calls this function. | 1460 // yet. It calls this function. |
| 1461 GrTextureDesc desc; | 1461 GrTextureDesc desc; |
| 1462 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1462 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1463 desc.fWidth = width; | 1463 desc.fWidth = width; |
| 1464 desc.fHeight = height; | 1464 desc.fHeight = height; |
| 1465 desc.fConfig = readConfig; | 1465 desc.fConfig = readConfig; |
| 1466 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 1466 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 1467 | 1467 |
| 1468 // When a full read back is faster than a partial we could always make t
he scratch exactly | 1468 // When a full read back is faster than a partial we could always make t
he scratch exactly |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1481 GrTexture* texture = ast.texture(); | 1481 GrTexture* texture = ast.texture(); |
| 1482 if (texture) { | 1482 if (texture) { |
| 1483 // compute a matrix to perform the draw | 1483 // compute a matrix to perform the draw |
| 1484 SkMatrix textureMatrix; | 1484 SkMatrix textureMatrix; |
| 1485 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); | 1485 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); |
| 1486 textureMatrix.postIDiv(src->width(), src->height()); | 1486 textureMatrix.postIDiv(src->width(), src->height()); |
| 1487 | 1487 |
| 1488 SkAutoTUnref<const GrEffect> effect; | 1488 SkAutoTUnref<const GrEffect> effect; |
| 1489 if (unpremul) { | 1489 if (unpremul) { |
| 1490 effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMa
trix)); | 1490 effect.reset(this->createPMToUPMEffect(src, swapRAndB, textureMa
trix)); |
| 1491 if (NULL != effect) { | 1491 if (effect) { |
| 1492 unpremul = false; // we no longer need to do this on CPU aft
er the read back. | 1492 unpremul = false; // we no longer need to do this on CPU aft
er the read back. |
| 1493 } | 1493 } |
| 1494 } | 1494 } |
| 1495 // If we failed to create a PM->UPM effect and have no other convers
ions to perform then | 1495 // If we failed to create a PM->UPM effect and have no other convers
ions to perform then |
| 1496 // there is no longer any point to using the scratch. | 1496 // there is no longer any point to using the scratch. |
| 1497 if (NULL != effect || flipY || swapRAndB) { | 1497 if (effect || flipY || swapRAndB) { |
| 1498 if (!effect) { | 1498 if (!effect) { |
| 1499 effect.reset(GrConfigConversionEffect::Create( | 1499 effect.reset(GrConfigConversionEffect::Create( |
| 1500 src, | 1500 src, |
| 1501 swapRAndB, | 1501 swapRAndB, |
| 1502 GrConfigConversionEffect::kN
one_PMConversion, | 1502 GrConfigConversionEffect::kN
one_PMConversion, |
| 1503 textureMatrix)); | 1503 textureMatrix)); |
| 1504 } | 1504 } |
| 1505 swapRAndB = false; // we will handle the swap in the draw. | 1505 swapRAndB = false; // we will handle the swap in the draw. |
| 1506 | 1506 |
| 1507 // We protect the existing geometry here since it may not be | 1507 // We protect the existing geometry here since it may not be |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1548 return true; | 1548 return true; |
| 1549 } | 1549 } |
| 1550 | 1550 |
| 1551 void GrContext::resolveRenderTarget(GrRenderTarget* target) { | 1551 void GrContext::resolveRenderTarget(GrRenderTarget* target) { |
| 1552 SkASSERT(target); | 1552 SkASSERT(target); |
| 1553 ASSERT_OWNED_RESOURCE(target); | 1553 ASSERT_OWNED_RESOURCE(target); |
| 1554 // In the future we may track whether there are any pending draws to this | 1554 // In the future we may track whether there are any pending draws to this |
| 1555 // target. We don't today so we always perform a flush. We don't promise | 1555 // target. We don't today so we always perform a flush. We don't promise |
| 1556 // this to our clients, though. | 1556 // this to our clients, though. |
| 1557 this->flush(); | 1557 this->flush(); |
| 1558 if (NULL != fGpu) { | 1558 if (fGpu) { |
| 1559 fGpu->resolveRenderTarget(target); | 1559 fGpu->resolveRenderTarget(target); |
| 1560 } | 1560 } |
| 1561 } | 1561 } |
| 1562 | 1562 |
| 1563 void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { | 1563 void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { |
| 1564 SkASSERT(renderTarget); | 1564 SkASSERT(renderTarget); |
| 1565 ASSERT_OWNED_RESOURCE(renderTarget); | 1565 ASSERT_OWNED_RESOURCE(renderTarget); |
| 1566 AutoRestoreEffects are; | 1566 AutoRestoreEffects are; |
| 1567 AutoCheckFlush acf(this); | 1567 AutoCheckFlush acf(this); |
| 1568 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf); | 1568 GrDrawTarget* target = this->prepareToDraw(NULL, BUFFERED_DRAW, &are, &acf); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1583 // of the source texture. See similar behavior in | 1583 // of the source texture. See similar behavior in |
| 1584 // GrContext::resolveRenderTarget. | 1584 // GrContext::resolveRenderTarget. |
| 1585 this->flush(); | 1585 this->flush(); |
| 1586 | 1586 |
| 1587 GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); | 1587 GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit); |
| 1588 GrDrawState* drawState = fGpu->drawState(); | 1588 GrDrawState* drawState = fGpu->drawState(); |
| 1589 drawState->setRenderTarget(dst); | 1589 drawState->setRenderTarget(dst); |
| 1590 SkMatrix sampleM; | 1590 SkMatrix sampleM; |
| 1591 sampleM.setIDiv(src->width(), src->height()); | 1591 sampleM.setIDiv(src->width(), src->height()); |
| 1592 SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); | 1592 SkIRect srcRect = SkIRect::MakeWH(dst->width(), dst->height()); |
| 1593 if (NULL != topLeft) { | 1593 if (topLeft) { |
| 1594 srcRect.offset(*topLeft); | 1594 srcRect.offset(*topLeft); |
| 1595 } | 1595 } |
| 1596 SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); | 1596 SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height()); |
| 1597 if (!srcRect.intersect(srcBounds)) { | 1597 if (!srcRect.intersect(srcBounds)) { |
| 1598 return; | 1598 return; |
| 1599 } | 1599 } |
| 1600 sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTo
p)); | 1600 sampleM.preTranslate(SkIntToScalar(srcRect.fLeft), SkIntToScalar(srcRect.fTo
p)); |
| 1601 drawState->addColorTextureEffect(src, sampleM); | 1601 drawState->addColorTextureEffect(src, sampleM); |
| 1602 SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(s
rcRect.height())); | 1602 SkRect dstR = SkRect::MakeWH(SkIntToScalar(srcRect.width()), SkIntToScalar(s
rcRect.height())); |
| 1603 fGpu->drawSimpleRect(dstR); | 1603 fGpu->drawSimpleRect(dstR); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1626 // set.) | 1626 // set.) |
| 1627 | 1627 |
| 1628 // If the RT is also a texture and we don't have to premultiply then take th
e texture path. | 1628 // If the RT is also a texture and we don't have to premultiply then take th
e texture path. |
| 1629 // We expect to be at least as fast or faster since it doesn't use an interm
ediate texture as | 1629 // We expect to be at least as fast or faster since it doesn't use an interm
ediate texture as |
| 1630 // we do below. | 1630 // we do below. |
| 1631 | 1631 |
| 1632 #if !defined(SK_BUILD_FOR_MAC) | 1632 #if !defined(SK_BUILD_FOR_MAC) |
| 1633 // At least some drivers on the Mac get confused when glTexImage2D is called
on a texture | 1633 // At least some drivers on the Mac get confused when glTexImage2D is called
on a texture |
| 1634 // attached to an FBO. The FBO still sees the old image. TODO: determine wha
t OS versions and/or | 1634 // attached to an FBO. The FBO still sees the old image. TODO: determine wha
t OS versions and/or |
| 1635 // HW is affected. | 1635 // HW is affected. |
| 1636 if (NULL != target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && | 1636 if (target->asTexture() && !(kUnpremul_PixelOpsFlag & flags) && |
| 1637 fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { | 1637 fGpu->canWriteTexturePixels(target->asTexture(), srcConfig)) { |
| 1638 return this->writeTexturePixels(target->asTexture(), | 1638 return this->writeTexturePixels(target->asTexture(), |
| 1639 left, top, width, height, | 1639 left, top, width, height, |
| 1640 srcConfig, buffer, rowBytes, flags); | 1640 srcConfig, buffer, rowBytes, flags); |
| 1641 } | 1641 } |
| 1642 #endif | 1642 #endif |
| 1643 | 1643 |
| 1644 // We ignore the preferred config unless it is a R/B swap of the src config.
In that case | 1644 // We ignore the preferred config unless it is a R/B swap of the src config.
In that case |
| 1645 // we will upload the original src data to a scratch texture but we will spo
of it as the swapped | 1645 // we will upload the original src data to a scratch texture but we will spo
of it as the swapped |
| 1646 // config. This scratch will then have R and B swapped. We correct for this
by swapping again | 1646 // config. This scratch will then have R and B swapped. We correct for this
by swapping again |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1743 | 1743 |
| 1744 if (NULL == fGpu) { | 1744 if (NULL == fGpu) { |
| 1745 return NULL; | 1745 return NULL; |
| 1746 } | 1746 } |
| 1747 | 1747 |
| 1748 if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffere
d) { | 1748 if (kNo_BufferedDraw == buffered && kYes_BufferedDraw == fLastDrawWasBuffere
d) { |
| 1749 fDrawBuffer->flush(); | 1749 fDrawBuffer->flush(); |
| 1750 fLastDrawWasBuffered = kNo_BufferedDraw; | 1750 fLastDrawWasBuffered = kNo_BufferedDraw; |
| 1751 } | 1751 } |
| 1752 ASSERT_OWNED_RESOURCE(fRenderTarget.get()); | 1752 ASSERT_OWNED_RESOURCE(fRenderTarget.get()); |
| 1753 if (NULL != paint) { | 1753 if (paint) { |
| 1754 SkASSERT(NULL != are); | 1754 SkASSERT(are); |
| 1755 SkASSERT(NULL != acf); | 1755 SkASSERT(acf); |
| 1756 are->set(fDrawState); | 1756 are->set(fDrawState); |
| 1757 fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); | 1757 fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); |
| 1758 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK | 1758 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK |
| 1759 if ((paint->hasMask() || 0xff != paint->fCoverage) && | 1759 if ((paint->hasMask() || 0xff != paint->fCoverage) && |
| 1760 !fDrawState->couldApplyCoverage(fGpu->caps())) { | 1760 !fDrawState->couldApplyCoverage(fGpu->caps())) { |
| 1761 GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); | 1761 GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); |
| 1762 } | 1762 } |
| 1763 #endif | 1763 #endif |
| 1764 // Clear any vertex attributes configured for the previous use of the | 1764 // Clear any vertex attributes configured for the previous use of the |
| 1765 // GrDrawState which can effect which blend optimizations are in effect. | 1765 // GrDrawState which can effect which blend optimizations are in effect. |
| 1766 fDrawState->setDefaultVertexAttribs(); | 1766 fDrawState->setDefaultVertexAttribs(); |
| 1767 } else { | 1767 } else { |
| 1768 fDrawState->reset(fViewMatrix); | 1768 fDrawState->reset(fViewMatrix); |
| 1769 fDrawState->setRenderTarget(fRenderTarget.get()); | 1769 fDrawState->setRenderTarget(fRenderTarget.get()); |
| 1770 } | 1770 } |
| 1771 GrDrawTarget* target; | 1771 GrDrawTarget* target; |
| 1772 if (kYes_BufferedDraw == buffered) { | 1772 if (kYes_BufferedDraw == buffered) { |
| 1773 fLastDrawWasBuffered = kYes_BufferedDraw; | 1773 fLastDrawWasBuffered = kYes_BufferedDraw; |
| 1774 target = fDrawBuffer; | 1774 target = fDrawBuffer; |
| 1775 } else { | 1775 } else { |
| 1776 SkASSERT(kNo_BufferedDraw == buffered); | 1776 SkASSERT(kNo_BufferedDraw == buffered); |
| 1777 fLastDrawWasBuffered = kNo_BufferedDraw; | 1777 fLastDrawWasBuffered = kNo_BufferedDraw; |
| 1778 target = fGpu; | 1778 target = fGpu; |
| 1779 } | 1779 } |
| 1780 fDrawState->setState(GrDrawState::kClip_StateBit, NULL != fClip && | 1780 fDrawState->setState(GrDrawState::kClip_StateBit, fClip && |
| 1781 !fClip->fClipStack->isWideO
pen()); | 1781 !fClip->fClipStack->isWideO
pen()); |
| 1782 target->setClip(fClip); | 1782 target->setClip(fClip); |
| 1783 SkASSERT(fDrawState == target->drawState()); | 1783 SkASSERT(fDrawState == target->drawState()); |
| 1784 return target; | 1784 return target; |
| 1785 } | 1785 } |
| 1786 | 1786 |
| 1787 /* | 1787 /* |
| 1788 * This method finds a path renderer that can draw the specified path on | 1788 * This method finds a path renderer that can draw the specified path on |
| 1789 * the provided target. | 1789 * the provided target. |
| 1790 * Due to its expense, the software path renderer has split out so it can | 1790 * Due to its expense, the software path renderer has split out so it can |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 return NULL; | 1909 return NULL; |
| 1910 } | 1910 } |
| 1911 } | 1911 } |
| 1912 | 1912 |
| 1913 GrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { | 1913 GrPath* GrContext::createPath(const SkPath& inPath, const SkStrokeRec& stroke) { |
| 1914 SkASSERT(fGpu->caps()->pathRenderingSupport()); | 1914 SkASSERT(fGpu->caps()->pathRenderingSupport()); |
| 1915 | 1915 |
| 1916 // TODO: now we add to fResourceCache. This should change to fResourceCache. | 1916 // TODO: now we add to fResourceCache. This should change to fResourceCache. |
| 1917 GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke); | 1917 GrResourceKey resourceKey = GrPath::ComputeKey(inPath, stroke); |
| 1918 GrPath* path = static_cast<GrPath*>(fResourceCache->find(resourceKey)); | 1918 GrPath* path = static_cast<GrPath*>(fResourceCache->find(resourceKey)); |
| 1919 if (NULL != path && path->isEqualTo(inPath, stroke)) { | 1919 if (path && path->isEqualTo(inPath, stroke)) { |
| 1920 path->ref(); | 1920 path->ref(); |
| 1921 } else { | 1921 } else { |
| 1922 path = fGpu->createPath(inPath, stroke); | 1922 path = fGpu->createPath(inPath, stroke); |
| 1923 fResourceCache->purgeAsNeeded(1, path->gpuMemorySize()); | 1923 fResourceCache->purgeAsNeeded(1, path->gpuMemorySize()); |
| 1924 fResourceCache->addResource(resourceKey, path); | 1924 fResourceCache->addResource(resourceKey, path); |
| 1925 } | 1925 } |
| 1926 return path; | 1926 return path; |
| 1927 } | 1927 } |
| 1928 | 1928 |
| 1929 void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuResour
ce* resource) { | 1929 void GrContext::addResourceToCache(const GrResourceKey& resourceKey, GrGpuResour
ce* resource) { |
| 1930 fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize()); | 1930 fResourceCache->purgeAsNeeded(1, resource->gpuMemorySize()); |
| 1931 fResourceCache->addResource(resourceKey, resource); | 1931 fResourceCache->addResource(resourceKey, resource); |
| 1932 } | 1932 } |
| 1933 | 1933 |
| 1934 GrGpuResource* GrContext::findAndRefCachedResource(const GrResourceKey& resource
Key) { | 1934 GrGpuResource* GrContext::findAndRefCachedResource(const GrResourceKey& resource
Key) { |
| 1935 GrGpuResource* resource = fResourceCache->find(resourceKey); | 1935 GrGpuResource* resource = fResourceCache->find(resourceKey); |
| 1936 SkSafeRef(resource); | 1936 SkSafeRef(resource); |
| 1937 return resource; | 1937 return resource; |
| 1938 } | 1938 } |
| 1939 | 1939 |
| 1940 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { | 1940 void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { |
| 1941 fGpu->addGpuTraceMarker(marker); | 1941 fGpu->addGpuTraceMarker(marker); |
| 1942 if (NULL != fDrawBuffer) { | 1942 if (fDrawBuffer) { |
| 1943 fDrawBuffer->addGpuTraceMarker(marker); | 1943 fDrawBuffer->addGpuTraceMarker(marker); |
| 1944 } | 1944 } |
| 1945 } | 1945 } |
| 1946 | 1946 |
| 1947 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 1947 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
| 1948 fGpu->removeGpuTraceMarker(marker); | 1948 fGpu->removeGpuTraceMarker(marker); |
| 1949 if (NULL != fDrawBuffer) { | 1949 if (fDrawBuffer) { |
| 1950 fDrawBuffer->removeGpuTraceMarker(marker); | 1950 fDrawBuffer->removeGpuTraceMarker(marker); |
| 1951 } | 1951 } |
| 1952 } | 1952 } |
| 1953 | 1953 |
| 1954 /////////////////////////////////////////////////////////////////////////////// | 1954 /////////////////////////////////////////////////////////////////////////////// |
| 1955 #if GR_CACHE_STATS | 1955 #if GR_CACHE_STATS |
| 1956 void GrContext::printCacheStats() const { | 1956 void GrContext::printCacheStats() const { |
| 1957 fResourceCache->printStats(); | 1957 fResourceCache->printStats(); |
| 1958 } | 1958 } |
| 1959 #endif | 1959 #endif |
| OLD | NEW |