1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "GrTexture.h" 9 #include "GrCaps.h" 10 #include "GrContext.h" 11 #include "GrContextPriv.h" 12 #include "GrGpu.h" 13 #include "GrRenderTarget.h" 14 #include "GrResourceKey.h" 15 #include "GrSurfacePriv.h" 16 #include "GrTexturePriv.h" 17 #include "GrTypes.h" 18 #include "SkMath.h" 19 #include "SkMipMap.h" 20 #include "SkTypes.h" 21 22 void GrTexture::markMipMapsDirty() { 23 if (GrMipMapsStatus::kValid == fMipMapsStatus) { 24 fMipMapsStatus = GrMipMapsStatus::kDirty; 25 } 26 } 27 28 void GrTexture::markMipMapsClean() { 29 SkASSERT(GrMipMapsStatus::kNotAllocated != fMipMapsStatus); 30 fMipMapsStatus = GrMipMapsStatus::kValid; 31 } 32 33 size_t GrTexture::onGpuMemorySize() const { 34 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1, 35 this->texturePriv().mipMapped(), false); 36 } 37 38 ///////////////////////////////////////////////////////////////////////////// 39 GrTexture::GrTexture(GrGpu* gpu, const GrSurfaceDesc& desc, GrTextureType textureType, 40 GrMipMapsStatus mipMapsStatus) 41 : INHERITED(gpu, desc), fTextureType(textureType), fMipMapsStatus(mipMapsStatus) { 42 if (GrMipMapsStatus::kNotAllocated == fMipMapsStatus) { 43 fMaxMipMapLevel = 0; 44 } else { 45 fMaxMipMapLevel = SkMipMap::ComputeLevelCount(this->width(), this->height()); 46 } 47 } 48 49 bool GrTexture::StealBackendTexture(sk_sp<GrTexture> texture, 50 GrBackendTexture* backendTexture, 51 SkImage::BackendTextureReleaseProc* releaseProc) { 52 if (!texture->surfacePriv().hasUniqueRef() || texture->surfacePriv().hasPendingIO()) { 53 return false; 54 } 55 56 if (!texture->onStealBackendTexture(backendTexture, releaseProc)) { 57 return false; 58 } 59 #ifdef SK_DEBUG 60 GrResourceCache* cache = texture->getContext()->priv().getResourceCache(); 61 int preCount = cache->getResourceCount(); 62 #endif 63 // Ensure that the texture will be released by the cache when we drop the last ref. 64 // A texture that has no refs and no keys should be immediately removed. 65 if (texture->getUniqueKey().isValid()) { 66 texture->resourcePriv().removeUniqueKey(); 67 } 68 if (texture->resourcePriv().getScratchKey().isValid()) { 69 texture->resourcePriv().removeScratchKey(); 70 } 71 #ifdef SK_DEBUG 72 texture.reset(); 73 int postCount = cache->getResourceCount(); 74 SkASSERT(postCount < preCount); 75 #endif 76 return true; 77 } 78 79 void GrTexture::computeScratchKey(GrScratchKey* key) const { 80 if (!GrPixelConfigIsCompressed(this->config())) { 81 const GrRenderTarget* rt = this->asRenderTarget(); 82 int sampleCount = 1; 83 if (rt) { 84 sampleCount = rt->numStencilSamples(); 85 } 86 GrTexturePriv::ComputeScratchKey(this->config(), this->width(), this->height(), 87 SkToBool(rt), sampleCount, 88 this->texturePriv().mipMapped(), key); 89 } 90 } 91 92 void GrTexturePriv::ComputeScratchKey(GrPixelConfig config, int width, int height, 93 bool isRenderTarget, int sampleCnt, 94 GrMipMapped mipMapped, GrScratchKey* key) { 95 static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); 96 uint32_t flags = isRenderTarget; 97 SkASSERT(width > 0); 98 SkASSERT(height > 0); 99 SkASSERT(sampleCnt > 0); 100 SkASSERT(1 == sampleCnt || isRenderTarget); 101 102 // make sure desc.fConfig fits in 5 bits 103 SkASSERT(sk_float_log2(kLast_GrPixelConfig) <= 5); 104 SkASSERT(static_cast<int>(config) < (1 << 5)); 105 SkASSERT(sampleCnt < (1 << 8)); 106 SkASSERT(flags < (1 << 10)); 107 SkASSERT(static_cast<int>(mipMapped) <= 1); 108 109 GrScratchKey::Builder builder(key, kType, 3); 110 builder[0] = width; 111 builder[1] = height; 112 builder[2] = config | (static_cast<uint8_t>(mipMapped) << 5) | (sampleCnt << 6) | (flags << 14); 113 } 114 115 void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) { 116 // Note: the fOrigin field is not used in the scratch key 117 return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight, 118 SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag), desc.fSampleCnt, 119 GrMipMapped::kNo, key); 120 } 121