GrTexture can now create its own cache key
http://codereview.appspot.com/6269047/
git-svn-id: http://skia.googlecode.com/svn/trunk@4148 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp
index 00ae8d0..e05b62b 100644
--- a/src/gpu/GrTexture.cpp
+++ b/src/gpu/GrTexture.cpp
@@ -12,6 +12,7 @@
#include "GrContext.h"
#include "GrGpu.h"
#include "GrRenderTarget.h"
+#include "GrResourceCache.h"
bool GrTexture::readPixels(int left, int top, int width, int height,
GrPixelConfig config, void* buffer,
@@ -80,3 +81,97 @@
GrAssert(0 == fDesc.fSampleCnt);
}
}
+
+enum TextureBits {
+ kFirst_TextureBit = (GrResourceKey::kLastPublic_TypeBit << 1),
+
+ /*
+ * The kNPOT bit is set when the texture is NPOT and is being repeated
+ * but the hardware doesn't support that feature.
+ */
+ kNPOT_TextureBit = kFirst_TextureBit,
+ /*
+ * The kFilter bit can only be set when the kNPOT flag is set and indicates
+ * whether the resizing of the texture should use filtering. This is
+ * to handle cases where the original texture is indexed to disable
+ * filtering.
+ */
+ kFilter_TextureBit = kNPOT_TextureBit << 1,
+ /*
+ * The kScratch bit is set if the texture is being used as a scratch
+ * texture.
+ */
+ kScratch_TextureBit = kFilter_TextureBit << 1,
+};
+
+namespace {
+void gen_texture_key_values(const GrGpu* gpu,
+ const GrSamplerState* sampler,
+ GrTexture::TextureKey clientKey,
+ const GrTextureDesc& desc,
+ bool scratch,
+ uint32_t v[4]) {
+ GR_STATIC_ASSERT(sizeof(GrTexture::TextureKey) == sizeof(uint64_t));
+
+ if (scratch) {
+ // Instead of a client-provided key of the texture contents
+ // we create a key of from the descriptor.
+ GrAssert(0 == clientKey);
+ clientKey = (desc.fFlags << 8) | ((uint64_t) desc.fConfig << 32);
+ }
+
+ // we assume we only need 16 bits of width and height
+ // assert that texture creation will fail anyway if this assumption
+ // would cause key collisions.
+ GrAssert(gpu->getCaps().fMaxTextureSize <= SK_MaxU16);
+ v[0] = clientKey & 0xffffffffUL;
+ v[1] = (clientKey >> 32) & 0xffffffffUL;
+ v[2] = desc.fWidth | (desc.fHeight << 16);
+
+ v[3] = (desc.fSampleCnt << 24);
+ GrAssert(desc.fSampleCnt >= 0 && desc.fSampleCnt < 256);
+
+ if (!gpu->getCaps().fNPOTTextureTileSupport) {
+ bool isPow2 = GrIsPow2(desc.fWidth) && GrIsPow2(desc.fHeight);
+
+ bool tiled = NULL != sampler &&
+ ((sampler->getWrapX() != GrSamplerState::kClamp_WrapMode) ||
+ (sampler->getWrapY() != GrSamplerState::kClamp_WrapMode));
+
+ if (tiled && !isPow2) {
+ v[3] |= kNPOT_TextureBit;
+ if (GrSamplerState::kNearest_Filter != sampler->getFilter()) {
+ v[3] |= kFilter_TextureBit;
+ }
+ }
+ }
+
+ if (scratch) {
+ v[3] |= kScratch_TextureBit;
+ }
+
+ v[3] |= GrResourceKey::kTexture_TypeBit;
+}
+}
+
+GrResourceKey GrTexture::ComputeKey(const GrGpu* gpu,
+ const GrSamplerState* sampler,
+ TextureKey clientKey,
+ const GrTextureDesc& desc,
+ bool scratch) {
+ uint32_t v[4];
+ gen_texture_key_values(gpu, sampler, clientKey, desc, scratch, v);
+ return GrResourceKey(v);
+}
+
+bool GrTexture::NeedsResizing(const GrResourceKey& key) {
+ return 0 != (key.getValue32(3) & kNPOT_TextureBit);
+}
+
+bool GrTexture::IsScratchTexture(const GrResourceKey& key) {
+ return 0 != (key.getValue32(3) & kScratch_TextureBit);
+}
+
+bool GrTexture::NeedsFiltering(const GrResourceKey& key) {
+ return 0 != (key.getValue32(3) & kFilter_TextureBit);
+}