1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 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 "src/gpu/GrResourceCache.h" 9cb93a386Sopenharmony_ci#include <atomic> 10cb93a386Sopenharmony_ci#include <ctime> 11cb93a386Sopenharmony_ci#include <vector> 12cb93a386Sopenharmony_ci#include <map> 13cb93a386Sopenharmony_ci#include <sstream> 14cb93a386Sopenharmony_ci#ifdef NOT_BUILD_FOR_OHOS_SDK 15cb93a386Sopenharmony_ci#include <parameters.h> 16cb93a386Sopenharmony_ci#endif 17cb93a386Sopenharmony_ci#include "include/core/SkString.h" 18cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 19cb93a386Sopenharmony_ci#include "include/private/GrSingleOwner.h" 20cb93a386Sopenharmony_ci#include "include/private/SkTo.h" 21cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 22cb93a386Sopenharmony_ci#include "src/core/SkMessageBus.h" 23cb93a386Sopenharmony_ci#include "src/core/SkOpts.h" 24cb93a386Sopenharmony_ci#include "src/core/SkScopeExit.h" 25cb93a386Sopenharmony_ci#include "src/core/SkTSort.h" 26cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 27cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 28cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourceCacheAccess.h" 29cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 30cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 31cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxyCacheAccess.h" 32cb93a386Sopenharmony_ci#include "src/gpu/GrThreadSafeCache.h" 33cb93a386Sopenharmony_ci#include "src/gpu/GrTracing.h" 34cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ciDECLARE_SKMESSAGEBUS_MESSAGE(GrUniqueKeyInvalidatedMessage, uint32_t, true); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciDECLARE_SKMESSAGEBUS_MESSAGE(GrTextureFreedMessage, GrDirectContext::DirectContextID, true); 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fSingleOwner) 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciGrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { 45cb93a386Sopenharmony_ci static std::atomic<int32_t> nextType{INHERITED::kInvalidDomain + 1}; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci int32_t type = nextType.fetch_add(1, std::memory_order_relaxed); 48cb93a386Sopenharmony_ci if (type > SkTo<int32_t>(UINT16_MAX)) { 49cb93a386Sopenharmony_ci SK_ABORT("Too many Resource Types"); 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci return static_cast<ResourceType>(type); 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ciGrUniqueKey::Domain GrUniqueKey::GenerateDomain() { 56cb93a386Sopenharmony_ci static std::atomic<int32_t> nextDomain{INHERITED::kInvalidDomain + 1}; 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci int32_t domain = nextDomain.fetch_add(1, std::memory_order_relaxed); 59cb93a386Sopenharmony_ci if (domain > SkTo<int32_t>(UINT16_MAX)) { 60cb93a386Sopenharmony_ci SK_ABORT("Too many GrUniqueKey Domains"); 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci return static_cast<Domain>(domain); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ciuint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { 67cb93a386Sopenharmony_ci return SkOpts::hash(data, size); 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ciclass GrResourceCache::AutoValidate : ::SkNoncopyable { 73cb93a386Sopenharmony_cipublic: 74cb93a386Sopenharmony_ci AutoValidate(GrResourceCache* cache) : fCache(cache) { cache->validate(); } 75cb93a386Sopenharmony_ci ~AutoValidate() { fCache->validate(); } 76cb93a386Sopenharmony_ciprivate: 77cb93a386Sopenharmony_ci GrResourceCache* fCache; 78cb93a386Sopenharmony_ci}; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ciinline GrResourceCache::TextureAwaitingUnref::TextureAwaitingUnref() = default; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ciinline GrResourceCache::TextureAwaitingUnref::TextureAwaitingUnref(GrTexture* texture) 85cb93a386Sopenharmony_ci : fTexture(texture), fNumUnrefs(1) {} 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ciinline GrResourceCache::TextureAwaitingUnref::TextureAwaitingUnref(TextureAwaitingUnref&& that) { 88cb93a386Sopenharmony_ci fTexture = std::exchange(that.fTexture, nullptr); 89cb93a386Sopenharmony_ci fNumUnrefs = std::exchange(that.fNumUnrefs, 0); 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciinline GrResourceCache::TextureAwaitingUnref& GrResourceCache::TextureAwaitingUnref::operator=( 93cb93a386Sopenharmony_ci TextureAwaitingUnref&& that) { 94cb93a386Sopenharmony_ci fTexture = std::exchange(that.fTexture, nullptr); 95cb93a386Sopenharmony_ci fNumUnrefs = std::exchange(that.fNumUnrefs, 0); 96cb93a386Sopenharmony_ci return *this; 97cb93a386Sopenharmony_ci} 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ciinline GrResourceCache::TextureAwaitingUnref::~TextureAwaitingUnref() { 100cb93a386Sopenharmony_ci if (fTexture) { 101cb93a386Sopenharmony_ci for (int i = 0; i < fNumUnrefs; ++i) { 102cb93a386Sopenharmony_ci fTexture->unref(); 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci} 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ciinline void GrResourceCache::TextureAwaitingUnref::TextureAwaitingUnref::addRef() { ++fNumUnrefs; } 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ciinline void GrResourceCache::TextureAwaitingUnref::unref() { 110cb93a386Sopenharmony_ci SkASSERT(fNumUnrefs > 0); 111cb93a386Sopenharmony_ci fTexture->unref(); 112cb93a386Sopenharmony_ci --fNumUnrefs; 113cb93a386Sopenharmony_ci} 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ciinline bool GrResourceCache::TextureAwaitingUnref::finished() { return !fNumUnrefs; } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ciGrResourceCache::GrResourceCache(GrSingleOwner* singleOwner, 120cb93a386Sopenharmony_ci GrDirectContext::DirectContextID owningContextID, 121cb93a386Sopenharmony_ci uint32_t familyID) 122cb93a386Sopenharmony_ci : fInvalidUniqueKeyInbox(familyID) 123cb93a386Sopenharmony_ci , fFreedTextureInbox(owningContextID) 124cb93a386Sopenharmony_ci , fOwningContextID(owningContextID) 125cb93a386Sopenharmony_ci , fContextUniqueID(familyID) 126cb93a386Sopenharmony_ci , fSingleOwner(singleOwner) { 127cb93a386Sopenharmony_ci SkASSERT(owningContextID.isValid()); 128cb93a386Sopenharmony_ci SkASSERT(familyID != SK_InvalidUniqueID); 129cb93a386Sopenharmony_ci#ifdef NOT_BUILD_FOR_OHOS_SDK 130cb93a386Sopenharmony_ci static int overtimeDuration = std::atoi( 131cb93a386Sopenharmony_ci OHOS::system::GetParameter("persist.sys.graphic.mem.async_free_cache_overtime", "600") 132cb93a386Sopenharmony_ci .c_str()); 133cb93a386Sopenharmony_ci static double maxBytesRate = std::atof( 134cb93a386Sopenharmony_ci OHOS::system::GetParameter("persist.sys.graphic.mem.async_free_cache_max_rate", "0.9") 135cb93a386Sopenharmony_ci .c_str()); 136cb93a386Sopenharmony_ci#else 137cb93a386Sopenharmony_ci static int overtimeDuration = 600; 138cb93a386Sopenharmony_ci static double maxBytesRate = 0.9; 139cb93a386Sopenharmony_ci#endif 140cb93a386Sopenharmony_ci fMaxBytesRate = maxBytesRate; 141cb93a386Sopenharmony_ci fOvertimeDuration = overtimeDuration; 142cb93a386Sopenharmony_ci} 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ciGrResourceCache::~GrResourceCache() { 145cb93a386Sopenharmony_ci this->releaseAll(); 146cb93a386Sopenharmony_ci} 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_civoid GrResourceCache::setLimit(size_t bytes) { 149cb93a386Sopenharmony_ci fMaxBytes = bytes; 150cb93a386Sopenharmony_ci this->purgeAsNeeded(); 151cb93a386Sopenharmony_ci} 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci#ifdef SKIA_DFX_FOR_OHOS 154cb93a386Sopenharmony_cistatic constexpr int MB = 1024 * 1024; 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci#ifdef SKIA_OHOS_FOR_OHOS_TRACE 157cb93a386Sopenharmony_cibool GrResourceCache::purgeUnlocakedResTraceEnabled_ = 158cb93a386Sopenharmony_ci std::atoi((OHOS::system::GetParameter("sys.graphic.skia.cache.debug", "0").c_str())) == 1; 159cb93a386Sopenharmony_ci#endif 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_civoid GrResourceCache::dumpInfo(SkString* out) { 162cb93a386Sopenharmony_ci if (out == nullptr) { 163cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::dumpInfo outPtr is nullptr!"); 164cb93a386Sopenharmony_ci return; 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci auto info = cacheInfo(); 167cb93a386Sopenharmony_ci constexpr uint8_t STEP_INDEX = 1; 168cb93a386Sopenharmony_ci SkTArray<SkString> lines; 169cb93a386Sopenharmony_ci SkStrSplit(info.substr(STEP_INDEX, info.length() - STEP_INDEX).c_str(), ";", &lines); 170cb93a386Sopenharmony_ci for (int i = 0; i < lines.size(); ++i) { 171cb93a386Sopenharmony_ci out->appendf(" %s\n", lines[i].c_str()); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci} 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_cistd::string GrResourceCache::cacheInfo() 176cb93a386Sopenharmony_ci{ 177cb93a386Sopenharmony_ci auto fPurgeableQueueInfoStr = cacheInfoPurgeableQueue(); 178cb93a386Sopenharmony_ci auto fNonpurgeableResourcesInfoStr = cacheInfoNoPurgeableQueue(); 179cb93a386Sopenharmony_ci size_t fRealAllocBytes = cacheInfoRealAllocSize(); 180cb93a386Sopenharmony_ci auto fRealAllocInfoStr = cacheInfoRealAllocQueue(); 181cb93a386Sopenharmony_ci auto fRealBytesOfPidInfoStr = realBytesOfPid(); 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ci std::ostringstream cacheInfoStream; 184cb93a386Sopenharmony_ci cacheInfoStream << "[fPurgeableQueueInfoStr.count : " << fPurgeableQueue.count() 185cb93a386Sopenharmony_ci << "; fNonpurgeableResources.count : " << fNonpurgeableResources.count() 186cb93a386Sopenharmony_ci << "; fBudgetedBytes : " << fBudgetedBytes 187cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fBudgetedBytes / MB) 188cb93a386Sopenharmony_ci << " MB) / " << fMaxBytes 189cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fMaxBytes / MB) 190cb93a386Sopenharmony_ci << " MB); fBudgetedCount : " << fBudgetedCount 191cb93a386Sopenharmony_ci << "; fBytes : " << fBytes 192cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fBytes / MB) 193cb93a386Sopenharmony_ci << " MB); fPurgeableBytes : " << fPurgeableBytes 194cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fPurgeableBytes / MB) 195cb93a386Sopenharmony_ci << " MB); fAllocImageBytes : " << fAllocImageBytes 196cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fAllocImageBytes / MB) 197cb93a386Sopenharmony_ci << " MB); fAllocBufferBytes : " << fAllocBufferBytes 198cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fAllocBufferBytes / MB) 199cb93a386Sopenharmony_ci << " MB); fRealAllocBytes : " << fRealAllocBytes 200cb93a386Sopenharmony_ci << "(" << static_cast<size_t>(fRealAllocBytes / MB) 201cb93a386Sopenharmony_ci << " MB); fTimestamp : " << fTimestamp 202cb93a386Sopenharmony_ci << "; " << fPurgeableQueueInfoStr << "; " << fNonpurgeableResourcesInfoStr 203cb93a386Sopenharmony_ci << "; " << fRealAllocInfoStr << "; " << fRealBytesOfPidInfoStr; 204cb93a386Sopenharmony_ci return cacheInfoStream.str(); 205cb93a386Sopenharmony_ci} 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_ci#ifdef SKIA_OHOS_FOR_OHOS_TRACE 208cb93a386Sopenharmony_civoid GrResourceCache::traceBeforePurgeUnlockRes(const std::string& method, SimpleCacheInfo& simpleCacheInfo) 209cb93a386Sopenharmony_ci{ 210cb93a386Sopenharmony_ci if (purgeUnlocakedResTraceEnabled_) { 211cb93a386Sopenharmony_ci StartTrace(HITRACE_TAG_GRAPHIC_AGP, method + " begin cacheInfo = " + cacheInfo()); 212cb93a386Sopenharmony_ci } else { 213cb93a386Sopenharmony_ci simpleCacheInfo.fPurgeableQueueCount = fPurgeableQueue.count(); 214cb93a386Sopenharmony_ci simpleCacheInfo.fNonpurgeableResourcesCount = fNonpurgeableResources.count(); 215cb93a386Sopenharmony_ci simpleCacheInfo.fPurgeableBytes = fPurgeableBytes; 216cb93a386Sopenharmony_ci simpleCacheInfo.fBudgetedCount = fBudgetedCount; 217cb93a386Sopenharmony_ci simpleCacheInfo.fBudgetedBytes = fBudgetedBytes; 218cb93a386Sopenharmony_ci simpleCacheInfo.fAllocImageBytes = fAllocImageBytes; 219cb93a386Sopenharmony_ci simpleCacheInfo.fAllocBufferBytes = fAllocBufferBytes; 220cb93a386Sopenharmony_ci } 221cb93a386Sopenharmony_ci} 222cb93a386Sopenharmony_ci 223cb93a386Sopenharmony_civoid GrResourceCache::traceAfterPurgeUnlockRes(const std::string& method, const SimpleCacheInfo& simpleCacheInfo) 224cb93a386Sopenharmony_ci{ 225cb93a386Sopenharmony_ci if (purgeUnlocakedResTraceEnabled_) { 226cb93a386Sopenharmony_ci HITRACE_OHOS_NAME_FMT_ALWAYS("%s end cacheInfo = %s", method.c_str(), cacheInfo().c_str()); 227cb93a386Sopenharmony_ci FinishTrace(HITRACE_TAG_GRAPHIC_AGP); 228cb93a386Sopenharmony_ci } else { 229cb93a386Sopenharmony_ci HITRACE_OHOS_NAME_FMT_ALWAYS("%s end cacheInfo = %s", 230cb93a386Sopenharmony_ci method.c_str(), cacheInfoComparison(simpleCacheInfo).c_str()); 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci} 233cb93a386Sopenharmony_ci 234cb93a386Sopenharmony_cistd::string GrResourceCache::cacheInfoComparison(const SimpleCacheInfo& simpleCacheInfo) 235cb93a386Sopenharmony_ci{ 236cb93a386Sopenharmony_ci std::ostringstream cacheInfoComparison; 237cb93a386Sopenharmony_ci cacheInfoComparison << "PurgeableCount : " << simpleCacheInfo.fPurgeableQueueCount 238cb93a386Sopenharmony_ci << " / " << fPurgeableQueue.count() 239cb93a386Sopenharmony_ci << "; NonpurgeableCount : " << simpleCacheInfo.fNonpurgeableResourcesCount 240cb93a386Sopenharmony_ci << " / " << fNonpurgeableResources.count() 241cb93a386Sopenharmony_ci << "; PurgeableBytes : " << simpleCacheInfo.fPurgeableBytes << " / " << fPurgeableBytes 242cb93a386Sopenharmony_ci << "; BudgetedCount : " << simpleCacheInfo.fBudgetedCount << " / " << fBudgetedCount 243cb93a386Sopenharmony_ci << "; BudgetedBytes : " << simpleCacheInfo.fBudgetedBytes << " / " << fBudgetedBytes 244cb93a386Sopenharmony_ci << "; AllocImageBytes : " << simpleCacheInfo.fAllocImageBytes << " / " << fAllocImageBytes 245cb93a386Sopenharmony_ci << "; AllocBufferBytes : " << simpleCacheInfo.fAllocBufferBytes << " / " << fAllocBufferBytes; 246cb93a386Sopenharmony_ci return cacheInfoComparison.str(); 247cb93a386Sopenharmony_ci} 248cb93a386Sopenharmony_ci#endif // SKIA_OHOS_FOR_OHOS_TRACE 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_cistd::string GrResourceCache::cacheInfoPurgeableQueue() 251cb93a386Sopenharmony_ci{ 252cb93a386Sopenharmony_ci std::map<uint32_t, int> purgSizeInfoWid; 253cb93a386Sopenharmony_ci std::map<uint32_t, int> purgCountInfoWid; 254cb93a386Sopenharmony_ci std::map<uint32_t, std::string> purgNameInfoWid; 255cb93a386Sopenharmony_ci std::map<uint32_t, int> purgPidInfoWid; 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_ci std::map<uint32_t, int> purgSizeInfoPid; 258cb93a386Sopenharmony_ci std::map<uint32_t, int> purgCountInfoPid; 259cb93a386Sopenharmony_ci std::map<uint32_t, std::string> purgNameInfoPid; 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci std::map<uint32_t, int> purgSizeInfoFid; 262cb93a386Sopenharmony_ci std::map<uint32_t, int> purgCountInfoFid; 263cb93a386Sopenharmony_ci std::map<uint32_t, std::string> purgNameInfoFid; 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ci int purgCountUnknown = 0; 266cb93a386Sopenharmony_ci int purgSizeUnknown = 0; 267cb93a386Sopenharmony_ci 268cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 269cb93a386Sopenharmony_ci auto resource = fPurgeableQueue.at(i); 270cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 271cb93a386Sopenharmony_ci if (resourceTag.fWid != 0) { 272cb93a386Sopenharmony_ci updatePurgeableWidMap(resource, purgNameInfoWid, purgSizeInfoWid, purgPidInfoWid, purgCountInfoWid); 273cb93a386Sopenharmony_ci } else if (resourceTag.fPid != 0) { 274cb93a386Sopenharmony_ci updatePurgeablePidMap(resource, purgNameInfoPid, purgSizeInfoPid, purgCountInfoPid); 275cb93a386Sopenharmony_ci } else if (resourceTag.fFid != 0) { 276cb93a386Sopenharmony_ci updatePurgeableFidMap(resource, purgNameInfoFid, purgSizeInfoFid, purgCountInfoFid); 277cb93a386Sopenharmony_ci } else { 278cb93a386Sopenharmony_ci purgCountUnknown++; 279cb93a386Sopenharmony_ci purgSizeUnknown += resource->gpuMemorySize(); 280cb93a386Sopenharmony_ci } 281cb93a386Sopenharmony_ci } 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci std::string infoStr; 284cb93a386Sopenharmony_ci if (purgSizeInfoWid.size() > 0) { 285cb93a386Sopenharmony_ci infoStr += ";PurgeableInfo_Node:["; 286cb93a386Sopenharmony_ci updatePurgeableWidInfo(infoStr, purgNameInfoWid, purgSizeInfoWid, purgPidInfoWid, purgCountInfoWid); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci if (purgSizeInfoPid.size() > 0) { 289cb93a386Sopenharmony_ci infoStr += ";PurgeableInfo_Pid:["; 290cb93a386Sopenharmony_ci updatePurgeablePidInfo(infoStr, purgNameInfoWid, purgSizeInfoWid, purgCountInfoWid); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci if (purgSizeInfoFid.size() > 0) { 293cb93a386Sopenharmony_ci infoStr += ";PurgeableInfo_Fid:["; 294cb93a386Sopenharmony_ci updatePurgeableFidInfo(infoStr, purgNameInfoFid, purgSizeInfoFid, purgCountInfoFid); 295cb93a386Sopenharmony_ci } 296cb93a386Sopenharmony_ci updatePurgeableUnknownInfo(infoStr, ";PurgeableInfo_Unknown:", purgCountUnknown, purgSizeUnknown); 297cb93a386Sopenharmony_ci return infoStr; 298cb93a386Sopenharmony_ci} 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_cistd::string GrResourceCache::cacheInfoNoPurgeableQueue() 301cb93a386Sopenharmony_ci{ 302cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgSizeInfoWid; 303cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgCountInfoWid; 304cb93a386Sopenharmony_ci std::map<uint32_t, std::string> noPurgNameInfoWid; 305cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgPidInfoWid; 306cb93a386Sopenharmony_ci 307cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgSizeInfoPid; 308cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgCountInfoPid; 309cb93a386Sopenharmony_ci std::map<uint32_t, std::string> noPurgNameInfoPid; 310cb93a386Sopenharmony_ci 311cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgSizeInfoFid; 312cb93a386Sopenharmony_ci std::map<uint32_t, int> noPurgCountInfoFid; 313cb93a386Sopenharmony_ci std::map<uint32_t, std::string> noPurgNameInfoFid; 314cb93a386Sopenharmony_ci 315cb93a386Sopenharmony_ci int noPurgCountUnknown = 0; 316cb93a386Sopenharmony_ci int noPurgSizeUnknown = 0; 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); i++) { 319cb93a386Sopenharmony_ci auto resource = fNonpurgeableResources[i]; 320cb93a386Sopenharmony_ci if (resource == nullptr) { 321cb93a386Sopenharmony_ci continue; 322cb93a386Sopenharmony_ci } 323cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 324cb93a386Sopenharmony_ci if (resourceTag.fWid != 0) { 325cb93a386Sopenharmony_ci updatePurgeableWidMap(resource, noPurgNameInfoWid, noPurgSizeInfoWid, noPurgPidInfoWid, noPurgCountInfoWid); 326cb93a386Sopenharmony_ci } else if (resourceTag.fPid != 0) { 327cb93a386Sopenharmony_ci updatePurgeablePidMap(resource, noPurgNameInfoPid, noPurgSizeInfoPid, noPurgCountInfoPid); 328cb93a386Sopenharmony_ci } else if (resourceTag.fFid != 0) { 329cb93a386Sopenharmony_ci updatePurgeableFidMap(resource, noPurgNameInfoFid, noPurgSizeInfoFid, noPurgCountInfoFid); 330cb93a386Sopenharmony_ci } else { 331cb93a386Sopenharmony_ci noPurgCountUnknown++; 332cb93a386Sopenharmony_ci noPurgSizeUnknown += resource->gpuMemorySize(); 333cb93a386Sopenharmony_ci } 334cb93a386Sopenharmony_ci } 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_ci std::string infoStr; 337cb93a386Sopenharmony_ci if (noPurgSizeInfoWid.size() > 0) { 338cb93a386Sopenharmony_ci infoStr += ";NonPurgeableInfo_Node:["; 339cb93a386Sopenharmony_ci updatePurgeableWidInfo(infoStr, noPurgNameInfoWid, noPurgSizeInfoWid, noPurgPidInfoWid, noPurgCountInfoWid); 340cb93a386Sopenharmony_ci } 341cb93a386Sopenharmony_ci if (noPurgSizeInfoPid.size() > 0) { 342cb93a386Sopenharmony_ci infoStr += ";NonPurgeableInfo_Pid:["; 343cb93a386Sopenharmony_ci updatePurgeablePidInfo(infoStr, noPurgNameInfoPid, noPurgSizeInfoPid, noPurgCountInfoPid); 344cb93a386Sopenharmony_ci } 345cb93a386Sopenharmony_ci if (noPurgSizeInfoFid.size() > 0) { 346cb93a386Sopenharmony_ci infoStr += ";NonPurgeableInfo_Fid:["; 347cb93a386Sopenharmony_ci updatePurgeableFidInfo(infoStr, noPurgNameInfoFid, noPurgSizeInfoFid, noPurgCountInfoFid); 348cb93a386Sopenharmony_ci } 349cb93a386Sopenharmony_ci updatePurgeableUnknownInfo(infoStr, ";NonPurgeableInfo_Unknown:", noPurgCountUnknown, noPurgSizeUnknown); 350cb93a386Sopenharmony_ci return infoStr; 351cb93a386Sopenharmony_ci} 352cb93a386Sopenharmony_ci 353cb93a386Sopenharmony_cisize_t GrResourceCache::cacheInfoRealAllocSize() 354cb93a386Sopenharmony_ci{ 355cb93a386Sopenharmony_ci size_t realAllocImageSize = 0; 356cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 357cb93a386Sopenharmony_ci auto resource = fPurgeableQueue.at(i); 358cb93a386Sopenharmony_ci if (resource == nullptr || !resource->isRealAlloc()) { 359cb93a386Sopenharmony_ci continue; 360cb93a386Sopenharmony_ci } 361cb93a386Sopenharmony_ci realAllocImageSize += resource->getRealAllocSize(); 362cb93a386Sopenharmony_ci } 363cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); i++) { 364cb93a386Sopenharmony_ci auto resource = fNonpurgeableResources[i]; 365cb93a386Sopenharmony_ci if (resource == nullptr || !resource->isRealAlloc()) { 366cb93a386Sopenharmony_ci continue; 367cb93a386Sopenharmony_ci } 368cb93a386Sopenharmony_ci realAllocImageSize += resource->getRealAllocSize(); 369cb93a386Sopenharmony_ci } 370cb93a386Sopenharmony_ci return realAllocImageSize; 371cb93a386Sopenharmony_ci} 372cb93a386Sopenharmony_ci 373cb93a386Sopenharmony_cistd::string GrResourceCache::cacheInfoRealAllocQueue() 374cb93a386Sopenharmony_ci{ 375cb93a386Sopenharmony_ci std::map<uint32_t, std::string> realAllocNameInfoWid; 376cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocSizeInfoWid; 377cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocPidInfoWid; 378cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocCountInfoWid; 379cb93a386Sopenharmony_ci 380cb93a386Sopenharmony_ci std::map<uint32_t, std::string> realAllocNameInfoPid; 381cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocSizeInfoPid; 382cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocCountInfoPid; 383cb93a386Sopenharmony_ci 384cb93a386Sopenharmony_ci std::map<uint32_t, std::string> realAllocNameInfoFid; 385cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocSizeInfoFid; 386cb93a386Sopenharmony_ci std::map<uint32_t, int> realAllocCountInfoFid; 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci int realAllocCountUnknown = 0; 389cb93a386Sopenharmony_ci int realAllocSizeUnknown = 0; 390cb93a386Sopenharmony_ci 391cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); i++) { 392cb93a386Sopenharmony_ci auto resource = fNonpurgeableResources[i]; 393cb93a386Sopenharmony_ci if (resource == nullptr || !resource->isRealAlloc()) { 394cb93a386Sopenharmony_ci continue; 395cb93a386Sopenharmony_ci } 396cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 397cb93a386Sopenharmony_ci if (resourceTag.fWid != 0) { 398cb93a386Sopenharmony_ci updateRealAllocWidMap(resource, realAllocNameInfoWid, realAllocSizeInfoWid, realAllocPidInfoWid, realAllocCountInfoWid); 399cb93a386Sopenharmony_ci } else if (resourceTag.fPid != 0) { 400cb93a386Sopenharmony_ci updateRealAllocPidMap(resource, realAllocNameInfoPid, realAllocSizeInfoPid, realAllocCountInfoPid); 401cb93a386Sopenharmony_ci } else if (resourceTag.fFid != 0) { 402cb93a386Sopenharmony_ci updateRealAllocFidMap(resource, realAllocNameInfoFid, realAllocSizeInfoFid, realAllocCountInfoFid); 403cb93a386Sopenharmony_ci } else { 404cb93a386Sopenharmony_ci realAllocCountUnknown++; 405cb93a386Sopenharmony_ci realAllocSizeUnknown += resource->getRealAllocSize(); 406cb93a386Sopenharmony_ci } 407cb93a386Sopenharmony_ci } 408cb93a386Sopenharmony_ci 409cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 410cb93a386Sopenharmony_ci auto resource = fPurgeableQueue.at(i); 411cb93a386Sopenharmony_ci if (resource == nullptr || !resource->isRealAlloc()) { 412cb93a386Sopenharmony_ci continue; 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 415cb93a386Sopenharmony_ci if (resourceTag.fWid != 0) { 416cb93a386Sopenharmony_ci updateRealAllocWidMap(resource, realAllocNameInfoWid, realAllocSizeInfoWid, realAllocPidInfoWid, realAllocCountInfoWid); 417cb93a386Sopenharmony_ci } else if (resourceTag.fPid != 0) { 418cb93a386Sopenharmony_ci updateRealAllocPidMap(resource, realAllocNameInfoPid, realAllocSizeInfoPid, realAllocCountInfoPid); 419cb93a386Sopenharmony_ci } else if (resourceTag.fFid != 0) { 420cb93a386Sopenharmony_ci updateRealAllocFidMap(resource, realAllocNameInfoFid, realAllocSizeInfoFid, realAllocCountInfoFid); 421cb93a386Sopenharmony_ci } else { 422cb93a386Sopenharmony_ci realAllocCountUnknown++; 423cb93a386Sopenharmony_ci realAllocSizeUnknown += resource->getRealAllocSize(); 424cb93a386Sopenharmony_ci } 425cb93a386Sopenharmony_ci } 426cb93a386Sopenharmony_ci 427cb93a386Sopenharmony_ci std::string infoStr; 428cb93a386Sopenharmony_ci if (realAllocSizeInfoWid.size() > 0) { 429cb93a386Sopenharmony_ci infoStr += ";RealAllocInfo_Node:["; 430cb93a386Sopenharmony_ci updatePurgeableWidInfo(infoStr, realAllocNameInfoWid, realAllocSizeInfoWid, realAllocPidInfoWid, realAllocCountInfoWid); 431cb93a386Sopenharmony_ci } 432cb93a386Sopenharmony_ci if (realAllocSizeInfoPid.size() > 0) { 433cb93a386Sopenharmony_ci infoStr += ";RealAllocInfo_Pid:["; 434cb93a386Sopenharmony_ci updatePurgeablePidInfo(infoStr, realAllocNameInfoPid, realAllocSizeInfoPid, realAllocCountInfoPid); 435cb93a386Sopenharmony_ci } 436cb93a386Sopenharmony_ci if (realAllocSizeInfoFid.size() > 0) { 437cb93a386Sopenharmony_ci infoStr += ";RealAllocInfo_Fid:["; 438cb93a386Sopenharmony_ci updatePurgeableFidInfo(infoStr, realAllocNameInfoFid, realAllocSizeInfoFid, realAllocCountInfoFid); 439cb93a386Sopenharmony_ci } 440cb93a386Sopenharmony_ci updatePurgeableUnknownInfo(infoStr, ";RealAllocInfo_Unknown:", realAllocCountUnknown, realAllocSizeUnknown); 441cb93a386Sopenharmony_ci return infoStr; 442cb93a386Sopenharmony_ci} 443cb93a386Sopenharmony_ci 444cb93a386Sopenharmony_cistd::string GrResourceCache::realBytesOfPid() 445cb93a386Sopenharmony_ci{ 446cb93a386Sopenharmony_ci std::string infoStr; 447cb93a386Sopenharmony_ci infoStr += ";fBytesOfPid : ["; 448cb93a386Sopenharmony_ci if (fBytesOfPid.size() > 0) { 449cb93a386Sopenharmony_ci for (auto it = fBytesOfPid.begin(); it != fBytesOfPid.end(); it++) { 450cb93a386Sopenharmony_ci infoStr += std::to_string(it->first) + ":" + std::to_string(it->second) + ", "; 451cb93a386Sopenharmony_ci } 452cb93a386Sopenharmony_ci } 453cb93a386Sopenharmony_ci infoStr += "]"; 454cb93a386Sopenharmony_ci return infoStr; 455cb93a386Sopenharmony_ci} 456cb93a386Sopenharmony_ci 457cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeableWidMap(GrGpuResource* resource, 458cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoWid, 459cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoWid, 460cb93a386Sopenharmony_ci std::map<uint32_t, int>& pidInfoWid, 461cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoWid) 462cb93a386Sopenharmony_ci{ 463cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 464cb93a386Sopenharmony_ci auto it = sizeInfoWid.find(resourceTag.fWid); 465cb93a386Sopenharmony_ci if (it != sizeInfoWid.end()) { 466cb93a386Sopenharmony_ci sizeInfoWid[resourceTag.fWid] = it->second + resource->gpuMemorySize(); 467cb93a386Sopenharmony_ci countInfoWid[resourceTag.fWid]++; 468cb93a386Sopenharmony_ci } else { 469cb93a386Sopenharmony_ci sizeInfoWid[resourceTag.fWid] = resource->gpuMemorySize(); 470cb93a386Sopenharmony_ci nameInfoWid[resourceTag.fWid] = resourceTag.fName; 471cb93a386Sopenharmony_ci pidInfoWid[resourceTag.fWid] = resourceTag.fPid; 472cb93a386Sopenharmony_ci countInfoWid[resourceTag.fWid] = 1; 473cb93a386Sopenharmony_ci } 474cb93a386Sopenharmony_ci} 475cb93a386Sopenharmony_ci 476cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeablePidMap(GrGpuResource* resource, 477cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoPid, 478cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoPid, 479cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoPid) 480cb93a386Sopenharmony_ci{ 481cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 482cb93a386Sopenharmony_ci auto it = sizeInfoPid.find(resourceTag.fPid); 483cb93a386Sopenharmony_ci if (it != sizeInfoPid.end()) { 484cb93a386Sopenharmony_ci sizeInfoPid[resourceTag.fPid] = it->second + resource->gpuMemorySize(); 485cb93a386Sopenharmony_ci countInfoPid[resourceTag.fPid]++; 486cb93a386Sopenharmony_ci } else { 487cb93a386Sopenharmony_ci sizeInfoPid[resourceTag.fPid] = resource->gpuMemorySize(); 488cb93a386Sopenharmony_ci nameInfoPid[resourceTag.fPid] = resourceTag.fName; 489cb93a386Sopenharmony_ci countInfoPid[resourceTag.fPid] = 1; 490cb93a386Sopenharmony_ci } 491cb93a386Sopenharmony_ci} 492cb93a386Sopenharmony_ci 493cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeableFidMap(GrGpuResource* resource, 494cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoFid, 495cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoFid, 496cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoFid) 497cb93a386Sopenharmony_ci{ 498cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 499cb93a386Sopenharmony_ci auto it = sizeInfoFid.find(resourceTag.fFid); 500cb93a386Sopenharmony_ci if (it != sizeInfoFid.end()) { 501cb93a386Sopenharmony_ci sizeInfoFid[resourceTag.fFid] = it->second + resource->gpuMemorySize(); 502cb93a386Sopenharmony_ci countInfoFid[resourceTag.fFid]++; 503cb93a386Sopenharmony_ci } else { 504cb93a386Sopenharmony_ci sizeInfoFid[resourceTag.fFid] = resource->gpuMemorySize(); 505cb93a386Sopenharmony_ci nameInfoFid[resourceTag.fFid] = resourceTag.fName; 506cb93a386Sopenharmony_ci countInfoFid[resourceTag.fFid] = 1; 507cb93a386Sopenharmony_ci } 508cb93a386Sopenharmony_ci} 509cb93a386Sopenharmony_ci 510cb93a386Sopenharmony_civoid GrResourceCache::updateRealAllocWidMap(GrGpuResource* resource, 511cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoWid, 512cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoWid, 513cb93a386Sopenharmony_ci std::map<uint32_t, int>& pidInfoWid, 514cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoWid) 515cb93a386Sopenharmony_ci{ 516cb93a386Sopenharmony_ci size_t size = resource->getRealAllocSize(); 517cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 518cb93a386Sopenharmony_ci auto it = sizeInfoWid.find(resourceTag.fWid); 519cb93a386Sopenharmony_ci if (it != sizeInfoWid.end()) { 520cb93a386Sopenharmony_ci sizeInfoWid[resourceTag.fWid] = it->second + size; 521cb93a386Sopenharmony_ci countInfoWid[resourceTag.fWid]++; 522cb93a386Sopenharmony_ci } else { 523cb93a386Sopenharmony_ci sizeInfoWid[resourceTag.fWid] = size; 524cb93a386Sopenharmony_ci nameInfoWid[resourceTag.fWid] = resourceTag.fName; 525cb93a386Sopenharmony_ci pidInfoWid[resourceTag.fWid] = resourceTag.fPid; 526cb93a386Sopenharmony_ci countInfoWid[resourceTag.fWid] = 1; 527cb93a386Sopenharmony_ci } 528cb93a386Sopenharmony_ci} 529cb93a386Sopenharmony_ci 530cb93a386Sopenharmony_civoid GrResourceCache::updateRealAllocPidMap(GrGpuResource* resource, 531cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoPid, 532cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoPid, 533cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoPid) 534cb93a386Sopenharmony_ci{ 535cb93a386Sopenharmony_ci size_t size = resource->getRealAllocSize(); 536cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 537cb93a386Sopenharmony_ci auto it = sizeInfoPid.find(resourceTag.fPid); 538cb93a386Sopenharmony_ci if (it != sizeInfoPid.end()) { 539cb93a386Sopenharmony_ci sizeInfoPid[resourceTag.fPid] = it->second + size; 540cb93a386Sopenharmony_ci countInfoPid[resourceTag.fPid]++; 541cb93a386Sopenharmony_ci } else { 542cb93a386Sopenharmony_ci sizeInfoPid[resourceTag.fPid] = size; 543cb93a386Sopenharmony_ci nameInfoPid[resourceTag.fPid] = resourceTag.fName; 544cb93a386Sopenharmony_ci countInfoPid[resourceTag.fPid] = 1; 545cb93a386Sopenharmony_ci } 546cb93a386Sopenharmony_ci} 547cb93a386Sopenharmony_ci 548cb93a386Sopenharmony_civoid GrResourceCache::updateRealAllocFidMap(GrGpuResource* resource, 549cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoFid, 550cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoFid, 551cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoFid) 552cb93a386Sopenharmony_ci{ 553cb93a386Sopenharmony_ci size_t size = resource->getRealAllocSize(); 554cb93a386Sopenharmony_ci auto resourceTag = resource->getResourceTag(); 555cb93a386Sopenharmony_ci auto it = sizeInfoFid.find(resourceTag.fFid); 556cb93a386Sopenharmony_ci if (it != sizeInfoFid.end()) { 557cb93a386Sopenharmony_ci sizeInfoFid[resourceTag.fFid] = it->second + size; 558cb93a386Sopenharmony_ci countInfoFid[resourceTag.fFid]++; 559cb93a386Sopenharmony_ci } else { 560cb93a386Sopenharmony_ci sizeInfoFid[resourceTag.fFid] = size; 561cb93a386Sopenharmony_ci nameInfoFid[resourceTag.fFid] = resourceTag.fName; 562cb93a386Sopenharmony_ci countInfoFid[resourceTag.fFid] = 1; 563cb93a386Sopenharmony_ci } 564cb93a386Sopenharmony_ci} 565cb93a386Sopenharmony_ci 566cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeableWidInfo(std::string& infoStr, 567cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoWid, 568cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoWid, 569cb93a386Sopenharmony_ci std::map<uint32_t, int>& pidInfoWid, 570cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoWid) 571cb93a386Sopenharmony_ci{ 572cb93a386Sopenharmony_ci for (auto it = sizeInfoWid.begin(); it != sizeInfoWid.end(); it++) { 573cb93a386Sopenharmony_ci infoStr += "[" + nameInfoWid[it->first] + 574cb93a386Sopenharmony_ci ",pid=" + std::to_string(pidInfoWid[it->first]) + 575cb93a386Sopenharmony_ci ",NodeId=" + std::to_string(it->first & 0xFFFFFFFF) + 576cb93a386Sopenharmony_ci ",count=" + std::to_string(countInfoWid[it->first]) + 577cb93a386Sopenharmony_ci ",size=" + std::to_string(it->second) + 578cb93a386Sopenharmony_ci "(" + std::to_string(it->second / MB) + " MB)],"; 579cb93a386Sopenharmony_ci } 580cb93a386Sopenharmony_ci infoStr += ']'; 581cb93a386Sopenharmony_ci} 582cb93a386Sopenharmony_ci 583cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeablePidInfo(std::string& infoStr, 584cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoPid, 585cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoPid, 586cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoPid) 587cb93a386Sopenharmony_ci{ 588cb93a386Sopenharmony_ci for (auto it = sizeInfoPid.begin(); it != sizeInfoPid.end(); it++) { 589cb93a386Sopenharmony_ci infoStr += "[" + nameInfoPid[it->first] + 590cb93a386Sopenharmony_ci ",pid=" + std::to_string(it->first) + 591cb93a386Sopenharmony_ci ",count=" + std::to_string(countInfoPid[it->first]) + 592cb93a386Sopenharmony_ci ",size=" + std::to_string(it->second) + 593cb93a386Sopenharmony_ci "(" + std::to_string(it->second / MB) + " MB)],"; 594cb93a386Sopenharmony_ci } 595cb93a386Sopenharmony_ci infoStr += ']'; 596cb93a386Sopenharmony_ci} 597cb93a386Sopenharmony_ci 598cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeableFidInfo(std::string& infoStr, 599cb93a386Sopenharmony_ci std::map<uint32_t, std::string>& nameInfoFid, 600cb93a386Sopenharmony_ci std::map<uint32_t, int>& sizeInfoFid, 601cb93a386Sopenharmony_ci std::map<uint32_t, int>& countInfoFid) 602cb93a386Sopenharmony_ci{ 603cb93a386Sopenharmony_ci for (auto it = sizeInfoFid.begin(); it != sizeInfoFid.end(); it++) { 604cb93a386Sopenharmony_ci infoStr += "[" + nameInfoFid[it->first] + 605cb93a386Sopenharmony_ci ",typeid=" + std::to_string(it->first) + 606cb93a386Sopenharmony_ci ",count=" + std::to_string(countInfoFid[it->first]) + 607cb93a386Sopenharmony_ci ",size=" + std::to_string(it->second) + 608cb93a386Sopenharmony_ci "(" + std::to_string(it->second / MB) + " MB)],"; 609cb93a386Sopenharmony_ci } 610cb93a386Sopenharmony_ci infoStr += ']'; 611cb93a386Sopenharmony_ci} 612cb93a386Sopenharmony_ci 613cb93a386Sopenharmony_civoid GrResourceCache::updatePurgeableUnknownInfo( 614cb93a386Sopenharmony_ci std::string& infoStr, const std::string& unknownPrefix, const int countUnknown, const int sizeUnknown) 615cb93a386Sopenharmony_ci{ 616cb93a386Sopenharmony_ci if (countUnknown > 0) { 617cb93a386Sopenharmony_ci infoStr += unknownPrefix + 618cb93a386Sopenharmony_ci "[count=" + std::to_string(countUnknown) + 619cb93a386Sopenharmony_ci ",size=" + std::to_string(sizeUnknown) + 620cb93a386Sopenharmony_ci "(" + std::to_string(sizeUnknown / MB) + "MB)]"; 621cb93a386Sopenharmony_ci } 622cb93a386Sopenharmony_ci} 623cb93a386Sopenharmony_ci#endif 624cb93a386Sopenharmony_ci 625cb93a386Sopenharmony_civoid GrResourceCache::insertResource(GrGpuResource* resource) 626cb93a386Sopenharmony_ci{ 627cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 628cb93a386Sopenharmony_ci SkASSERT(resource); 629cb93a386Sopenharmony_ci SkASSERT(!this->isInCache(resource)); 630cb93a386Sopenharmony_ci SkASSERT(!resource->wasDestroyed()); 631cb93a386Sopenharmony_ci SkASSERT(!resource->resourcePriv().isPurgeable()); 632cb93a386Sopenharmony_ci if (!resource || this->isInCache(resource) || resource->wasDestroyed() || resource->resourcePriv().isPurgeable()) { 633cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::insertResource resource is invalid!!!"); 634cb93a386Sopenharmony_ci return; 635cb93a386Sopenharmony_ci } 636cb93a386Sopenharmony_ci // We must set the timestamp before adding to the array in case the timestamp wraps and we wind 637cb93a386Sopenharmony_ci // up iterating over all the resources that already have timestamps. 638cb93a386Sopenharmony_ci resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 639cb93a386Sopenharmony_ci 640cb93a386Sopenharmony_ci this->addToNonpurgeableArray(resource); 641cb93a386Sopenharmony_ci 642cb93a386Sopenharmony_ci size_t size = resource->gpuMemorySize(); 643cb93a386Sopenharmony_ci SkDEBUGCODE(++fCount;) 644cb93a386Sopenharmony_ci fBytes += size; 645cb93a386Sopenharmony_ci 646cb93a386Sopenharmony_ci // OH ISSUE: memory count 647cb93a386Sopenharmony_ci auto pid = resource->getResourceTag().fPid; 648cb93a386Sopenharmony_ci if (pid && resource->isRealAlloc()) { 649cb93a386Sopenharmony_ci auto& pidSize = fBytesOfPid[pid]; 650cb93a386Sopenharmony_ci pidSize += resource->getRealAllocSize(); 651cb93a386Sopenharmony_ci fUpdatedBytesOfPid[pid] = pidSize; 652cb93a386Sopenharmony_ci if (pidSize >= fMemoryControl_ && fExitedPid_.find(pid) == fExitedPid_.end() && fMemoryOverflowCallback_) { 653cb93a386Sopenharmony_ci fMemoryOverflowCallback_(pid, pidSize, true); 654cb93a386Sopenharmony_ci fExitedPid_.insert(pid); 655cb93a386Sopenharmony_ci SkDebugf("OHOS resource overflow! pid[%{public}d], size[%{public}zu]", pid, pidSize); 656cb93a386Sopenharmony_ci#ifdef SKIA_OHOS_FOR_OHOS_TRACE 657cb93a386Sopenharmony_ci HITRACE_OHOS_NAME_FMT_ALWAYS("OHOS gpu resource overflow: pid(%u), size:(%u)", pid, pidSize); 658cb93a386Sopenharmony_ci#endif 659cb93a386Sopenharmony_ci } 660cb93a386Sopenharmony_ci } 661cb93a386Sopenharmony_ci 662cb93a386Sopenharmony_ci#if GR_CACHE_STATS 663cb93a386Sopenharmony_ci fHighWaterCount = std::max(this->getResourceCount(), fHighWaterCount); 664cb93a386Sopenharmony_ci fHighWaterBytes = std::max(fBytes, fHighWaterBytes); 665cb93a386Sopenharmony_ci#endif 666cb93a386Sopenharmony_ci if (GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType()) { 667cb93a386Sopenharmony_ci ++fBudgetedCount; 668cb93a386Sopenharmony_ci fBudgetedBytes += size; 669cb93a386Sopenharmony_ci TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 670cb93a386Sopenharmony_ci fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 671cb93a386Sopenharmony_ci#if GR_CACHE_STATS 672cb93a386Sopenharmony_ci fBudgetedHighWaterCount = std::max(fBudgetedCount, fBudgetedHighWaterCount); 673cb93a386Sopenharmony_ci fBudgetedHighWaterBytes = std::max(fBudgetedBytes, fBudgetedHighWaterBytes); 674cb93a386Sopenharmony_ci#endif 675cb93a386Sopenharmony_ci } 676cb93a386Sopenharmony_ci SkASSERT(!resource->cacheAccess().isUsableAsScratch()); 677cb93a386Sopenharmony_ci#ifdef SKIA_OHOS_FOR_OHOS_TRACE 678cb93a386Sopenharmony_ci if (fBudgetedBytes >= fMaxBytes) { 679cb93a386Sopenharmony_ci HITRACE_OHOS_NAME_FMT_ALWAYS("cache over fBudgetedBytes:(%u), fMaxBytes:(%u)", fBudgetedBytes, fMaxBytes); 680cb93a386Sopenharmony_ci#ifdef SKIA_DFX_FOR_OHOS 681cb93a386Sopenharmony_ci SimpleCacheInfo simpleCacheInfo; 682cb93a386Sopenharmony_ci traceBeforePurgeUnlockRes("insertResource", simpleCacheInfo); 683cb93a386Sopenharmony_ci#endif 684cb93a386Sopenharmony_ci this->purgeAsNeeded(); 685cb93a386Sopenharmony_ci#ifdef SKIA_DFX_FOR_OHOS 686cb93a386Sopenharmony_ci traceAfterPurgeUnlockRes("insertResource", simpleCacheInfo); 687cb93a386Sopenharmony_ci#endif 688cb93a386Sopenharmony_ci } else { 689cb93a386Sopenharmony_ci this->purgeAsNeeded(); 690cb93a386Sopenharmony_ci } 691cb93a386Sopenharmony_ci#else 692cb93a386Sopenharmony_ci this->purgeAsNeeded(); 693cb93a386Sopenharmony_ci#endif 694cb93a386Sopenharmony_ci} 695cb93a386Sopenharmony_ci 696cb93a386Sopenharmony_civoid GrResourceCache::removeResource(GrGpuResource* resource) { 697cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 698cb93a386Sopenharmony_ci this->validate(); 699cb93a386Sopenharmony_ci SkASSERT(this->isInCache(resource)); 700cb93a386Sopenharmony_ci 701cb93a386Sopenharmony_ci size_t size = resource->gpuMemorySize(); 702cb93a386Sopenharmony_ci if (resource->resourcePriv().isPurgeable() && this->isInPurgeableCache(resource)) { 703cb93a386Sopenharmony_ci fPurgeableQueue.remove(resource); 704cb93a386Sopenharmony_ci fPurgeableBytes -= size; 705cb93a386Sopenharmony_ci } else if (this->isInNonpurgeableCache(resource)) { 706cb93a386Sopenharmony_ci this->removeFromNonpurgeableArray(resource); 707cb93a386Sopenharmony_ci } 708cb93a386Sopenharmony_ci 709cb93a386Sopenharmony_ci SkDEBUGCODE(--fCount;) 710cb93a386Sopenharmony_ci fBytes -= size; 711cb93a386Sopenharmony_ci 712cb93a386Sopenharmony_ci // OH ISSUE: memory count 713cb93a386Sopenharmony_ci auto pid = resource->getResourceTag().fPid; 714cb93a386Sopenharmony_ci if (pid && resource->isRealAlloc()) { 715cb93a386Sopenharmony_ci auto& pidSize = fBytesOfPid[pid]; 716cb93a386Sopenharmony_ci pidSize -= resource->getRealAllocSize(); 717cb93a386Sopenharmony_ci fUpdatedBytesOfPid[pid] = pidSize; 718cb93a386Sopenharmony_ci if (pidSize == 0) { 719cb93a386Sopenharmony_ci fBytesOfPid.erase(pid); 720cb93a386Sopenharmony_ci } 721cb93a386Sopenharmony_ci } 722cb93a386Sopenharmony_ci 723cb93a386Sopenharmony_ci if (GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType()) { 724cb93a386Sopenharmony_ci --fBudgetedCount; 725cb93a386Sopenharmony_ci fBudgetedBytes -= size; 726cb93a386Sopenharmony_ci TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 727cb93a386Sopenharmony_ci fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 728cb93a386Sopenharmony_ci } 729cb93a386Sopenharmony_ci 730cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 731cb93a386Sopenharmony_ci fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 732cb93a386Sopenharmony_ci } 733cb93a386Sopenharmony_ci if (resource->getUniqueKey().isValid()) { 734cb93a386Sopenharmony_ci fUniqueHash.remove(resource->getUniqueKey()); 735cb93a386Sopenharmony_ci } 736cb93a386Sopenharmony_ci this->validate(); 737cb93a386Sopenharmony_ci} 738cb93a386Sopenharmony_ci 739cb93a386Sopenharmony_civoid GrResourceCache::abandonAll() { 740cb93a386Sopenharmony_ci AutoValidate av(this); 741cb93a386Sopenharmony_ci 742cb93a386Sopenharmony_ci // We need to make sure to free any resources that were waiting on a free message but never 743cb93a386Sopenharmony_ci // received one. 744cb93a386Sopenharmony_ci fTexturesAwaitingUnref.reset(); 745cb93a386Sopenharmony_ci 746cb93a386Sopenharmony_ci while (fNonpurgeableResources.count()) { 747cb93a386Sopenharmony_ci GrGpuResource* back = *(fNonpurgeableResources.end() - 1); 748cb93a386Sopenharmony_ci SkASSERT(!back->wasDestroyed()); 749cb93a386Sopenharmony_ci back->cacheAccess().abandon(); 750cb93a386Sopenharmony_ci } 751cb93a386Sopenharmony_ci 752cb93a386Sopenharmony_ci while (fPurgeableQueue.count()) { 753cb93a386Sopenharmony_ci GrGpuResource* top = fPurgeableQueue.peek(); 754cb93a386Sopenharmony_ci SkASSERT(!top->wasDestroyed()); 755cb93a386Sopenharmony_ci top->cacheAccess().abandon(); 756cb93a386Sopenharmony_ci } 757cb93a386Sopenharmony_ci 758cb93a386Sopenharmony_ci fThreadSafeCache->dropAllRefs(); 759cb93a386Sopenharmony_ci 760cb93a386Sopenharmony_ci SkASSERT(!fScratchMap.count()); 761cb93a386Sopenharmony_ci SkASSERT(!fUniqueHash.count()); 762cb93a386Sopenharmony_ci SkASSERT(!fCount); 763cb93a386Sopenharmony_ci SkASSERT(!this->getResourceCount()); 764cb93a386Sopenharmony_ci SkASSERT(!fBytes); 765cb93a386Sopenharmony_ci SkASSERT(!fBudgetedCount); 766cb93a386Sopenharmony_ci SkASSERT(!fBudgetedBytes); 767cb93a386Sopenharmony_ci SkASSERT(!fPurgeableBytes); 768cb93a386Sopenharmony_ci SkASSERT(!fTexturesAwaitingUnref.count()); 769cb93a386Sopenharmony_ci} 770cb93a386Sopenharmony_ci 771cb93a386Sopenharmony_civoid GrResourceCache::releaseAll() { 772cb93a386Sopenharmony_ci AutoValidate av(this); 773cb93a386Sopenharmony_ci 774cb93a386Sopenharmony_ci fThreadSafeCache->dropAllRefs(); 775cb93a386Sopenharmony_ci 776cb93a386Sopenharmony_ci this->processFreedGpuResources(); 777cb93a386Sopenharmony_ci 778cb93a386Sopenharmony_ci // We need to make sure to free any resources that were waiting on a free message but never 779cb93a386Sopenharmony_ci // received one. 780cb93a386Sopenharmony_ci fTexturesAwaitingUnref.reset(); 781cb93a386Sopenharmony_ci 782cb93a386Sopenharmony_ci SkASSERT(fProxyProvider); // better have called setProxyProvider 783cb93a386Sopenharmony_ci SkASSERT(fThreadSafeCache); // better have called setThreadSafeCache too 784cb93a386Sopenharmony_ci 785cb93a386Sopenharmony_ci // We must remove the uniqueKeys from the proxies here. While they possess a uniqueKey 786cb93a386Sopenharmony_ci // they also have a raw pointer back to this class (which is presumably going away)! 787cb93a386Sopenharmony_ci fProxyProvider->removeAllUniqueKeys(); 788cb93a386Sopenharmony_ci 789cb93a386Sopenharmony_ci while (fNonpurgeableResources.count()) { 790cb93a386Sopenharmony_ci GrGpuResource* back = *(fNonpurgeableResources.end() - 1); 791cb93a386Sopenharmony_ci SkASSERT(!back->wasDestroyed()); 792cb93a386Sopenharmony_ci back->cacheAccess().release(); 793cb93a386Sopenharmony_ci } 794cb93a386Sopenharmony_ci 795cb93a386Sopenharmony_ci while (fPurgeableQueue.count()) { 796cb93a386Sopenharmony_ci GrGpuResource* top = fPurgeableQueue.peek(); 797cb93a386Sopenharmony_ci SkASSERT(!top->wasDestroyed()); 798cb93a386Sopenharmony_ci top->cacheAccess().release(); 799cb93a386Sopenharmony_ci } 800cb93a386Sopenharmony_ci 801cb93a386Sopenharmony_ci SkASSERT(!fScratchMap.count()); 802cb93a386Sopenharmony_ci SkASSERT(!fUniqueHash.count()); 803cb93a386Sopenharmony_ci SkASSERT(!fCount); 804cb93a386Sopenharmony_ci SkASSERT(!this->getResourceCount()); 805cb93a386Sopenharmony_ci SkASSERT(!fBytes); 806cb93a386Sopenharmony_ci SkASSERT(!fBudgetedCount); 807cb93a386Sopenharmony_ci SkASSERT(!fBudgetedBytes); 808cb93a386Sopenharmony_ci SkASSERT(!fPurgeableBytes); 809cb93a386Sopenharmony_ci SkASSERT(!fTexturesAwaitingUnref.count()); 810cb93a386Sopenharmony_ci} 811cb93a386Sopenharmony_ci 812cb93a386Sopenharmony_civoid GrResourceCache::releaseByTag(const GrGpuResourceTag& tag) { 813cb93a386Sopenharmony_ci AutoValidate av(this); 814cb93a386Sopenharmony_ci this->processFreedGpuResources(); 815cb93a386Sopenharmony_ci SkASSERT(fProxyProvider); // better have called setProxyProvider 816cb93a386Sopenharmony_ci std::vector<GrGpuResource*> recycleVector; 817cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); i++) { 818cb93a386Sopenharmony_ci GrGpuResource* resource = fNonpurgeableResources[i]; 819cb93a386Sopenharmony_ci if (tag.filter(resource->getResourceTag())) { 820cb93a386Sopenharmony_ci recycleVector.emplace_back(resource); 821cb93a386Sopenharmony_ci if (resource->getUniqueKey().isValid()) { 822cb93a386Sopenharmony_ci fProxyProvider->processInvalidUniqueKey(resource->getUniqueKey(), nullptr, 823cb93a386Sopenharmony_ci GrProxyProvider::InvalidateGPUResource::kNo); 824cb93a386Sopenharmony_ci } 825cb93a386Sopenharmony_ci } 826cb93a386Sopenharmony_ci } 827cb93a386Sopenharmony_ci 828cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 829cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 830cb93a386Sopenharmony_ci if (tag.filter(resource->getResourceTag())) { 831cb93a386Sopenharmony_ci recycleVector.emplace_back(resource); 832cb93a386Sopenharmony_ci if (resource->getUniqueKey().isValid()) { 833cb93a386Sopenharmony_ci fProxyProvider->processInvalidUniqueKey(resource->getUniqueKey(), nullptr, 834cb93a386Sopenharmony_ci GrProxyProvider::InvalidateGPUResource::kNo); 835cb93a386Sopenharmony_ci } 836cb93a386Sopenharmony_ci } 837cb93a386Sopenharmony_ci } 838cb93a386Sopenharmony_ci 839cb93a386Sopenharmony_ci for (auto resource : recycleVector) { 840cb93a386Sopenharmony_ci SkASSERT(!resource->wasDestroyed()); 841cb93a386Sopenharmony_ci resource->cacheAccess().release(); 842cb93a386Sopenharmony_ci } 843cb93a386Sopenharmony_ci} 844cb93a386Sopenharmony_ci 845cb93a386Sopenharmony_civoid GrResourceCache::setCurrentGrResourceTag(const GrGpuResourceTag& tag) { 846cb93a386Sopenharmony_ci if (tag.isGrTagValid()) { 847cb93a386Sopenharmony_ci grResourceTagCacheStack.push(tag); 848cb93a386Sopenharmony_ci return; 849cb93a386Sopenharmony_ci } 850cb93a386Sopenharmony_ci if (!grResourceTagCacheStack.empty()) { 851cb93a386Sopenharmony_ci grResourceTagCacheStack.pop(); 852cb93a386Sopenharmony_ci } 853cb93a386Sopenharmony_ci} 854cb93a386Sopenharmony_ci 855cb93a386Sopenharmony_civoid GrResourceCache::popGrResourceTag() 856cb93a386Sopenharmony_ci{ 857cb93a386Sopenharmony_ci if (!grResourceTagCacheStack.empty()) { 858cb93a386Sopenharmony_ci grResourceTagCacheStack.pop(); 859cb93a386Sopenharmony_ci } 860cb93a386Sopenharmony_ci} 861cb93a386Sopenharmony_ci 862cb93a386Sopenharmony_ciGrGpuResourceTag GrResourceCache::getCurrentGrResourceTag() const { 863cb93a386Sopenharmony_ci if (grResourceTagCacheStack.empty()) { 864cb93a386Sopenharmony_ci return{}; 865cb93a386Sopenharmony_ci } 866cb93a386Sopenharmony_ci return grResourceTagCacheStack.top(); 867cb93a386Sopenharmony_ci} 868cb93a386Sopenharmony_ci 869cb93a386Sopenharmony_cistd::set<GrGpuResourceTag> GrResourceCache::getAllGrGpuResourceTags() const { 870cb93a386Sopenharmony_ci std::set<GrGpuResourceTag> result; 871cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 872cb93a386Sopenharmony_ci auto tag = fNonpurgeableResources[i]->getResourceTag(); 873cb93a386Sopenharmony_ci result.insert(tag); 874cb93a386Sopenharmony_ci } 875cb93a386Sopenharmony_ci return result; 876cb93a386Sopenharmony_ci} 877cb93a386Sopenharmony_ci 878cb93a386Sopenharmony_ci// OH ISSUE: get the memory information of the updated pid. 879cb93a386Sopenharmony_civoid GrResourceCache::getUpdatedMemoryMap(std::unordered_map<int32_t, size_t> &out) 880cb93a386Sopenharmony_ci{ 881cb93a386Sopenharmony_ci fUpdatedBytesOfPid.swap(out); 882cb93a386Sopenharmony_ci} 883cb93a386Sopenharmony_ci 884cb93a386Sopenharmony_ci// OH ISSUE: init gpu memory limit. 885cb93a386Sopenharmony_civoid GrResourceCache::initGpuMemoryLimit(MemoryOverflowCalllback callback, uint64_t size) 886cb93a386Sopenharmony_ci{ 887cb93a386Sopenharmony_ci if (fMemoryOverflowCallback_ == nullptr) { 888cb93a386Sopenharmony_ci fMemoryOverflowCallback_ = callback; 889cb93a386Sopenharmony_ci fMemoryControl_ = size; 890cb93a386Sopenharmony_ci } 891cb93a386Sopenharmony_ci} 892cb93a386Sopenharmony_ci 893cb93a386Sopenharmony_ci// OH ISSUE: check whether the PID is abnormal. 894cb93a386Sopenharmony_cibool GrResourceCache::isPidAbnormal() const 895cb93a386Sopenharmony_ci{ 896cb93a386Sopenharmony_ci return fExitedPid_.find(getCurrentGrResourceTag().fPid) != fExitedPid_.end(); 897cb93a386Sopenharmony_ci} 898cb93a386Sopenharmony_ci 899cb93a386Sopenharmony_ci// OH ISSUE: change the fbyte when the resource tag changes. 900cb93a386Sopenharmony_civoid GrResourceCache::changeByteOfPid(int32_t beforePid, int32_t afterPid, size_t bytes) 901cb93a386Sopenharmony_ci{ 902cb93a386Sopenharmony_ci if (beforePid) { 903cb93a386Sopenharmony_ci auto& pidSize = fBytesOfPid[beforePid]; 904cb93a386Sopenharmony_ci pidSize -= bytes; 905cb93a386Sopenharmony_ci fUpdatedBytesOfPid[beforePid] = pidSize; 906cb93a386Sopenharmony_ci if (pidSize == 0) { 907cb93a386Sopenharmony_ci fBytesOfPid.erase(beforePid); 908cb93a386Sopenharmony_ci } 909cb93a386Sopenharmony_ci } 910cb93a386Sopenharmony_ci if (afterPid) { 911cb93a386Sopenharmony_ci auto& size = fBytesOfPid[afterPid]; 912cb93a386Sopenharmony_ci size += bytes; 913cb93a386Sopenharmony_ci fUpdatedBytesOfPid[afterPid] = size; 914cb93a386Sopenharmony_ci } 915cb93a386Sopenharmony_ci} 916cb93a386Sopenharmony_ci 917cb93a386Sopenharmony_civoid GrResourceCache::refResource(GrGpuResource* resource) { 918cb93a386Sopenharmony_ci SkASSERT(resource); 919cb93a386Sopenharmony_ci SkASSERT(resource->getContext()->priv().getResourceCache() == this); 920cb93a386Sopenharmony_ci if (resource->cacheAccess().hasRef()) { 921cb93a386Sopenharmony_ci resource->ref(); 922cb93a386Sopenharmony_ci } else { 923cb93a386Sopenharmony_ci this->refAndMakeResourceMRU(resource); 924cb93a386Sopenharmony_ci } 925cb93a386Sopenharmony_ci this->validate(); 926cb93a386Sopenharmony_ci} 927cb93a386Sopenharmony_ci 928cb93a386Sopenharmony_ciclass GrResourceCache::AvailableForScratchUse { 929cb93a386Sopenharmony_cipublic: 930cb93a386Sopenharmony_ci AvailableForScratchUse() { } 931cb93a386Sopenharmony_ci 932cb93a386Sopenharmony_ci bool operator()(const GrGpuResource* resource) const { 933cb93a386Sopenharmony_ci // Everything that is in the scratch map should be usable as a 934cb93a386Sopenharmony_ci // scratch resource. 935cb93a386Sopenharmony_ci return true; 936cb93a386Sopenharmony_ci } 937cb93a386Sopenharmony_ci}; 938cb93a386Sopenharmony_ci 939cb93a386Sopenharmony_ciGrGpuResource* GrResourceCache::findAndRefScratchResource(const GrScratchKey& scratchKey) { 940cb93a386Sopenharmony_ci SkASSERT(scratchKey.isValid()); 941cb93a386Sopenharmony_ci 942cb93a386Sopenharmony_ci GrGpuResource* resource = fScratchMap.find(scratchKey, AvailableForScratchUse()); 943cb93a386Sopenharmony_ci if (resource) { 944cb93a386Sopenharmony_ci fScratchMap.remove(scratchKey, resource); 945cb93a386Sopenharmony_ci if (!this->isInCache(resource)) { 946cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::findAndRefScratchResource not in cache, return!!!"); 947cb93a386Sopenharmony_ci return nullptr; 948cb93a386Sopenharmony_ci } 949cb93a386Sopenharmony_ci this->refAndMakeResourceMRU(resource); 950cb93a386Sopenharmony_ci this->validate(); 951cb93a386Sopenharmony_ci } 952cb93a386Sopenharmony_ci return resource; 953cb93a386Sopenharmony_ci} 954cb93a386Sopenharmony_ci 955cb93a386Sopenharmony_civoid GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { 956cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 957cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().getScratchKey().isValid()); 958cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 959cb93a386Sopenharmony_ci fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 960cb93a386Sopenharmony_ci } 961cb93a386Sopenharmony_ci} 962cb93a386Sopenharmony_ci 963cb93a386Sopenharmony_civoid GrResourceCache::removeUniqueKey(GrGpuResource* resource) { 964cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 965cb93a386Sopenharmony_ci // Someone has a ref to this resource in order to have removed the key. When the ref count 966cb93a386Sopenharmony_ci // reaches zero we will get a ref cnt notification and figure out what to do with it. 967cb93a386Sopenharmony_ci if (resource->getUniqueKey().isValid()) { 968cb93a386Sopenharmony_ci SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); 969cb93a386Sopenharmony_ci fUniqueHash.remove(resource->getUniqueKey()); 970cb93a386Sopenharmony_ci } 971cb93a386Sopenharmony_ci resource->cacheAccess().removeUniqueKey(); 972cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 973cb93a386Sopenharmony_ci fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 974cb93a386Sopenharmony_ci } 975cb93a386Sopenharmony_ci 976cb93a386Sopenharmony_ci // Removing a unique key from a kUnbudgetedCacheable resource would make the resource 977cb93a386Sopenharmony_ci // require purging. However, the resource must be ref'ed to get here and therefore can't 978cb93a386Sopenharmony_ci // be purgeable. We'll purge it when the refs reach zero. 979cb93a386Sopenharmony_ci SkASSERT(!resource->resourcePriv().isPurgeable()); 980cb93a386Sopenharmony_ci this->validate(); 981cb93a386Sopenharmony_ci} 982cb93a386Sopenharmony_ci 983cb93a386Sopenharmony_civoid GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey& newKey) { 984cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 985cb93a386Sopenharmony_ci SkASSERT(resource); 986cb93a386Sopenharmony_ci SkASSERT(this->isInCache(resource)); 987cb93a386Sopenharmony_ci 988cb93a386Sopenharmony_ci // If another resource has the new key, remove its key then install the key on this resource. 989cb93a386Sopenharmony_ci if (newKey.isValid()) { 990cb93a386Sopenharmony_ci if (GrGpuResource* old = fUniqueHash.find(newKey)) { 991cb93a386Sopenharmony_ci // If the old resource using the key is purgeable and is unreachable, then remove it. 992cb93a386Sopenharmony_ci if (!old->resourcePriv().getScratchKey().isValid() && 993cb93a386Sopenharmony_ci old->resourcePriv().isPurgeable()) { 994cb93a386Sopenharmony_ci old->cacheAccess().release(); 995cb93a386Sopenharmony_ci } else { 996cb93a386Sopenharmony_ci // removeUniqueKey expects an external owner of the resource. 997cb93a386Sopenharmony_ci this->removeUniqueKey(sk_ref_sp(old).get()); 998cb93a386Sopenharmony_ci } 999cb93a386Sopenharmony_ci } 1000cb93a386Sopenharmony_ci SkASSERT(nullptr == fUniqueHash.find(newKey)); 1001cb93a386Sopenharmony_ci 1002cb93a386Sopenharmony_ci // Remove the entry for this resource if it already has a unique key. 1003cb93a386Sopenharmony_ci if (resource->getUniqueKey().isValid()) { 1004cb93a386Sopenharmony_ci SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); 1005cb93a386Sopenharmony_ci fUniqueHash.remove(resource->getUniqueKey()); 1006cb93a386Sopenharmony_ci SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); 1007cb93a386Sopenharmony_ci } else { 1008cb93a386Sopenharmony_ci // 'resource' didn't have a valid unique key before so it is switching sides. Remove it 1009cb93a386Sopenharmony_ci // from the ScratchMap. The isUsableAsScratch call depends on us not adding the new 1010cb93a386Sopenharmony_ci // unique key until after this check. 1011cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 1012cb93a386Sopenharmony_ci fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 1013cb93a386Sopenharmony_ci } 1014cb93a386Sopenharmony_ci } 1015cb93a386Sopenharmony_ci 1016cb93a386Sopenharmony_ci resource->cacheAccess().setUniqueKey(newKey); 1017cb93a386Sopenharmony_ci fUniqueHash.add(resource); 1018cb93a386Sopenharmony_ci } else { 1019cb93a386Sopenharmony_ci this->removeUniqueKey(resource); 1020cb93a386Sopenharmony_ci } 1021cb93a386Sopenharmony_ci 1022cb93a386Sopenharmony_ci this->validate(); 1023cb93a386Sopenharmony_ci} 1024cb93a386Sopenharmony_ci 1025cb93a386Sopenharmony_civoid GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { 1026cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 1027cb93a386Sopenharmony_ci SkASSERT(resource); 1028cb93a386Sopenharmony_ci SkASSERT(this->isInCache(resource)); 1029cb93a386Sopenharmony_ci 1030cb93a386Sopenharmony_ci if (resource->resourcePriv().isPurgeable()) { 1031cb93a386Sopenharmony_ci // It's about to become unpurgeable. 1032cb93a386Sopenharmony_ci if (this->isInPurgeableCache(resource)) { 1033cb93a386Sopenharmony_ci fPurgeableBytes -= resource->gpuMemorySize(); 1034cb93a386Sopenharmony_ci fPurgeableQueue.remove(resource); 1035cb93a386Sopenharmony_ci } 1036cb93a386Sopenharmony_ci if (!this->isInNonpurgeableCache(resource)) { 1037cb93a386Sopenharmony_ci this->addToNonpurgeableArray(resource); 1038cb93a386Sopenharmony_ci } else { 1039cb93a386Sopenharmony_ci SkDebugf("OHOS resource in isInNonpurgeableCache, do not add again!"); 1040cb93a386Sopenharmony_ci } 1041cb93a386Sopenharmony_ci } else if (!resource->cacheAccess().hasRefOrCommandBufferUsage() && 1042cb93a386Sopenharmony_ci resource->resourcePriv().budgetedType() == GrBudgetedType::kBudgeted) { 1043cb93a386Sopenharmony_ci SkASSERT(fNumBudgetedResourcesFlushWillMakePurgeable > 0); 1044cb93a386Sopenharmony_ci fNumBudgetedResourcesFlushWillMakePurgeable--; 1045cb93a386Sopenharmony_ci } 1046cb93a386Sopenharmony_ci resource->cacheAccess().ref(); 1047cb93a386Sopenharmony_ci 1048cb93a386Sopenharmony_ci resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 1049cb93a386Sopenharmony_ci this->validate(); 1050cb93a386Sopenharmony_ci} 1051cb93a386Sopenharmony_ci 1052cb93a386Sopenharmony_civoid GrResourceCache::notifyARefCntReachedZero(GrGpuResource* resource, 1053cb93a386Sopenharmony_ci GrGpuResource::LastRemovedRef removedRef) { 1054cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 1055cb93a386Sopenharmony_ci SkASSERT(resource); 1056cb93a386Sopenharmony_ci SkASSERT(!resource->wasDestroyed()); 1057cb93a386Sopenharmony_ci SkASSERT(this->isInCache(resource)); 1058cb93a386Sopenharmony_ci // This resource should always be in the nonpurgeable array when this function is called. It 1059cb93a386Sopenharmony_ci // will be moved to the queue if it is newly purgeable. 1060cb93a386Sopenharmony_ci SkASSERT(fNonpurgeableResources[*resource->cacheAccess().accessCacheIndex()] == resource); 1061cb93a386Sopenharmony_ci if (!resource || resource->wasDestroyed() || this->isInPurgeableCache(resource) || 1062cb93a386Sopenharmony_ci !this->isInNonpurgeableCache(resource)) { 1063cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::notifyARefCntReachedZero return!"); 1064cb93a386Sopenharmony_ci return; 1065cb93a386Sopenharmony_ci } 1066cb93a386Sopenharmony_ci if (removedRef == GrGpuResource::LastRemovedRef::kMainRef) { 1067cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 1068cb93a386Sopenharmony_ci fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 1069cb93a386Sopenharmony_ci } 1070cb93a386Sopenharmony_ci } 1071cb93a386Sopenharmony_ci 1072cb93a386Sopenharmony_ci if (resource->cacheAccess().hasRefOrCommandBufferUsage()) { 1073cb93a386Sopenharmony_ci this->validate(); 1074cb93a386Sopenharmony_ci return; 1075cb93a386Sopenharmony_ci } 1076cb93a386Sopenharmony_ci 1077cb93a386Sopenharmony_ci#ifdef SK_DEBUG 1078cb93a386Sopenharmony_ci // When the timestamp overflows validate() is called. validate() checks that resources in 1079cb93a386Sopenharmony_ci // the nonpurgeable array are indeed not purgeable. However, the movement from the array to 1080cb93a386Sopenharmony_ci // the purgeable queue happens just below in this function. So we mark it as an exception. 1081cb93a386Sopenharmony_ci if (resource->resourcePriv().isPurgeable()) { 1082cb93a386Sopenharmony_ci fNewlyPurgeableResourceForValidation = resource; 1083cb93a386Sopenharmony_ci } 1084cb93a386Sopenharmony_ci#endif 1085cb93a386Sopenharmony_ci resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 1086cb93a386Sopenharmony_ci SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr); 1087cb93a386Sopenharmony_ci 1088cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable() && 1089cb93a386Sopenharmony_ci resource->resourcePriv().budgetedType() == GrBudgetedType::kBudgeted) { 1090cb93a386Sopenharmony_ci ++fNumBudgetedResourcesFlushWillMakePurgeable; 1091cb93a386Sopenharmony_ci } 1092cb93a386Sopenharmony_ci 1093cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable()) { 1094cb93a386Sopenharmony_ci this->validate(); 1095cb93a386Sopenharmony_ci return; 1096cb93a386Sopenharmony_ci } 1097cb93a386Sopenharmony_ci 1098cb93a386Sopenharmony_ci this->removeFromNonpurgeableArray(resource); 1099cb93a386Sopenharmony_ci fPurgeableQueue.insert(resource); 1100cb93a386Sopenharmony_ci resource->cacheAccess().setTimeWhenResourceBecomePurgeable(); 1101cb93a386Sopenharmony_ci fPurgeableBytes += resource->gpuMemorySize(); 1102cb93a386Sopenharmony_ci 1103cb93a386Sopenharmony_ci bool hasUniqueKey = resource->getUniqueKey().isValid(); 1104cb93a386Sopenharmony_ci 1105cb93a386Sopenharmony_ci GrBudgetedType budgetedType = resource->resourcePriv().budgetedType(); 1106cb93a386Sopenharmony_ci 1107cb93a386Sopenharmony_ci if (budgetedType == GrBudgetedType::kBudgeted) { 1108cb93a386Sopenharmony_ci // Purge the resource immediately if we're over budget 1109cb93a386Sopenharmony_ci // Also purge if the resource has neither a valid scratch key nor a unique key. 1110cb93a386Sopenharmony_ci bool hasKey = resource->resourcePriv().getScratchKey().isValid() || hasUniqueKey; 1111cb93a386Sopenharmony_ci if (!this->overBudget() && hasKey) { 1112cb93a386Sopenharmony_ci return; 1113cb93a386Sopenharmony_ci } 1114cb93a386Sopenharmony_ci } else { 1115cb93a386Sopenharmony_ci // We keep unbudgeted resources with a unique key in the purgeable queue of the cache so 1116cb93a386Sopenharmony_ci // they can be reused again by the image connected to the unique key. 1117cb93a386Sopenharmony_ci if (hasUniqueKey && budgetedType == GrBudgetedType::kUnbudgetedCacheable) { 1118cb93a386Sopenharmony_ci return; 1119cb93a386Sopenharmony_ci } 1120cb93a386Sopenharmony_ci // Check whether this resource could still be used as a scratch resource. 1121cb93a386Sopenharmony_ci if (!resource->resourcePriv().refsWrappedObjects() && 1122cb93a386Sopenharmony_ci resource->resourcePriv().getScratchKey().isValid()) { 1123cb93a386Sopenharmony_ci // We won't purge an existing resource to make room for this one. 1124cb93a386Sopenharmony_ci if (this->wouldFit(resource->gpuMemorySize())) { 1125cb93a386Sopenharmony_ci resource->resourcePriv().makeBudgeted(); 1126cb93a386Sopenharmony_ci return; 1127cb93a386Sopenharmony_ci } 1128cb93a386Sopenharmony_ci } 1129cb93a386Sopenharmony_ci } 1130cb93a386Sopenharmony_ci 1131cb93a386Sopenharmony_ci SkDEBUGCODE(int beforeCount = this->getResourceCount();) 1132cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1133cb93a386Sopenharmony_ci // We should at least free this resource, perhaps dependent resources as well. 1134cb93a386Sopenharmony_ci SkASSERT(this->getResourceCount() < beforeCount); 1135cb93a386Sopenharmony_ci this->validate(); 1136cb93a386Sopenharmony_ci} 1137cb93a386Sopenharmony_ci 1138cb93a386Sopenharmony_civoid GrResourceCache::didChangeBudgetStatus(GrGpuResource* resource) { 1139cb93a386Sopenharmony_ci ASSERT_SINGLE_OWNER 1140cb93a386Sopenharmony_ci SkASSERT(resource); 1141cb93a386Sopenharmony_ci SkASSERT(this->isInCache(resource)); 1142cb93a386Sopenharmony_ci 1143cb93a386Sopenharmony_ci size_t size = resource->gpuMemorySize(); 1144cb93a386Sopenharmony_ci // Changing from BudgetedType::kUnbudgetedCacheable to another budgeted type could make 1145cb93a386Sopenharmony_ci // resource become purgeable. However, we should never allow that transition. Wrapped 1146cb93a386Sopenharmony_ci // resources are the only resources that can be in that state and they aren't allowed to 1147cb93a386Sopenharmony_ci // transition from one budgeted state to another. 1148cb93a386Sopenharmony_ci SkDEBUGCODE(bool wasPurgeable = resource->resourcePriv().isPurgeable()); 1149cb93a386Sopenharmony_ci if (resource->resourcePriv().budgetedType() == GrBudgetedType::kBudgeted) { 1150cb93a386Sopenharmony_ci ++fBudgetedCount; 1151cb93a386Sopenharmony_ci fBudgetedBytes += size; 1152cb93a386Sopenharmony_ci#if GR_CACHE_STATS 1153cb93a386Sopenharmony_ci fBudgetedHighWaterBytes = std::max(fBudgetedBytes, fBudgetedHighWaterBytes); 1154cb93a386Sopenharmony_ci fBudgetedHighWaterCount = std::max(fBudgetedCount, fBudgetedHighWaterCount); 1155cb93a386Sopenharmony_ci#endif 1156cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable() && 1157cb93a386Sopenharmony_ci !resource->cacheAccess().hasRefOrCommandBufferUsage()) { 1158cb93a386Sopenharmony_ci ++fNumBudgetedResourcesFlushWillMakePurgeable; 1159cb93a386Sopenharmony_ci } 1160cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 1161cb93a386Sopenharmony_ci fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 1162cb93a386Sopenharmony_ci } 1163cb93a386Sopenharmony_ci this->purgeAsNeeded(); 1164cb93a386Sopenharmony_ci } else { 1165cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().budgetedType() != GrBudgetedType::kUnbudgetedCacheable); 1166cb93a386Sopenharmony_ci --fBudgetedCount; 1167cb93a386Sopenharmony_ci fBudgetedBytes -= size; 1168cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable() && 1169cb93a386Sopenharmony_ci !resource->cacheAccess().hasRefOrCommandBufferUsage()) { 1170cb93a386Sopenharmony_ci --fNumBudgetedResourcesFlushWillMakePurgeable; 1171cb93a386Sopenharmony_ci } 1172cb93a386Sopenharmony_ci if (!resource->cacheAccess().hasRef() && !resource->getUniqueKey().isValid() && 1173cb93a386Sopenharmony_ci resource->resourcePriv().getScratchKey().isValid()) { 1174cb93a386Sopenharmony_ci fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 1175cb93a386Sopenharmony_ci } 1176cb93a386Sopenharmony_ci } 1177cb93a386Sopenharmony_ci SkASSERT(wasPurgeable == resource->resourcePriv().isPurgeable()); 1178cb93a386Sopenharmony_ci TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 1179cb93a386Sopenharmony_ci fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 1180cb93a386Sopenharmony_ci 1181cb93a386Sopenharmony_ci this->validate(); 1182cb93a386Sopenharmony_ci} 1183cb93a386Sopenharmony_ci 1184cb93a386Sopenharmony_cistatic constexpr int timeUnit = 1000; 1185cb93a386Sopenharmony_ci 1186cb93a386Sopenharmony_ci// OH ISSUE: allow access to release interface 1187cb93a386Sopenharmony_cibool GrResourceCache::allowToPurge(const std::function<bool(void)>& nextFrameHasArrived) 1188cb93a386Sopenharmony_ci{ 1189cb93a386Sopenharmony_ci if (!fEnabled) { 1190cb93a386Sopenharmony_ci return true; 1191cb93a386Sopenharmony_ci } 1192cb93a386Sopenharmony_ci if (fFrameInfo.duringFrame == 0) { 1193cb93a386Sopenharmony_ci if (nextFrameHasArrived && nextFrameHasArrived()) { 1194cb93a386Sopenharmony_ci return false; 1195cb93a386Sopenharmony_ci } 1196cb93a386Sopenharmony_ci return true; 1197cb93a386Sopenharmony_ci } 1198cb93a386Sopenharmony_ci if (fFrameInfo.frameCount != fLastFrameCount) { // the next frame arrives 1199cb93a386Sopenharmony_ci struct timespec startTime = {0, 0}; 1200cb93a386Sopenharmony_ci if (clock_gettime(CLOCK_REALTIME, &startTime) == -1) { 1201cb93a386Sopenharmony_ci return true; 1202cb93a386Sopenharmony_ci } 1203cb93a386Sopenharmony_ci fStartTime = startTime.tv_sec * timeUnit * timeUnit + startTime.tv_nsec / timeUnit; 1204cb93a386Sopenharmony_ci fLastFrameCount = fFrameInfo.frameCount; 1205cb93a386Sopenharmony_ci return true; 1206cb93a386Sopenharmony_ci } 1207cb93a386Sopenharmony_ci struct timespec endTime = {0, 0}; 1208cb93a386Sopenharmony_ci if (clock_gettime(CLOCK_REALTIME, &endTime) == -1) { 1209cb93a386Sopenharmony_ci return true; 1210cb93a386Sopenharmony_ci } 1211cb93a386Sopenharmony_ci if (((endTime.tv_sec * timeUnit * timeUnit + endTime.tv_nsec / timeUnit) - fStartTime) >= fOvertimeDuration) { 1212cb93a386Sopenharmony_ci return false; 1213cb93a386Sopenharmony_ci } 1214cb93a386Sopenharmony_ci return true; 1215cb93a386Sopenharmony_ci} 1216cb93a386Sopenharmony_ci 1217cb93a386Sopenharmony_civoid GrResourceCache::purgeAsNeeded(const std::function<bool(void)>& nextFrameHasArrived) { 1218cb93a386Sopenharmony_ci SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs; 1219cb93a386Sopenharmony_ci fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs); 1220cb93a386Sopenharmony_ci if (invalidKeyMsgs.count()) { 1221cb93a386Sopenharmony_ci SkASSERT(fProxyProvider); 1222cb93a386Sopenharmony_ci 1223cb93a386Sopenharmony_ci for (int i = 0; i < invalidKeyMsgs.count(); ++i) { 1224cb93a386Sopenharmony_ci if (invalidKeyMsgs[i].inThreadSafeCache()) { 1225cb93a386Sopenharmony_ci fThreadSafeCache->remove(invalidKeyMsgs[i].key()); 1226cb93a386Sopenharmony_ci SkASSERT(!fThreadSafeCache->has(invalidKeyMsgs[i].key())); 1227cb93a386Sopenharmony_ci } else { 1228cb93a386Sopenharmony_ci fProxyProvider->processInvalidUniqueKey( 1229cb93a386Sopenharmony_ci invalidKeyMsgs[i].key(), nullptr, 1230cb93a386Sopenharmony_ci GrProxyProvider::InvalidateGPUResource::kYes); 1231cb93a386Sopenharmony_ci SkASSERT(!this->findAndRefUniqueResource(invalidKeyMsgs[i].key())); 1232cb93a386Sopenharmony_ci } 1233cb93a386Sopenharmony_ci } 1234cb93a386Sopenharmony_ci } 1235cb93a386Sopenharmony_ci 1236cb93a386Sopenharmony_ci this->processFreedGpuResources(); 1237cb93a386Sopenharmony_ci 1238cb93a386Sopenharmony_ci bool stillOverbudget = this->overBudget(nextFrameHasArrived); 1239cb93a386Sopenharmony_ci while (stillOverbudget && fPurgeableQueue.count() && this->allowToPurge(nextFrameHasArrived)) { 1240cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.peek(); 1241cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable()) { 1242cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::purgeAsNeeded() resource is nonPurgeable"); 1243cb93a386Sopenharmony_ci continue; 1244cb93a386Sopenharmony_ci } 1245cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1246cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1247cb93a386Sopenharmony_ci stillOverbudget = this->overBudget(nextFrameHasArrived); 1248cb93a386Sopenharmony_ci } 1249cb93a386Sopenharmony_ci 1250cb93a386Sopenharmony_ci if (stillOverbudget) { 1251cb93a386Sopenharmony_ci fThreadSafeCache->dropUniqueRefs(this); 1252cb93a386Sopenharmony_ci 1253cb93a386Sopenharmony_ci stillOverbudget = this->overBudget(nextFrameHasArrived); 1254cb93a386Sopenharmony_ci while (stillOverbudget && fPurgeableQueue.count() && this->allowToPurge(nextFrameHasArrived)) { 1255cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.peek(); 1256cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable()) { 1257cb93a386Sopenharmony_ci SkDebugf("OHOS GrResourceCache::purgeAsNeeded() resource is nonPurgeable after dropUniqueRefs"); 1258cb93a386Sopenharmony_ci continue; 1259cb93a386Sopenharmony_ci } 1260cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1261cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1262cb93a386Sopenharmony_ci stillOverbudget = this->overBudget(nextFrameHasArrived); 1263cb93a386Sopenharmony_ci } 1264cb93a386Sopenharmony_ci } 1265cb93a386Sopenharmony_ci 1266cb93a386Sopenharmony_ci this->validate(); 1267cb93a386Sopenharmony_ci} 1268cb93a386Sopenharmony_ci 1269cb93a386Sopenharmony_civoid GrResourceCache::purgeUnlockedResources(const GrStdSteadyClock::time_point* purgeTime, 1270cb93a386Sopenharmony_ci bool scratchResourcesOnly) { 1271cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1272cb93a386Sopenharmony_ci SimpleCacheInfo simpleCacheInfo; 1273cb93a386Sopenharmony_ci traceBeforePurgeUnlockRes("purgeUnlockedResources", simpleCacheInfo); 1274cb93a386Sopenharmony_ci#endif 1275cb93a386Sopenharmony_ci if (!scratchResourcesOnly) { 1276cb93a386Sopenharmony_ci if (purgeTime) { 1277cb93a386Sopenharmony_ci fThreadSafeCache->dropUniqueRefsOlderThan(*purgeTime); 1278cb93a386Sopenharmony_ci } else { 1279cb93a386Sopenharmony_ci fThreadSafeCache->dropUniqueRefs(nullptr); 1280cb93a386Sopenharmony_ci } 1281cb93a386Sopenharmony_ci 1282cb93a386Sopenharmony_ci // We could disable maintaining the heap property here, but it would add a lot of 1283cb93a386Sopenharmony_ci // complexity. Moreover, this is rarely called. 1284cb93a386Sopenharmony_ci while (fPurgeableQueue.count()) { 1285cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.peek(); 1286cb93a386Sopenharmony_ci 1287cb93a386Sopenharmony_ci const GrStdSteadyClock::time_point resourceTime = 1288cb93a386Sopenharmony_ci resource->cacheAccess().timeWhenResourceBecamePurgeable(); 1289cb93a386Sopenharmony_ci if (purgeTime && resourceTime >= *purgeTime) { 1290cb93a386Sopenharmony_ci // Resources were given both LRU timestamps and tagged with a frame number when 1291cb93a386Sopenharmony_ci // they first became purgeable. The LRU timestamp won't change again until the 1292cb93a386Sopenharmony_ci // resource is made non-purgeable again. So, at this point all the remaining 1293cb93a386Sopenharmony_ci // resources in the timestamp-sorted queue will have a frame number >= to this 1294cb93a386Sopenharmony_ci // one. 1295cb93a386Sopenharmony_ci break; 1296cb93a386Sopenharmony_ci } 1297cb93a386Sopenharmony_ci 1298cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1299cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1300cb93a386Sopenharmony_ci } 1301cb93a386Sopenharmony_ci } else { 1302cb93a386Sopenharmony_ci // Early out if the very first item is too new to purge to avoid sorting the queue when 1303cb93a386Sopenharmony_ci // nothing will be deleted. 1304cb93a386Sopenharmony_ci if (purgeTime && fPurgeableQueue.count() && 1305cb93a386Sopenharmony_ci fPurgeableQueue.peek()->cacheAccess().timeWhenResourceBecamePurgeable() >= *purgeTime) { 1306cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1307cb93a386Sopenharmony_ci traceAfterPurgeUnlockRes("purgeUnlockedResources", simpleCacheInfo); 1308cb93a386Sopenharmony_ci#endif 1309cb93a386Sopenharmony_ci return; 1310cb93a386Sopenharmony_ci } 1311cb93a386Sopenharmony_ci 1312cb93a386Sopenharmony_ci // Sort the queue 1313cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1314cb93a386Sopenharmony_ci 1315cb93a386Sopenharmony_ci // Make a list of the scratch resources to delete 1316cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> scratchResources; 1317cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 1318cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1319cb93a386Sopenharmony_ci 1320cb93a386Sopenharmony_ci const GrStdSteadyClock::time_point resourceTime = 1321cb93a386Sopenharmony_ci resource->cacheAccess().timeWhenResourceBecamePurgeable(); 1322cb93a386Sopenharmony_ci if (purgeTime && resourceTime >= *purgeTime) { 1323cb93a386Sopenharmony_ci // scratch or not, all later iterations will be too recently used to purge. 1324cb93a386Sopenharmony_ci break; 1325cb93a386Sopenharmony_ci } 1326cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1327cb93a386Sopenharmony_ci if (!resource->getUniqueKey().isValid()) { 1328cb93a386Sopenharmony_ci *scratchResources.append() = resource; 1329cb93a386Sopenharmony_ci } 1330cb93a386Sopenharmony_ci } 1331cb93a386Sopenharmony_ci 1332cb93a386Sopenharmony_ci // Delete the scratch resources. This must be done as a separate pass 1333cb93a386Sopenharmony_ci // to avoid messing up the sorted order of the queue 1334cb93a386Sopenharmony_ci for (int i = 0; i < scratchResources.count(); i++) { 1335cb93a386Sopenharmony_ci scratchResources.getAt(i)->cacheAccess().release(); 1336cb93a386Sopenharmony_ci } 1337cb93a386Sopenharmony_ci } 1338cb93a386Sopenharmony_ci 1339cb93a386Sopenharmony_ci this->validate(); 1340cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1341cb93a386Sopenharmony_ci traceAfterPurgeUnlockRes("purgeUnlockedResources", simpleCacheInfo); 1342cb93a386Sopenharmony_ci#endif 1343cb93a386Sopenharmony_ci} 1344cb93a386Sopenharmony_ci 1345cb93a386Sopenharmony_civoid GrResourceCache::purgeUnlockAndSafeCacheGpuResources() { 1346cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1347cb93a386Sopenharmony_ci SimpleCacheInfo simpleCacheInfo; 1348cb93a386Sopenharmony_ci traceBeforePurgeUnlockRes("purgeUnlockAndSafeCacheGpuResources", simpleCacheInfo); 1349cb93a386Sopenharmony_ci#endif 1350cb93a386Sopenharmony_ci fThreadSafeCache->dropUniqueRefs(nullptr); 1351cb93a386Sopenharmony_ci // Sort the queue 1352cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1353cb93a386Sopenharmony_ci 1354cb93a386Sopenharmony_ci //Make a list of the scratch resources to delete 1355cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> scratchResources; 1356cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 1357cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1358cb93a386Sopenharmony_ci if (!resource) { 1359cb93a386Sopenharmony_ci continue; 1360cb93a386Sopenharmony_ci } 1361cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1362cb93a386Sopenharmony_ci if (!resource->getUniqueKey().isValid()) { 1363cb93a386Sopenharmony_ci *scratchResources.append() = resource; 1364cb93a386Sopenharmony_ci } 1365cb93a386Sopenharmony_ci } 1366cb93a386Sopenharmony_ci 1367cb93a386Sopenharmony_ci //Delete the scatch resource. This must be done as a separate pass 1368cb93a386Sopenharmony_ci //to avoid messing up the sorted order of the queue 1369cb93a386Sopenharmony_ci for (int i = 0; i <scratchResources.count(); i++) { 1370cb93a386Sopenharmony_ci scratchResources.getAt(i)->cacheAccess().release(); 1371cb93a386Sopenharmony_ci } 1372cb93a386Sopenharmony_ci 1373cb93a386Sopenharmony_ci this->validate(); 1374cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1375cb93a386Sopenharmony_ci traceAfterPurgeUnlockRes("purgeUnlockAndSafeCacheGpuResources", simpleCacheInfo); 1376cb93a386Sopenharmony_ci#endif 1377cb93a386Sopenharmony_ci} 1378cb93a386Sopenharmony_ci 1379cb93a386Sopenharmony_ci// OH ISSUE: suppress release window 1380cb93a386Sopenharmony_civoid GrResourceCache::suppressGpuCacheBelowCertainRatio(const std::function<bool(void)>& nextFrameHasArrived) { 1381cb93a386Sopenharmony_ci if (!fEnabled) { 1382cb93a386Sopenharmony_ci return; 1383cb93a386Sopenharmony_ci } 1384cb93a386Sopenharmony_ci this->purgeAsNeeded(nextFrameHasArrived); 1385cb93a386Sopenharmony_ci} 1386cb93a386Sopenharmony_ci 1387cb93a386Sopenharmony_civoid GrResourceCache::purgeCacheBetweenFrames(bool scratchResourcesOnly, const std::set<int>& exitedPidSet, 1388cb93a386Sopenharmony_ci const std::set<int>& protectedPidSet) { 1389cb93a386Sopenharmony_ci HITRACE_OHOS_NAME_FMT_ALWAYS("PurgeGrResourceCache cur=%d, limit=%d", fBudgetedBytes, fMaxBytes); 1390cb93a386Sopenharmony_ci if (exitedPidSet.size() > 1) { 1391cb93a386Sopenharmony_ci for (int i = 1; i < fPurgeableQueue.count(); i++) { 1392cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1393cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1394cb93a386Sopenharmony_ci if (exitedPidSet.find(resource->getResourceTag().fPid) != exitedPidSet.end()) { 1395cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1396cb93a386Sopenharmony_ci this->validate(); 1397cb93a386Sopenharmony_ci return; 1398cb93a386Sopenharmony_ci } 1399cb93a386Sopenharmony_ci } 1400cb93a386Sopenharmony_ci } 1401cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1402cb93a386Sopenharmony_ci const char* softLimitPercentage = "0.9"; 1403cb93a386Sopenharmony_ci #ifdef NOT_BUILD_FOR_OHOS_SDK 1404cb93a386Sopenharmony_ci static int softLimit = 1405cb93a386Sopenharmony_ci std::atof(OHOS::system::GetParameter("persist.sys.graphic.mem.soft_limit", 1406cb93a386Sopenharmony_ci softLimitPercentage).c_str()) * fMaxBytes; 1407cb93a386Sopenharmony_ci #else 1408cb93a386Sopenharmony_ci static int softLimit = 0.9 * fMaxBytes; 1409cb93a386Sopenharmony_ci #endif 1410cb93a386Sopenharmony_ci if (fBudgetedBytes >= softLimit) { 1411cb93a386Sopenharmony_ci for (int i=0; i < fPurgeableQueue.count(); i++) { 1412cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1413cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1414cb93a386Sopenharmony_ci if (protectedPidSet.find(resource->getResourceTag().fPid) == protectedPidSet.end() 1415cb93a386Sopenharmony_ci && (!scratchResourcesOnly || !resource->getUniqueKey().isValid())) { 1416cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1417cb93a386Sopenharmony_ci this->validate(); 1418cb93a386Sopenharmony_ci return; 1419cb93a386Sopenharmony_ci } 1420cb93a386Sopenharmony_ci } 1421cb93a386Sopenharmony_ci } 1422cb93a386Sopenharmony_ci} 1423cb93a386Sopenharmony_ci 1424cb93a386Sopenharmony_civoid GrResourceCache::purgeUnlockedResourcesByPid(bool scratchResourceOnly, const std::set<int>& exitedPidSet) { 1425cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1426cb93a386Sopenharmony_ci SimpleCacheInfo simpleCacheInfo; 1427cb93a386Sopenharmony_ci traceBeforePurgeUnlockRes("purgeUnlockedResourcesByPid", simpleCacheInfo); 1428cb93a386Sopenharmony_ci#endif 1429cb93a386Sopenharmony_ci // Sort the queue 1430cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1431cb93a386Sopenharmony_ci 1432cb93a386Sopenharmony_ci //Make lists of the need purged resources to delete 1433cb93a386Sopenharmony_ci fThreadSafeCache->dropUniqueRefs(nullptr); 1434cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> exitPidResources; 1435cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> scratchResources; 1436cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 1437cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1438cb93a386Sopenharmony_ci if (!resource) { 1439cb93a386Sopenharmony_ci continue; 1440cb93a386Sopenharmony_ci } 1441cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1442cb93a386Sopenharmony_ci if (exitedPidSet.count(resource->getResourceTag().fPid)) { 1443cb93a386Sopenharmony_ci *exitPidResources.append() = resource; 1444cb93a386Sopenharmony_ci } else if (!resource->getUniqueKey().isValid()) { 1445cb93a386Sopenharmony_ci *scratchResources.append() = resource; 1446cb93a386Sopenharmony_ci } 1447cb93a386Sopenharmony_ci } 1448cb93a386Sopenharmony_ci 1449cb93a386Sopenharmony_ci //Delete the exited pid and scatch resource. This must be done as a separate pass 1450cb93a386Sopenharmony_ci //to avoid messing up the sorted order of the queue 1451cb93a386Sopenharmony_ci for (int i = 0; i <exitPidResources.count(); i++) { 1452cb93a386Sopenharmony_ci exitPidResources.getAt(i)->cacheAccess().release(); 1453cb93a386Sopenharmony_ci } 1454cb93a386Sopenharmony_ci for (int i = 0; i <scratchResources.count(); i++) { 1455cb93a386Sopenharmony_ci scratchResources.getAt(i)->cacheAccess().release(); 1456cb93a386Sopenharmony_ci } 1457cb93a386Sopenharmony_ci 1458cb93a386Sopenharmony_ci for (auto pid : exitedPidSet) { 1459cb93a386Sopenharmony_ci fExitedPid_.erase(pid); 1460cb93a386Sopenharmony_ci } 1461cb93a386Sopenharmony_ci 1462cb93a386Sopenharmony_ci this->validate(); 1463cb93a386Sopenharmony_ci#if defined (SKIA_OHOS_FOR_OHOS_TRACE) && defined (SKIA_DFX_FOR_OHOS) 1464cb93a386Sopenharmony_ci traceAfterPurgeUnlockRes("purgeUnlockedResourcesByPid", simpleCacheInfo); 1465cb93a386Sopenharmony_ci#endif 1466cb93a386Sopenharmony_ci} 1467cb93a386Sopenharmony_ci 1468cb93a386Sopenharmony_civoid GrResourceCache::purgeUnlockedResourcesByTag(bool scratchResourcesOnly, const GrGpuResourceTag& tag) { 1469cb93a386Sopenharmony_ci // Sort the queue 1470cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1471cb93a386Sopenharmony_ci 1472cb93a386Sopenharmony_ci //Make a list of the scratch resources to delete 1473cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> scratchResources; 1474cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 1475cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1476cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1477cb93a386Sopenharmony_ci if (tag.filter(resource->getResourceTag()) && (!scratchResourcesOnly || !resource->getUniqueKey().isValid())) { 1478cb93a386Sopenharmony_ci *scratchResources.append() = resource; 1479cb93a386Sopenharmony_ci } 1480cb93a386Sopenharmony_ci } 1481cb93a386Sopenharmony_ci 1482cb93a386Sopenharmony_ci //Delete the scatch resource. This must be done as a separate pass 1483cb93a386Sopenharmony_ci //to avoid messing up the sorted order of the queue 1484cb93a386Sopenharmony_ci for (int i = 0; i <scratchResources.count(); i++) { 1485cb93a386Sopenharmony_ci scratchResources.getAt(i)->cacheAccess().release(); 1486cb93a386Sopenharmony_ci } 1487cb93a386Sopenharmony_ci 1488cb93a386Sopenharmony_ci this->validate(); 1489cb93a386Sopenharmony_ci} 1490cb93a386Sopenharmony_ci 1491cb93a386Sopenharmony_cibool GrResourceCache::purgeToMakeHeadroom(size_t desiredHeadroomBytes) { 1492cb93a386Sopenharmony_ci AutoValidate av(this); 1493cb93a386Sopenharmony_ci if (desiredHeadroomBytes > fMaxBytes) { 1494cb93a386Sopenharmony_ci return false; 1495cb93a386Sopenharmony_ci } 1496cb93a386Sopenharmony_ci if (this->wouldFit(desiredHeadroomBytes)) { 1497cb93a386Sopenharmony_ci return true; 1498cb93a386Sopenharmony_ci } 1499cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1500cb93a386Sopenharmony_ci 1501cb93a386Sopenharmony_ci size_t projectedBudget = fBudgetedBytes; 1502cb93a386Sopenharmony_ci int purgeCnt = 0; 1503cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); i++) { 1504cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1505cb93a386Sopenharmony_ci if (GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType()) { 1506cb93a386Sopenharmony_ci projectedBudget -= resource->gpuMemorySize(); 1507cb93a386Sopenharmony_ci } 1508cb93a386Sopenharmony_ci if (projectedBudget + desiredHeadroomBytes <= fMaxBytes) { 1509cb93a386Sopenharmony_ci purgeCnt = i + 1; 1510cb93a386Sopenharmony_ci break; 1511cb93a386Sopenharmony_ci } 1512cb93a386Sopenharmony_ci } 1513cb93a386Sopenharmony_ci if (purgeCnt == 0) { 1514cb93a386Sopenharmony_ci return false; 1515cb93a386Sopenharmony_ci } 1516cb93a386Sopenharmony_ci 1517cb93a386Sopenharmony_ci // Success! Release the resources. 1518cb93a386Sopenharmony_ci // Copy to array first so we don't mess with the queue. 1519cb93a386Sopenharmony_ci std::vector<GrGpuResource*> resources; 1520cb93a386Sopenharmony_ci resources.reserve(purgeCnt); 1521cb93a386Sopenharmony_ci for (int i = 0; i < purgeCnt; i++) { 1522cb93a386Sopenharmony_ci resources.push_back(fPurgeableQueue.at(i)); 1523cb93a386Sopenharmony_ci } 1524cb93a386Sopenharmony_ci for (GrGpuResource* resource : resources) { 1525cb93a386Sopenharmony_ci resource->cacheAccess().release(); 1526cb93a386Sopenharmony_ci } 1527cb93a386Sopenharmony_ci return true; 1528cb93a386Sopenharmony_ci} 1529cb93a386Sopenharmony_ci 1530cb93a386Sopenharmony_civoid GrResourceCache::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) { 1531cb93a386Sopenharmony_ci 1532cb93a386Sopenharmony_ci const size_t tmpByteBudget = std::max((size_t)0, fBytes - bytesToPurge); 1533cb93a386Sopenharmony_ci bool stillOverbudget = tmpByteBudget < fBytes; 1534cb93a386Sopenharmony_ci 1535cb93a386Sopenharmony_ci if (preferScratchResources && bytesToPurge < fPurgeableBytes) { 1536cb93a386Sopenharmony_ci // Sort the queue 1537cb93a386Sopenharmony_ci fPurgeableQueue.sort(); 1538cb93a386Sopenharmony_ci 1539cb93a386Sopenharmony_ci // Make a list of the scratch resources to delete 1540cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> scratchResources; 1541cb93a386Sopenharmony_ci size_t scratchByteCount = 0; 1542cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count() && stillOverbudget; i++) { 1543cb93a386Sopenharmony_ci GrGpuResource* resource = fPurgeableQueue.at(i); 1544cb93a386Sopenharmony_ci SkASSERT(resource->resourcePriv().isPurgeable()); 1545cb93a386Sopenharmony_ci if (!resource->getUniqueKey().isValid()) { 1546cb93a386Sopenharmony_ci *scratchResources.append() = resource; 1547cb93a386Sopenharmony_ci scratchByteCount += resource->gpuMemorySize(); 1548cb93a386Sopenharmony_ci stillOverbudget = tmpByteBudget < fBytes - scratchByteCount; 1549cb93a386Sopenharmony_ci } 1550cb93a386Sopenharmony_ci } 1551cb93a386Sopenharmony_ci 1552cb93a386Sopenharmony_ci // Delete the scratch resources. This must be done as a separate pass 1553cb93a386Sopenharmony_ci // to avoid messing up the sorted order of the queue 1554cb93a386Sopenharmony_ci for (int i = 0; i < scratchResources.count(); i++) { 1555cb93a386Sopenharmony_ci scratchResources.getAt(i)->cacheAccess().release(); 1556cb93a386Sopenharmony_ci } 1557cb93a386Sopenharmony_ci stillOverbudget = tmpByteBudget < fBytes; 1558cb93a386Sopenharmony_ci 1559cb93a386Sopenharmony_ci this->validate(); 1560cb93a386Sopenharmony_ci } 1561cb93a386Sopenharmony_ci 1562cb93a386Sopenharmony_ci // Purge any remaining resources in LRU order 1563cb93a386Sopenharmony_ci if (stillOverbudget) { 1564cb93a386Sopenharmony_ci const size_t cachedByteCount = fMaxBytes; 1565cb93a386Sopenharmony_ci fMaxBytes = tmpByteBudget; 1566cb93a386Sopenharmony_ci this->purgeAsNeeded(); 1567cb93a386Sopenharmony_ci fMaxBytes = cachedByteCount; 1568cb93a386Sopenharmony_ci } 1569cb93a386Sopenharmony_ci} 1570cb93a386Sopenharmony_ci 1571cb93a386Sopenharmony_cibool GrResourceCache::requestsFlush() const { 1572cb93a386Sopenharmony_ci return this->overBudget() && !fPurgeableQueue.count() && 1573cb93a386Sopenharmony_ci fNumBudgetedResourcesFlushWillMakePurgeable > 0; 1574cb93a386Sopenharmony_ci} 1575cb93a386Sopenharmony_ci 1576cb93a386Sopenharmony_civoid GrResourceCache::insertDelayedTextureUnref(GrTexture* texture) { 1577cb93a386Sopenharmony_ci texture->ref(); 1578cb93a386Sopenharmony_ci uint32_t id = texture->uniqueID().asUInt(); 1579cb93a386Sopenharmony_ci if (auto* data = fTexturesAwaitingUnref.find(id)) { 1580cb93a386Sopenharmony_ci data->addRef(); 1581cb93a386Sopenharmony_ci } else { 1582cb93a386Sopenharmony_ci fTexturesAwaitingUnref.set(id, {texture}); 1583cb93a386Sopenharmony_ci } 1584cb93a386Sopenharmony_ci} 1585cb93a386Sopenharmony_ci 1586cb93a386Sopenharmony_civoid GrResourceCache::processFreedGpuResources() { 1587cb93a386Sopenharmony_ci if (!fTexturesAwaitingUnref.count()) { 1588cb93a386Sopenharmony_ci return; 1589cb93a386Sopenharmony_ci } 1590cb93a386Sopenharmony_ci 1591cb93a386Sopenharmony_ci SkTArray<GrTextureFreedMessage> msgs; 1592cb93a386Sopenharmony_ci fFreedTextureInbox.poll(&msgs); 1593cb93a386Sopenharmony_ci for (int i = 0; i < msgs.count(); ++i) { 1594cb93a386Sopenharmony_ci SkASSERT(msgs[i].fIntendedRecipient == fOwningContextID); 1595cb93a386Sopenharmony_ci uint32_t id = msgs[i].fTexture->uniqueID().asUInt(); 1596cb93a386Sopenharmony_ci TextureAwaitingUnref* info = fTexturesAwaitingUnref.find(id); 1597cb93a386Sopenharmony_ci // If the GrContext was released or abandoned then fTexturesAwaitingUnref should have been 1598cb93a386Sopenharmony_ci // empty and we would have returned early above. Thus, any texture from a message should be 1599cb93a386Sopenharmony_ci // in the list of fTexturesAwaitingUnref. 1600cb93a386Sopenharmony_ci SkASSERT(info); 1601cb93a386Sopenharmony_ci info->unref(); 1602cb93a386Sopenharmony_ci if (info->finished()) { 1603cb93a386Sopenharmony_ci fTexturesAwaitingUnref.remove(id); 1604cb93a386Sopenharmony_ci } 1605cb93a386Sopenharmony_ci } 1606cb93a386Sopenharmony_ci} 1607cb93a386Sopenharmony_ci 1608cb93a386Sopenharmony_civoid GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) { 1609cb93a386Sopenharmony_ci int index = fNonpurgeableResources.count(); 1610cb93a386Sopenharmony_ci *fNonpurgeableResources.append() = resource; 1611cb93a386Sopenharmony_ci *resource->cacheAccess().accessCacheIndex() = index; 1612cb93a386Sopenharmony_ci} 1613cb93a386Sopenharmony_ci 1614cb93a386Sopenharmony_civoid GrResourceCache::removeFromNonpurgeableArray(GrGpuResource* resource) { 1615cb93a386Sopenharmony_ci int* index = resource->cacheAccess().accessCacheIndex(); 1616cb93a386Sopenharmony_ci // Fill the hole we will create in the array with the tail object, adjust its index, and 1617cb93a386Sopenharmony_ci // then pop the array 1618cb93a386Sopenharmony_ci GrGpuResource* tail = *(fNonpurgeableResources.end() - 1); 1619cb93a386Sopenharmony_ci SkASSERT(fNonpurgeableResources[*index] == resource); 1620cb93a386Sopenharmony_ci fNonpurgeableResources[*index] = tail; 1621cb93a386Sopenharmony_ci *tail->cacheAccess().accessCacheIndex() = *index; 1622cb93a386Sopenharmony_ci fNonpurgeableResources.pop(); 1623cb93a386Sopenharmony_ci SkDEBUGCODE(*index = -1); 1624cb93a386Sopenharmony_ci} 1625cb93a386Sopenharmony_ci 1626cb93a386Sopenharmony_ciuint32_t GrResourceCache::getNextTimestamp() { 1627cb93a386Sopenharmony_ci // If we wrap then all the existing resources will appear older than any resources that get 1628cb93a386Sopenharmony_ci // a timestamp after the wrap. 1629cb93a386Sopenharmony_ci if (0 == fTimestamp) { 1630cb93a386Sopenharmony_ci int count = this->getResourceCount(); 1631cb93a386Sopenharmony_ci if (count) { 1632cb93a386Sopenharmony_ci // Reset all the timestamps. We sort the resources by timestamp and then assign 1633cb93a386Sopenharmony_ci // sequential timestamps beginning with 0. This is O(n*lg(n)) but it should be extremely 1634cb93a386Sopenharmony_ci // rare. 1635cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> sortedPurgeableResources; 1636cb93a386Sopenharmony_ci sortedPurgeableResources.setReserve(fPurgeableQueue.count()); 1637cb93a386Sopenharmony_ci 1638cb93a386Sopenharmony_ci while (fPurgeableQueue.count()) { 1639cb93a386Sopenharmony_ci *sortedPurgeableResources.append() = fPurgeableQueue.peek(); 1640cb93a386Sopenharmony_ci fPurgeableQueue.pop(); 1641cb93a386Sopenharmony_ci } 1642cb93a386Sopenharmony_ci 1643cb93a386Sopenharmony_ci SkTQSort(fNonpurgeableResources.begin(), fNonpurgeableResources.end(), 1644cb93a386Sopenharmony_ci CompareTimestamp); 1645cb93a386Sopenharmony_ci 1646cb93a386Sopenharmony_ci // Pick resources out of the purgeable and non-purgeable arrays based on lowest 1647cb93a386Sopenharmony_ci // timestamp and assign new timestamps. 1648cb93a386Sopenharmony_ci int currP = 0; 1649cb93a386Sopenharmony_ci int currNP = 0; 1650cb93a386Sopenharmony_ci while (currP < sortedPurgeableResources.count() && 1651cb93a386Sopenharmony_ci currNP < fNonpurgeableResources.count()) { 1652cb93a386Sopenharmony_ci uint32_t tsP = sortedPurgeableResources[currP]->cacheAccess().timestamp(); 1653cb93a386Sopenharmony_ci uint32_t tsNP = fNonpurgeableResources[currNP]->cacheAccess().timestamp(); 1654cb93a386Sopenharmony_ci SkASSERT(tsP != tsNP); 1655cb93a386Sopenharmony_ci if (tsP < tsNP) { 1656cb93a386Sopenharmony_ci sortedPurgeableResources[currP++]->cacheAccess().setTimestamp(fTimestamp++); 1657cb93a386Sopenharmony_ci } else { 1658cb93a386Sopenharmony_ci // Correct the index in the nonpurgeable array stored on the resource post-sort. 1659cb93a386Sopenharmony_ci *fNonpurgeableResources[currNP]->cacheAccess().accessCacheIndex() = currNP; 1660cb93a386Sopenharmony_ci fNonpurgeableResources[currNP++]->cacheAccess().setTimestamp(fTimestamp++); 1661cb93a386Sopenharmony_ci } 1662cb93a386Sopenharmony_ci } 1663cb93a386Sopenharmony_ci 1664cb93a386Sopenharmony_ci // The above loop ended when we hit the end of one array. Finish the other one. 1665cb93a386Sopenharmony_ci while (currP < sortedPurgeableResources.count()) { 1666cb93a386Sopenharmony_ci sortedPurgeableResources[currP++]->cacheAccess().setTimestamp(fTimestamp++); 1667cb93a386Sopenharmony_ci } 1668cb93a386Sopenharmony_ci while (currNP < fNonpurgeableResources.count()) { 1669cb93a386Sopenharmony_ci *fNonpurgeableResources[currNP]->cacheAccess().accessCacheIndex() = currNP; 1670cb93a386Sopenharmony_ci fNonpurgeableResources[currNP++]->cacheAccess().setTimestamp(fTimestamp++); 1671cb93a386Sopenharmony_ci } 1672cb93a386Sopenharmony_ci 1673cb93a386Sopenharmony_ci // Rebuild the queue. 1674cb93a386Sopenharmony_ci for (int i = 0; i < sortedPurgeableResources.count(); ++i) { 1675cb93a386Sopenharmony_ci fPurgeableQueue.insert(sortedPurgeableResources[i]); 1676cb93a386Sopenharmony_ci } 1677cb93a386Sopenharmony_ci 1678cb93a386Sopenharmony_ci this->validate(); 1679cb93a386Sopenharmony_ci SkASSERT(count == this->getResourceCount()); 1680cb93a386Sopenharmony_ci 1681cb93a386Sopenharmony_ci // count should be the next timestamp we return. 1682cb93a386Sopenharmony_ci SkASSERT(fTimestamp == SkToU32(count)); 1683cb93a386Sopenharmony_ci } 1684cb93a386Sopenharmony_ci } 1685cb93a386Sopenharmony_ci return fTimestamp++; 1686cb93a386Sopenharmony_ci} 1687cb93a386Sopenharmony_ci 1688cb93a386Sopenharmony_civoid GrResourceCache::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { 1689cb93a386Sopenharmony_ci SkTDArray<GrGpuResource*> resources; 1690cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 1691cb93a386Sopenharmony_ci *resources.append() = fNonpurgeableResources[i]; 1692cb93a386Sopenharmony_ci } 1693cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); ++i) { 1694cb93a386Sopenharmony_ci *resources.append() = fPurgeableQueue.at(i); 1695cb93a386Sopenharmony_ci } 1696cb93a386Sopenharmony_ci for (int i = 0; i < resources.count(); i++) { 1697cb93a386Sopenharmony_ci auto resource = resources.getAt(i); 1698cb93a386Sopenharmony_ci if (!resource || resource->wasDestroyed()) { 1699cb93a386Sopenharmony_ci continue; 1700cb93a386Sopenharmony_ci } 1701cb93a386Sopenharmony_ci resource->dumpMemoryStatistics(traceMemoryDump); 1702cb93a386Sopenharmony_ci } 1703cb93a386Sopenharmony_ci} 1704cb93a386Sopenharmony_ci 1705cb93a386Sopenharmony_civoid GrResourceCache::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump, const GrGpuResourceTag& tag) const { 1706cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 1707cb93a386Sopenharmony_ci if (tag.filter(fNonpurgeableResources[i]->getResourceTag())) { 1708cb93a386Sopenharmony_ci fNonpurgeableResources[i]->dumpMemoryStatistics(traceMemoryDump); 1709cb93a386Sopenharmony_ci } 1710cb93a386Sopenharmony_ci } 1711cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); ++i) { 1712cb93a386Sopenharmony_ci if (tag.filter(fPurgeableQueue.at(i)->getResourceTag())) { 1713cb93a386Sopenharmony_ci fPurgeableQueue.at(i)->dumpMemoryStatistics(traceMemoryDump); 1714cb93a386Sopenharmony_ci } 1715cb93a386Sopenharmony_ci } 1716cb93a386Sopenharmony_ci} 1717cb93a386Sopenharmony_ci 1718cb93a386Sopenharmony_ci#if GR_CACHE_STATS 1719cb93a386Sopenharmony_civoid GrResourceCache::getStats(Stats* stats) const { 1720cb93a386Sopenharmony_ci stats->reset(); 1721cb93a386Sopenharmony_ci 1722cb93a386Sopenharmony_ci stats->fTotal = this->getResourceCount(); 1723cb93a386Sopenharmony_ci stats->fNumNonPurgeable = fNonpurgeableResources.count(); 1724cb93a386Sopenharmony_ci stats->fNumPurgeable = fPurgeableQueue.count(); 1725cb93a386Sopenharmony_ci 1726cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 1727cb93a386Sopenharmony_ci stats->update(fNonpurgeableResources[i]); 1728cb93a386Sopenharmony_ci } 1729cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); ++i) { 1730cb93a386Sopenharmony_ci stats->update(fPurgeableQueue.at(i)); 1731cb93a386Sopenharmony_ci } 1732cb93a386Sopenharmony_ci} 1733cb93a386Sopenharmony_ci 1734cb93a386Sopenharmony_ci#if GR_TEST_UTILS 1735cb93a386Sopenharmony_civoid GrResourceCache::dumpStats(SkString* out) const { 1736cb93a386Sopenharmony_ci this->validate(); 1737cb93a386Sopenharmony_ci 1738cb93a386Sopenharmony_ci Stats stats; 1739cb93a386Sopenharmony_ci 1740cb93a386Sopenharmony_ci this->getStats(&stats); 1741cb93a386Sopenharmony_ci 1742cb93a386Sopenharmony_ci float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes; 1743cb93a386Sopenharmony_ci 1744cb93a386Sopenharmony_ci out->appendf("Budget: %d bytes\n", (int)fMaxBytes); 1745cb93a386Sopenharmony_ci out->appendf("\t\tEntry Count: current %d" 1746cb93a386Sopenharmony_ci " (%d budgeted, %d wrapped, %d locked, %d scratch), high %d\n", 1747cb93a386Sopenharmony_ci stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable, 1748cb93a386Sopenharmony_ci stats.fScratch, fHighWaterCount); 1749cb93a386Sopenharmony_ci out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n", 1750cb93a386Sopenharmony_ci SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization, 1751cb93a386Sopenharmony_ci SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes)); 1752cb93a386Sopenharmony_ci} 1753cb93a386Sopenharmony_ci 1754cb93a386Sopenharmony_civoid GrResourceCache::dumpStatsKeyValuePairs(SkTArray<SkString>* keys, 1755cb93a386Sopenharmony_ci SkTArray<double>* values) const { 1756cb93a386Sopenharmony_ci this->validate(); 1757cb93a386Sopenharmony_ci 1758cb93a386Sopenharmony_ci Stats stats; 1759cb93a386Sopenharmony_ci this->getStats(&stats); 1760cb93a386Sopenharmony_ci 1761cb93a386Sopenharmony_ci keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable); 1762cb93a386Sopenharmony_ci} 1763cb93a386Sopenharmony_ci#endif // GR_TEST_UTILS 1764cb93a386Sopenharmony_ci#endif // GR_CACHE_STATS 1765cb93a386Sopenharmony_ci 1766cb93a386Sopenharmony_ci#ifdef SK_DEBUG 1767cb93a386Sopenharmony_civoid GrResourceCache::validate() const { 1768cb93a386Sopenharmony_ci // Reduce the frequency of validations for large resource counts. 1769cb93a386Sopenharmony_ci static SkRandom gRandom; 1770cb93a386Sopenharmony_ci int mask = (SkNextPow2(fCount + 1) >> 5) - 1; 1771cb93a386Sopenharmony_ci if (~mask && (gRandom.nextU() & mask)) { 1772cb93a386Sopenharmony_ci return; 1773cb93a386Sopenharmony_ci } 1774cb93a386Sopenharmony_ci 1775cb93a386Sopenharmony_ci struct Stats { 1776cb93a386Sopenharmony_ci size_t fBytes; 1777cb93a386Sopenharmony_ci int fBudgetedCount; 1778cb93a386Sopenharmony_ci size_t fBudgetedBytes; 1779cb93a386Sopenharmony_ci int fLocked; 1780cb93a386Sopenharmony_ci int fScratch; 1781cb93a386Sopenharmony_ci int fCouldBeScratch; 1782cb93a386Sopenharmony_ci int fContent; 1783cb93a386Sopenharmony_ci const ScratchMap* fScratchMap; 1784cb93a386Sopenharmony_ci const UniqueHash* fUniqueHash; 1785cb93a386Sopenharmony_ci 1786cb93a386Sopenharmony_ci Stats(const GrResourceCache* cache) { 1787cb93a386Sopenharmony_ci memset(this, 0, sizeof(*this)); 1788cb93a386Sopenharmony_ci fScratchMap = &cache->fScratchMap; 1789cb93a386Sopenharmony_ci fUniqueHash = &cache->fUniqueHash; 1790cb93a386Sopenharmony_ci } 1791cb93a386Sopenharmony_ci 1792cb93a386Sopenharmony_ci void update(GrGpuResource* resource) { 1793cb93a386Sopenharmony_ci fBytes += resource->gpuMemorySize(); 1794cb93a386Sopenharmony_ci 1795cb93a386Sopenharmony_ci if (!resource->resourcePriv().isPurgeable()) { 1796cb93a386Sopenharmony_ci ++fLocked; 1797cb93a386Sopenharmony_ci } 1798cb93a386Sopenharmony_ci 1799cb93a386Sopenharmony_ci const GrScratchKey& scratchKey = resource->resourcePriv().getScratchKey(); 1800cb93a386Sopenharmony_ci const GrUniqueKey& uniqueKey = resource->getUniqueKey(); 1801cb93a386Sopenharmony_ci 1802cb93a386Sopenharmony_ci if (resource->cacheAccess().isUsableAsScratch()) { 1803cb93a386Sopenharmony_ci SkASSERT(!uniqueKey.isValid()); 1804cb93a386Sopenharmony_ci SkASSERT(GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType()); 1805cb93a386Sopenharmony_ci SkASSERT(!resource->cacheAccess().hasRef()); 1806cb93a386Sopenharmony_ci ++fScratch; 1807cb93a386Sopenharmony_ci SkASSERT(fScratchMap->countForKey(scratchKey)); 1808cb93a386Sopenharmony_ci SkASSERT(!resource->resourcePriv().refsWrappedObjects()); 1809cb93a386Sopenharmony_ci } else if (scratchKey.isValid()) { 1810cb93a386Sopenharmony_ci SkASSERT(GrBudgetedType::kBudgeted != resource->resourcePriv().budgetedType() || 1811cb93a386Sopenharmony_ci uniqueKey.isValid() || resource->cacheAccess().hasRef()); 1812cb93a386Sopenharmony_ci SkASSERT(!resource->resourcePriv().refsWrappedObjects()); 1813cb93a386Sopenharmony_ci SkASSERT(!fScratchMap->has(resource, scratchKey)); 1814cb93a386Sopenharmony_ci } 1815cb93a386Sopenharmony_ci if (uniqueKey.isValid()) { 1816cb93a386Sopenharmony_ci ++fContent; 1817cb93a386Sopenharmony_ci SkASSERT(fUniqueHash->find(uniqueKey) == resource); 1818cb93a386Sopenharmony_ci SkASSERT(GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType() || 1819cb93a386Sopenharmony_ci resource->resourcePriv().refsWrappedObjects()); 1820cb93a386Sopenharmony_ci } 1821cb93a386Sopenharmony_ci 1822cb93a386Sopenharmony_ci if (GrBudgetedType::kBudgeted == resource->resourcePriv().budgetedType()) { 1823cb93a386Sopenharmony_ci ++fBudgetedCount; 1824cb93a386Sopenharmony_ci fBudgetedBytes += resource->gpuMemorySize(); 1825cb93a386Sopenharmony_ci } 1826cb93a386Sopenharmony_ci } 1827cb93a386Sopenharmony_ci }; 1828cb93a386Sopenharmony_ci 1829cb93a386Sopenharmony_ci { 1830cb93a386Sopenharmony_ci int count = 0; 1831cb93a386Sopenharmony_ci fScratchMap.foreach([&](const GrGpuResource& resource) { 1832cb93a386Sopenharmony_ci SkASSERT(resource.cacheAccess().isUsableAsScratch()); 1833cb93a386Sopenharmony_ci count++; 1834cb93a386Sopenharmony_ci }); 1835cb93a386Sopenharmony_ci SkASSERT(count == fScratchMap.count()); 1836cb93a386Sopenharmony_ci } 1837cb93a386Sopenharmony_ci 1838cb93a386Sopenharmony_ci Stats stats(this); 1839cb93a386Sopenharmony_ci size_t purgeableBytes = 0; 1840cb93a386Sopenharmony_ci int numBudgetedResourcesFlushWillMakePurgeable = 0; 1841cb93a386Sopenharmony_ci 1842cb93a386Sopenharmony_ci for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 1843cb93a386Sopenharmony_ci SkASSERT(!fNonpurgeableResources[i]->resourcePriv().isPurgeable() || 1844cb93a386Sopenharmony_ci fNewlyPurgeableResourceForValidation == fNonpurgeableResources[i]); 1845cb93a386Sopenharmony_ci SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() == i); 1846cb93a386Sopenharmony_ci SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); 1847cb93a386Sopenharmony_ci if (fNonpurgeableResources[i]->resourcePriv().budgetedType() == GrBudgetedType::kBudgeted && 1848cb93a386Sopenharmony_ci !fNonpurgeableResources[i]->cacheAccess().hasRefOrCommandBufferUsage() && 1849cb93a386Sopenharmony_ci fNewlyPurgeableResourceForValidation != fNonpurgeableResources[i]) { 1850cb93a386Sopenharmony_ci ++numBudgetedResourcesFlushWillMakePurgeable; 1851cb93a386Sopenharmony_ci } 1852cb93a386Sopenharmony_ci stats.update(fNonpurgeableResources[i]); 1853cb93a386Sopenharmony_ci } 1854cb93a386Sopenharmony_ci for (int i = 0; i < fPurgeableQueue.count(); ++i) { 1855cb93a386Sopenharmony_ci SkASSERT(fPurgeableQueue.at(i)->resourcePriv().isPurgeable()); 1856cb93a386Sopenharmony_ci SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i); 1857cb93a386Sopenharmony_ci SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed()); 1858cb93a386Sopenharmony_ci stats.update(fPurgeableQueue.at(i)); 1859cb93a386Sopenharmony_ci purgeableBytes += fPurgeableQueue.at(i)->gpuMemorySize(); 1860cb93a386Sopenharmony_ci } 1861cb93a386Sopenharmony_ci 1862cb93a386Sopenharmony_ci SkASSERT(fCount == this->getResourceCount()); 1863cb93a386Sopenharmony_ci SkASSERT(fBudgetedCount <= fCount); 1864cb93a386Sopenharmony_ci SkASSERT(fBudgetedBytes <= fBytes); 1865cb93a386Sopenharmony_ci SkASSERT(stats.fBytes == fBytes); 1866cb93a386Sopenharmony_ci SkASSERT(fNumBudgetedResourcesFlushWillMakePurgeable == 1867cb93a386Sopenharmony_ci numBudgetedResourcesFlushWillMakePurgeable); 1868cb93a386Sopenharmony_ci SkASSERT(stats.fBudgetedBytes == fBudgetedBytes); 1869cb93a386Sopenharmony_ci SkASSERT(stats.fBudgetedCount == fBudgetedCount); 1870cb93a386Sopenharmony_ci SkASSERT(purgeableBytes == fPurgeableBytes); 1871cb93a386Sopenharmony_ci#if GR_CACHE_STATS 1872cb93a386Sopenharmony_ci SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); 1873cb93a386Sopenharmony_ci SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); 1874cb93a386Sopenharmony_ci SkASSERT(fBytes <= fHighWaterBytes); 1875cb93a386Sopenharmony_ci SkASSERT(fCount <= fHighWaterCount); 1876cb93a386Sopenharmony_ci SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes); 1877cb93a386Sopenharmony_ci SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount); 1878cb93a386Sopenharmony_ci#endif 1879cb93a386Sopenharmony_ci SkASSERT(stats.fContent == fUniqueHash.count()); 1880cb93a386Sopenharmony_ci SkASSERT(stats.fScratch == fScratchMap.count()); 1881cb93a386Sopenharmony_ci 1882cb93a386Sopenharmony_ci // This assertion is not currently valid because we can be in recursive notifyCntReachedZero() 1883cb93a386Sopenharmony_ci // calls. This will be fixed when subresource registration is explicit. 1884cb93a386Sopenharmony_ci // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; 1885cb93a386Sopenharmony_ci // SkASSERT(!overBudget || locked == count || fPurging); 1886cb93a386Sopenharmony_ci} 1887cb93a386Sopenharmony_ci#endif // SK_DEBUG 1888cb93a386Sopenharmony_ci 1889cb93a386Sopenharmony_cibool GrResourceCache::isInCache(const GrGpuResource* resource) const { 1890cb93a386Sopenharmony_ci int index = *resource->cacheAccess().accessCacheIndex(); 1891cb93a386Sopenharmony_ci if (index < 0) { 1892cb93a386Sopenharmony_ci return false; 1893cb93a386Sopenharmony_ci } 1894cb93a386Sopenharmony_ci if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource) { 1895cb93a386Sopenharmony_ci return true; 1896cb93a386Sopenharmony_ci } 1897cb93a386Sopenharmony_ci if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index] == resource) { 1898cb93a386Sopenharmony_ci return true; 1899cb93a386Sopenharmony_ci } 1900cb93a386Sopenharmony_ci SkDEBUGFAIL("Resource index should be -1 or the resource should be in the cache."); 1901cb93a386Sopenharmony_ci return false; 1902cb93a386Sopenharmony_ci} 1903cb93a386Sopenharmony_ci 1904cb93a386Sopenharmony_cibool GrResourceCache::isInPurgeableCache(const GrGpuResource* resource) const { 1905cb93a386Sopenharmony_ci int index = *resource->cacheAccess().accessCacheIndex(); 1906cb93a386Sopenharmony_ci if (index < 0) { 1907cb93a386Sopenharmony_ci return false; 1908cb93a386Sopenharmony_ci } 1909cb93a386Sopenharmony_ci if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource) { 1910cb93a386Sopenharmony_ci return true; 1911cb93a386Sopenharmony_ci } 1912cb93a386Sopenharmony_ci SkDEBUGFAIL("OHOS Resource index should be -1 or the resource should be in the cache."); 1913cb93a386Sopenharmony_ci return false; 1914cb93a386Sopenharmony_ci} 1915cb93a386Sopenharmony_ci 1916cb93a386Sopenharmony_cibool GrResourceCache::isInNonpurgeableCache(const GrGpuResource* resource) const { 1917cb93a386Sopenharmony_ci int index = *resource->cacheAccess().accessCacheIndex(); 1918cb93a386Sopenharmony_ci if (index < 0) { 1919cb93a386Sopenharmony_ci return false; 1920cb93a386Sopenharmony_ci } 1921cb93a386Sopenharmony_ci if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index] == resource) { 1922cb93a386Sopenharmony_ci return true; 1923cb93a386Sopenharmony_ci } 1924cb93a386Sopenharmony_ci SkDEBUGFAIL("OHOS Resource index should be -1 or the resource should be in the cache."); 1925cb93a386Sopenharmony_ci return false; 1926cb93a386Sopenharmony_ci} 1927cb93a386Sopenharmony_ci 1928cb93a386Sopenharmony_ci#if GR_TEST_UTILS 1929cb93a386Sopenharmony_ci 1930cb93a386Sopenharmony_ciint GrResourceCache::countUniqueKeysWithTag(const char* tag) const { 1931cb93a386Sopenharmony_ci int count = 0; 1932cb93a386Sopenharmony_ci fUniqueHash.foreach([&](const GrGpuResource& resource){ 1933cb93a386Sopenharmony_ci if (0 == strcmp(tag, resource.getUniqueKey().tag())) { 1934cb93a386Sopenharmony_ci ++count; 1935cb93a386Sopenharmony_ci } 1936cb93a386Sopenharmony_ci }); 1937cb93a386Sopenharmony_ci return count; 1938cb93a386Sopenharmony_ci} 1939cb93a386Sopenharmony_ci 1940cb93a386Sopenharmony_civoid GrResourceCache::changeTimestamp(uint32_t newTimestamp) { 1941cb93a386Sopenharmony_ci fTimestamp = newTimestamp; 1942cb93a386Sopenharmony_ci} 1943cb93a386Sopenharmony_ci 1944cb93a386Sopenharmony_ci#endif // GR_TEST_UTILS 1945