1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkMath.h" 9cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 10cb93a386Sopenharmony_ci#include "include/gpu/GrTypes.h" 11cb93a386Sopenharmony_ci#include "include/private/GrResourceKey.h" 12cb93a386Sopenharmony_ci#include "src/core/SkMipmap.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrRenderTarget.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrResourceCache.h" 17cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#ifdef SK_DEBUG 20cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 21cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 22cb93a386Sopenharmony_ci#endif 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_civoid GrTexture::markMipmapsDirty() { 25cb93a386Sopenharmony_ci if (GrMipmapStatus::kValid == fMipmapStatus) { 26cb93a386Sopenharmony_ci fMipmapStatus = GrMipmapStatus::kDirty; 27cb93a386Sopenharmony_ci } 28cb93a386Sopenharmony_ci} 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_civoid GrTexture::markMipmapsClean() { 31cb93a386Sopenharmony_ci SkASSERT(GrMipmapStatus::kNotAllocated != fMipmapStatus); 32cb93a386Sopenharmony_ci fMipmapStatus = GrMipmapStatus::kValid; 33cb93a386Sopenharmony_ci} 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_cisize_t GrTexture::onGpuMemorySize() const { 36cb93a386Sopenharmony_ci return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 37cb93a386Sopenharmony_ci /*colorSamplesPerPixel=*/1, this->mipmapped()); 38cb93a386Sopenharmony_ci} 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////// 41cb93a386Sopenharmony_ciGrTexture::GrTexture(GrGpu* gpu, 42cb93a386Sopenharmony_ci const SkISize& dimensions, 43cb93a386Sopenharmony_ci GrProtected isProtected, 44cb93a386Sopenharmony_ci GrTextureType textureType, 45cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus) 46cb93a386Sopenharmony_ci : INHERITED(gpu, dimensions, isProtected) 47cb93a386Sopenharmony_ci , fTextureType(textureType) 48cb93a386Sopenharmony_ci , fMipmapStatus(mipmapStatus) { 49cb93a386Sopenharmony_ci if (fMipmapStatus == GrMipmapStatus::kNotAllocated) { 50cb93a386Sopenharmony_ci fMaxMipmapLevel = 0; 51cb93a386Sopenharmony_ci } else { 52cb93a386Sopenharmony_ci fMaxMipmapLevel = SkMipmap::ComputeLevelCount(this->width(), this->height()); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci if (textureType == GrTextureType::kExternal) { 55cb93a386Sopenharmony_ci this->setReadOnly(); 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci} 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_cibool GrTexture::StealBackendTexture(sk_sp<GrTexture> texture, 60cb93a386Sopenharmony_ci GrBackendTexture* backendTexture, 61cb93a386Sopenharmony_ci SkImage::BackendTextureReleaseProc* releaseProc) { 62cb93a386Sopenharmony_ci if (!texture->unique()) { 63cb93a386Sopenharmony_ci return false; 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci if (!texture->onStealBackendTexture(backendTexture, releaseProc)) { 67cb93a386Sopenharmony_ci return false; 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci#ifdef SK_DEBUG 70cb93a386Sopenharmony_ci GrResourceCache* cache = texture->getContext()->priv().getResourceCache(); 71cb93a386Sopenharmony_ci int preCount = cache->getResourceCount(); 72cb93a386Sopenharmony_ci#endif 73cb93a386Sopenharmony_ci // Ensure that the texture will be released by the cache when we drop the last ref. 74cb93a386Sopenharmony_ci // A texture that has no refs and no keys should be immediately removed. 75cb93a386Sopenharmony_ci if (texture->getUniqueKey().isValid()) { 76cb93a386Sopenharmony_ci texture->resourcePriv().removeUniqueKey(); 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci if (texture->resourcePriv().getScratchKey().isValid()) { 79cb93a386Sopenharmony_ci texture->resourcePriv().removeScratchKey(); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci#ifdef SK_DEBUG 82cb93a386Sopenharmony_ci texture.reset(); 83cb93a386Sopenharmony_ci int postCount = cache->getResourceCount(); 84cb93a386Sopenharmony_ci SkASSERT(postCount < preCount); 85cb93a386Sopenharmony_ci#endif 86cb93a386Sopenharmony_ci return true; 87cb93a386Sopenharmony_ci} 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_civoid GrTexture::computeScratchKey(GrScratchKey* key) const { 90cb93a386Sopenharmony_ci if (!this->getGpu()->caps()->isFormatCompressed(this->backendFormat())) { 91cb93a386Sopenharmony_ci int sampleCount = 1; 92cb93a386Sopenharmony_ci GrRenderable renderable = GrRenderable::kNo; 93cb93a386Sopenharmony_ci if (const auto* rt = this->asRenderTarget()) { 94cb93a386Sopenharmony_ci sampleCount = rt->numSamples(); 95cb93a386Sopenharmony_ci renderable = GrRenderable::kYes; 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci auto isProtected = this->isProtected() ? GrProtected::kYes : GrProtected::kNo; 98cb93a386Sopenharmony_ci ComputeScratchKey(*this->getGpu()->caps(), this->backendFormat(), this->dimensions(), 99cb93a386Sopenharmony_ci renderable, sampleCount, this->mipmapped(), isProtected, key); 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci} 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_civoid GrTexture::ComputeScratchKey(const GrCaps& caps, 104cb93a386Sopenharmony_ci const GrBackendFormat& format, 105cb93a386Sopenharmony_ci SkISize dimensions, 106cb93a386Sopenharmony_ci GrRenderable renderable, 107cb93a386Sopenharmony_ci int sampleCnt, 108cb93a386Sopenharmony_ci GrMipmapped mipMapped, 109cb93a386Sopenharmony_ci GrProtected isProtected, 110cb93a386Sopenharmony_ci GrScratchKey* key) { 111cb93a386Sopenharmony_ci static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType(); 112cb93a386Sopenharmony_ci SkASSERT(!dimensions.isEmpty()); 113cb93a386Sopenharmony_ci SkASSERT(sampleCnt > 0); 114cb93a386Sopenharmony_ci SkASSERT(1 == sampleCnt || renderable == GrRenderable::kYes); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci SkASSERT(static_cast<uint32_t>(mipMapped) <= 1); 117cb93a386Sopenharmony_ci SkASSERT(static_cast<uint32_t>(isProtected) <= 1); 118cb93a386Sopenharmony_ci SkASSERT(static_cast<uint32_t>(renderable) <= 1); 119cb93a386Sopenharmony_ci SkASSERT(static_cast<uint32_t>(sampleCnt) < (1 << (32 - 3))); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci uint64_t formatKey = caps.computeFormatKey(format); 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci GrScratchKey::Builder builder(key, kType, 5); 124cb93a386Sopenharmony_ci builder[0] = dimensions.width(); 125cb93a386Sopenharmony_ci builder[1] = dimensions.height(); 126cb93a386Sopenharmony_ci builder[2] = formatKey & 0xFFFFFFFF; 127cb93a386Sopenharmony_ci builder[3] = (formatKey >> 32) & 0xFFFFFFFF; 128cb93a386Sopenharmony_ci builder[4] = (static_cast<uint32_t>(mipMapped) << 0) 129cb93a386Sopenharmony_ci | (static_cast<uint32_t>(isProtected) << 1) 130cb93a386Sopenharmony_ci | (static_cast<uint32_t>(renderable) << 2) 131cb93a386Sopenharmony_ci | (static_cast<uint32_t>(sampleCnt) << 3); 132cb93a386Sopenharmony_ci} 133