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 |