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