| 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 "GrTexture.h" | 10 #include "GrTexture.h" |
| 11 | 11 |
| 12 #include "GrContext.h" | 12 #include "GrContext.h" |
| 13 #include "GrDrawTargetCaps.h" | 13 #include "GrDrawTargetCaps.h" |
| 14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
| 15 #include "GrRenderTarget.h" | 15 #include "GrRenderTarget.h" |
| 16 #include "GrResourceCache.h" | 16 #include "GrResourceCache.h" |
| 17 | 17 |
| 18 GrTexture::~GrTexture() { | 18 GrTexture::~GrTexture() { |
| 19 if (NULL != fRenderTarget.get()) { | 19 if (NULL != fRenderTarget.get()) { |
| 20 fRenderTarget.get()->owningTextureDestroyed(); | 20 fRenderTarget.get()->owningTextureDestroyed(); |
| 21 } | 21 } |
| 22 } | 22 } |
| 23 | 23 |
| 24 /** | 24 /** |
| 25 * This method allows us to interrupt the normal deletion process and place | 25 * This method allows us to interrupt the normal deletion process and place |
| 26 * textures back in the texture cache when their ref count goes to zero. | 26 * textures back in the texture cache when their ref count goes to zero. |
| 27 */ | 27 */ |
| 28 void GrTexture::internal_dispose() const { | 28 void GrTexture::internal_dispose() const { |
| 29 | 29 if (this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToCache_F
lagBit) && |
| 30 if (this->isSetFlag((GrTextureFlags) kReturnToCache_FlagBit) && | |
| 31 NULL != this->INHERITED::getContext()) { | 30 NULL != this->INHERITED::getContext()) { |
| 32 GrTexture* nonConstThis = const_cast<GrTexture *>(this); | 31 GrTexture* nonConstThis = const_cast<GrTexture *>(this); |
| 33 this->fRefCnt = 1; // restore ref count to initial setting | 32 this->fRefCnt = 1; // restore ref count to initial setting |
| 34 | 33 |
| 35 nonConstThis->resetFlag((GrTextureFlags) kReturnToCache_FlagBit); | 34 nonConstThis->impl()->resetFlag((GrTextureFlags) GrTextureImpl::kReturnT
oCache_FlagBit); |
| 36 nonConstThis->INHERITED::getContext()->addExistingTextureToCache(nonCons
tThis); | 35 nonConstThis->INHERITED::getContext()->addExistingTextureToCache(nonCons
tThis); |
| 37 | 36 |
| 38 // Note: "this" texture might be freed inside addExistingTextureToCache | 37 // Note: "this" texture might be freed inside addExistingTextureToCache |
| 39 // if it is purged. | 38 // if it is purged. |
| 40 return; | 39 return; |
| 41 } | 40 } |
| 42 | 41 |
| 43 SkASSERT(0 == this->getDeferredRefCount()); | 42 SkASSERT(0 == this->getDeferredRefCount()); |
| 44 this->INHERITED::internal_dispose(); | 43 this->INHERITED::internal_dispose(); |
| 45 } | 44 } |
| 46 | 45 |
| 47 void GrTexture::dirtyMipMaps(bool mipMapsDirty) { | 46 void GrTextureImpl::dirtyMipMaps(bool mipMapsDirty) { |
| 48 if (mipMapsDirty) { | 47 if (mipMapsDirty) { |
| 49 if (kValid_MipMapsStatus == fMipMapsStatus) { | 48 if (kValid_MipMapsStatus == fMipMapsStatus) { |
| 50 fMipMapsStatus = kAllocated_MipMapsStatus; | 49 fMipMapsStatus = kAllocated_MipMapsStatus; |
| 51 } | 50 } |
| 52 } else { | 51 } else { |
| 53 const bool sizeChanged = kNotAllocated_MipMapsStatus == fMipMapsStatus; | 52 const bool sizeChanged = kNotAllocated_MipMapsStatus == fMipMapsStatus; |
| 54 fMipMapsStatus = kValid_MipMapsStatus; | 53 fMipMapsStatus = kValid_MipMapsStatus; |
| 55 if (sizeChanged) { | 54 if (sizeChanged) { |
| 56 // This must not be called until after changing fMipMapsStatus. | 55 // This must not be called until after changing fMipMapsStatus. |
| 57 this->didChangeGpuMemorySize(); | 56 this->didChangeGpuMemorySize(); |
| 58 } | 57 } |
| 59 } | 58 } |
| 60 } | 59 } |
| 61 | 60 |
| 62 size_t GrTexture::gpuMemorySize() const { | 61 size_t GrTexture::gpuMemorySize() const { |
| 63 size_t textureSize = (size_t) fDesc.fWidth * | 62 size_t textureSize = (size_t) fDesc.fWidth * |
| 64 fDesc.fHeight * | 63 fDesc.fHeight * |
| 65 GrBytesPerPixel(fDesc.fConfig); | 64 GrBytesPerPixel(fDesc.fConfig); |
| 66 if (kNotAllocated_MipMapsStatus != fMipMapsStatus) { | 65 if (this->impl()->hasMipMaps()) { |
| 67 // We don't have to worry about the mipmaps being a different size than | 66 // We don't have to worry about the mipmaps being a different size than |
| 68 // we'd expect because we never change fDesc.fWidth/fHeight. | 67 // we'd expect because we never change fDesc.fWidth/fHeight. |
| 69 textureSize *= 2; | 68 textureSize *= 2; |
| 70 } | 69 } |
| 71 return textureSize; | 70 return textureSize; |
| 72 } | 71 } |
| 73 | 72 |
| 74 bool GrTexture::readPixels(int left, int top, int width, int height, | 73 bool GrTexture::readPixels(int left, int top, int width, int height, |
| 75 GrPixelConfig config, void* buffer, | 74 GrPixelConfig config, void* buffer, |
| 76 size_t rowBytes, uint32_t pixelOpsFlags) { | 75 size_t rowBytes, uint32_t pixelOpsFlags) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 93 if (NULL == context) { | 92 if (NULL == context) { |
| 94 return; | 93 return; |
| 95 } | 94 } |
| 96 context->writeTexturePixels(this, | 95 context->writeTexturePixels(this, |
| 97 left, top, width, height, | 96 left, top, width, height, |
| 98 config, buffer, rowBytes, | 97 config, buffer, rowBytes, |
| 99 pixelOpsFlags); | 98 pixelOpsFlags); |
| 100 } | 99 } |
| 101 | 100 |
| 102 void GrTexture::onRelease() { | 101 void GrTexture::onRelease() { |
| 103 SkASSERT(!this->isSetFlag((GrTextureFlags) kReturnToCache_FlagBit)); | 102 SkASSERT(!this->impl()->isSetFlag((GrTextureFlags) GrTextureImpl::kReturnToC
ache_FlagBit)); |
| 104 INHERITED::onRelease(); | 103 INHERITED::onRelease(); |
| 105 } | 104 } |
| 106 | 105 |
| 107 void GrTexture::onAbandon() { | 106 void GrTexture::onAbandon() { |
| 108 if (NULL != fRenderTarget.get()) { | 107 if (NULL != fRenderTarget.get()) { |
| 109 fRenderTarget->abandon(); | 108 fRenderTarget->abandon(); |
| 110 } | 109 } |
| 111 INHERITED::onAbandon(); | 110 INHERITED::onAbandon(); |
| 112 } | 111 } |
| 113 | 112 |
| 114 void GrTexture::validateDesc() const { | 113 void GrTexture::validateDesc() const { |
| 115 if (NULL != this->asRenderTarget()) { | 114 if (NULL != this->asRenderTarget()) { |
| 116 // This texture has a render target | 115 // This texture has a render target |
| 117 SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrTextureFlagBit)); | 116 SkASSERT(0 != (fDesc.fFlags & kRenderTarget_GrTextureFlagBit)); |
| 118 | 117 |
| 119 if (NULL != this->asRenderTarget()->getStencilBuffer()) { | 118 if (NULL != this->asRenderTarget()->getStencilBuffer()) { |
| 120 SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); | 119 SkASSERT(0 != (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); |
| 121 } else { | 120 } else { |
| 122 SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); | 121 SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); |
| 123 } | 122 } |
| 124 | 123 |
| 125 SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples()); | 124 SkASSERT(fDesc.fSampleCnt == this->asRenderTarget()->numSamples()); |
| 126 } else { | 125 } else { |
| 127 SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrTextureFlagBit)); | 126 SkASSERT(0 == (fDesc.fFlags & kRenderTarget_GrTextureFlagBit)); |
| 128 SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); | 127 SkASSERT(0 == (fDesc.fFlags & kNoStencil_GrTextureFlagBit)); |
| 129 SkASSERT(0 == fDesc.fSampleCnt); | 128 SkASSERT(0 == fDesc.fSampleCnt); |
| 130 } | 129 } |
| 131 } | 130 } |
| 132 | 131 |
| 132 ////////////////////////////////////////////////////////////////////////////// |
| 133 |
| 133 // These flags need to fit in a GrResourceKey::ResourceFlags so they can be fold
ed into the texture | 134 // These flags need to fit in a GrResourceKey::ResourceFlags so they can be fold
ed into the texture |
| 134 // key | 135 // key |
| 135 enum TextureFlags { | 136 enum TextureFlags { |
| 136 /** | 137 /** |
| 137 * The kStretchToPOT bit is set when the texture is NPOT and is being repeat
ed but the | 138 * The kStretchToPOT bit is set when the texture is NPOT and is being repeat
ed but the |
| 138 * hardware doesn't support that feature. | 139 * hardware doesn't support that feature. |
| 139 */ | 140 */ |
| 140 kStretchToPOT_TextureFlag = 0x1, | 141 kStretchToPOT_TextureFlag = 0x1, |
| 141 /** | 142 /** |
| 142 * The kBilerp bit can only be set when the kStretchToPOT flag is set and in
dicates whether the | 143 * The kBilerp bit can only be set when the kStretchToPOT flag is set and in
dicates whether the |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 // to render upside down. | 180 // to render upside down. |
| 180 bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit); | 181 bool renderTarget = 0 != (desc.fFlags & kRenderTarget_GrTextureFlagBit); |
| 181 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { | 182 if (kDefault_GrSurfaceOrigin == desc.fOrigin) { |
| 182 return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOr
igin; | 183 return renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOr
igin; |
| 183 } else { | 184 } else { |
| 184 return desc.fOrigin; | 185 return desc.fOrigin; |
| 185 } | 186 } |
| 186 } | 187 } |
| 187 } | 188 } |
| 188 | 189 |
| 189 GrResourceKey GrTexture::ComputeKey(const GrGpu* gpu, | 190 ////////////////////////////////////////////////////////////////////////////// |
| 191 |
| 192 GrResourceKey GrTextureImpl::ComputeKey(const GrGpu* gpu, |
| 190 const GrTextureParams* params, | 193 const GrTextureParams* params, |
| 191 const GrTextureDesc& desc, | 194 const GrTextureDesc& desc, |
| 192 const GrCacheID& cacheID) { | 195 const GrCacheID& cacheID) { |
| 193 GrResourceKey::ResourceFlags flags = get_texture_flags(gpu, params, desc); | 196 GrResourceKey::ResourceFlags flags = get_texture_flags(gpu, params, desc); |
| 194 return GrResourceKey(cacheID, texture_resource_type(), flags); | 197 return GrResourceKey(cacheID, texture_resource_type(), flags); |
| 195 } | 198 } |
| 196 | 199 |
| 197 GrResourceKey GrTexture::ComputeScratchKey(const GrTextureDesc& desc) { | 200 GrResourceKey GrTextureImpl::ComputeScratchKey(const GrTextureDesc& desc) { |
| 198 GrCacheID::Key idKey; | 201 GrCacheID::Key idKey; |
| 199 // Instead of a client-provided key of the texture contents we create a key
from the | 202 // Instead of a client-provided key of the texture contents we create a key
from the |
| 200 // descriptor. | 203 // descriptor. |
| 201 GR_STATIC_ASSERT(sizeof(idKey) >= 16); | 204 GR_STATIC_ASSERT(sizeof(idKey) >= 16); |
| 202 SkASSERT(desc.fHeight < (1 << 16)); | 205 SkASSERT(desc.fHeight < (1 << 16)); |
| 203 SkASSERT(desc.fWidth < (1 << 16)); | 206 SkASSERT(desc.fWidth < (1 << 16)); |
| 204 idKey.fData32[0] = (desc.fWidth) | (desc.fHeight << 16); | 207 idKey.fData32[0] = (desc.fWidth) | (desc.fHeight << 16); |
| 205 idKey.fData32[1] = desc.fConfig | desc.fSampleCnt << 16; | 208 idKey.fData32[1] = desc.fConfig | desc.fSampleCnt << 16; |
| 206 idKey.fData32[2] = desc.fFlags; | 209 idKey.fData32[2] = desc.fFlags; |
| 207 idKey.fData32[3] = resolve_origin(desc); // Only needs 2 bits actually | 210 idKey.fData32[3] = resolve_origin(desc); // Only needs 2 bits actually |
| 208 static const int kPadSize = sizeof(idKey) - 16; | 211 static const int kPadSize = sizeof(idKey) - 16; |
| 209 GR_STATIC_ASSERT(kPadSize >= 0); | 212 GR_STATIC_ASSERT(kPadSize >= 0); |
| 210 memset(idKey.fData8 + 16, 0, kPadSize); | 213 memset(idKey.fData8 + 16, 0, kPadSize); |
| 211 | 214 |
| 212 GrCacheID cacheID(GrResourceKey::ScratchDomain(), idKey); | 215 GrCacheID cacheID(GrResourceKey::ScratchDomain(), idKey); |
| 213 return GrResourceKey(cacheID, texture_resource_type(), 0); | 216 return GrResourceKey(cacheID, texture_resource_type(), 0); |
| 214 } | 217 } |
| 215 | 218 |
| 216 bool GrTexture::NeedsResizing(const GrResourceKey& key) { | 219 bool GrTextureImpl::NeedsResizing(const GrResourceKey& key) { |
| 217 return SkToBool(key.getResourceFlags() & kStretchToPOT_TextureFlag); | 220 return SkToBool(key.getResourceFlags() & kStretchToPOT_TextureFlag); |
| 218 } | 221 } |
| 219 | 222 |
| 220 bool GrTexture::NeedsBilerp(const GrResourceKey& key) { | 223 bool GrTextureImpl::NeedsBilerp(const GrResourceKey& key) { |
| 221 return SkToBool(key.getResourceFlags() & kBilerp_TextureFlag); | 224 return SkToBool(key.getResourceFlags() & kBilerp_TextureFlag); |
| 222 } | 225 } |
| OLD | NEW |