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 "GrContext.h" 9 #include "GrCaps.h" 10 #include "GrGpu.h" 11 #include "GrResourceKey.h" 12 #include "GrRenderTarget.h" 13 #include "GrSurfacePriv.h" 14 #include "GrTexture.h" 15 #include "GrTexturePriv.h" 16 #include "GrTypes.h" 17 #include "SkMath.h" 18 #include "SkMipMap.h" 19 #include "SkTypes.h" 20 21 void GrTexture::markMipMapsDirty() { 22 if (GrMipMapsStatus::kValid == fMipMapsStatus) { 23 fMipMapsStatus = GrMipMapsStatus::kDirty; 24 } 25 } 26 27 void GrTexture::markMipMapsClean() { 28 const bool sizeChanged = GrMipMapsStatus::kNotAllocated == fMipMapsStatus; 29 fMipMapsStatus = GrMipMapsStatus::kValid; 30 if (sizeChanged) { 31 // This must not be called until after changing fMipMapsStatus. 32 this->didChangeGpuMemorySize(); 33 // TODO(http://skbug.com/4548) - The desc and scratch key should be 34 // updated to reflect the newly-allocated mipmaps. 35 } 36 } 37 38 size_t GrTexture::onGpuMemorySize() const { 39 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1, 40 this->texturePriv().mipMapped(), false); 41 } 42 43 ///////////////////////////////////////////////////////////////////////////// 44 GrTexture::GrTexture(GrGpu* gpu, const GrSurfaceDesc& desc, GrSLType samplerType, 45 GrSamplerState::Filter highestFilterMode, 46 GrMipMapsStatus mipMapsStatus) 47 : INHERITED(gpu, desc) 48 , fSamplerType(samplerType) 49 , fHighestFilterMode(highestFilterMode) 50 , fMipMapsStatus(mipMapsStatus) 51 // Mip color mode is explicitly set after creation via GrTexturePriv 52 , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy) { 53 if (GrMipMapsStatus::kNotAllocated == fMipMapsStatus) { 54 fMaxMipMapLevel = 0; 55 } else { 56 fMaxMipMapLevel = SkMipMap::ComputeLevelCount(this->width(), this->height()); 57 } 58 } 59 60 bool GrTexture::StealBackendTexture(sk_sp<GrTexture>&& texture, 61 GrBackendTexture* backendTexture, 62 SkImage::BackendTextureReleaseProc* releaseProc) { 63 if (!texture->surfacePriv().hasUniqueRef() || texture->surfacePriv().hasPendingIO()) { 64 return false; 65 } 66 67 if (!texture->onStealBackendTexture(backendTexture, releaseProc)) { 68 return false; 69 } 70 71 // Release any not-stolen data being held by this class. 72 texture->onRelease(); 73 // Abandon the GrTexture so it can't be re-used. 74 texture->abandon(); 75 76 return true; 77 } 78 79 void GrTexture::computeScratchKey(GrScratchKey* key) const { 80 const GrRenderTarget* rt = this->asRenderTarget(); 81 int sampleCount = 1; 82 if (rt) { 83 sampleCount = rt->numStencilSamples(); 84 } 85 GrTexturePriv::ComputeScratchKey(this->config(), this->width(), this->height(), 86 SkToBool(rt), sampleCount, 87 this->texturePriv().mipMapped(), key); 88 } 89 90 void GrTexturePriv::ComputeScratchKey(GrPixelConfig config, int width, int height, 91 bool isRenderTarget, int sampleCnt, 92 GrMipMapped mipMapped, GrScratchKey* key) { 93 static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); 94 uint32_t flags = isRenderTarget; 95 SkASSERT(width > 0); 96 SkASSERT(height > 0); 97 SkASSERT(sampleCnt > 0); 98 SkASSERT(1 == sampleCnt || isRenderTarget); 99 100 // make sure desc.fConfig fits in 5 bits 101 SkASSERT(sk_float_log2(kLast_GrPixelConfig) <= 5); 102 SkASSERT(static_cast<int>(config) < (1 << 5)); 103 SkASSERT(sampleCnt < (1 << 8)); 104 SkASSERT(flags < (1 << 10)); 105 SkASSERT(static_cast<int>(mipMapped) <= 1); 106 107 GrScratchKey::Builder builder(key, kType, 3); 108 builder[0] = width; 109 builder[1] = height; 110 builder[2] = config | (static_cast<uint8_t>(mipMapped) << 5) | (sampleCnt << 6) | (flags << 14); 111 } 112 113 void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) { 114 // Note: the fOrigin field is not used in the scratch key 115 return ComputeScratchKey(desc.fConfig, desc.fWidth, desc.fHeight, 116 SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag), desc.fSampleCnt, 117 GrMipMapped::kNo, key); 118 } 119