chromium/third_party/skia/src/gpu/ganesh/GrResourceCache.cpp

/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/ganesh/GrResourceCache.h"

#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/private/base/SingleOwner.h"
#include "include/private/base/SkNoncopyable.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkMathPriv.h"
#include "src/base/SkRandom.h"
#include "src/base/SkTSort.h"
#include "src/core/SkMessageBus.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGpuResourceCacheAccess.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrThreadSafeCache.h"

#include <algorithm>
#include <chrono>
#include <cstring>
#include <vector>

usingnamespaceskia_private;

DECLARE_SKMESSAGEBUS_MESSAGE()

DECLARE_SKMESSAGEBUS_MESSAGE()

#define ASSERT_SINGLE_OWNER

//////////////////////////////////////////////////////////////////////////////

class GrResourceCache::AutoValidate : ::SkNoncopyable {};

//////////////////////////////////////////////////////////////////////////////

GrResourceCache::GrResourceCache(skgpu::SingleOwner* singleOwner,
                                 GrDirectContext::DirectContextID owningContextID,
                                 uint32_t familyID)
        :{}

GrResourceCache::~GrResourceCache() {}

void GrResourceCache::setLimit(size_t bytes) {}

void GrResourceCache::insertResource(GrGpuResource* resource) {}

void GrResourceCache::removeResource(GrGpuResource* resource) {}

void GrResourceCache::abandonAll() {}

void GrResourceCache::releaseAll() {}

void GrResourceCache::refResource(GrGpuResource* resource) {}

GrGpuResource* GrResourceCache::findAndRefScratchResource(const skgpu::ScratchKey& scratchKey) {}

void GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) {}

void GrResourceCache::removeUniqueKey(GrGpuResource* resource) {}

void GrResourceCache::changeUniqueKey(GrGpuResource* resource, const skgpu::UniqueKey& newKey) {}

void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) {}

void GrResourceCache::notifyARefCntReachedZero(GrGpuResource* resource,
                                               GrGpuResource::LastRemovedRef removedRef) {}

void GrResourceCache::didChangeBudgetStatus(GrGpuResource* resource) {}

void GrResourceCache::purgeAsNeeded() {}

void GrResourceCache::purgeUnlockedResources(const skgpu::StdSteadyClock::time_point* purgeTime,
                                             GrPurgeResourceOptions opts) {}

bool GrResourceCache::purgeToMakeHeadroom(size_t desiredHeadroomBytes) {}

void GrResourceCache::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {}

bool GrResourceCache::requestsFlush() const {}

void GrResourceCache::processFreedGpuResources() {}

void GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) {}

void GrResourceCache::removeFromNonpurgeableArray(GrGpuResource* resource) {}

uint32_t GrResourceCache::getNextTimestamp() {}

void GrResourceCache::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {}

#if GR_CACHE_STATS
void GrResourceCache::getStats(Stats* stats) const {}

#if defined(GPU_TEST_UTILS)
void GrResourceCache::dumpStats(SkString* out) const {
    this->validate();

    Stats stats;

    this->getStats(&stats);

    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;

    out->appendf("Budget: %d bytes\n", (int)fMaxBytes);
    out->appendf("\t\tEntry Count: current %d"
                 " (%d budgeted, %d wrapped, %d locked, %d scratch), high %d\n",
                 stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable,
                 stats.fScratch, fHighWaterCount);
    out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
                 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
                 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
}

void GrResourceCache::dumpStatsKeyValuePairs(TArray<SkString>* keys,
                                             TArray<double>* values) const {
    this->validate();

    Stats stats;
    this->getStats(&stats);

    keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable);
}
#endif // defined(GPU_TEST_UTILS)
#endif // GR_CACHE_STATS

#ifdef SK_DEBUG
void GrResourceCache::validate() const {}

bool GrResourceCache::isInCache(const GrGpuResource* resource) const {}

#endif // SK_DEBUG

#if defined(GPU_TEST_UTILS)

int GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
    int count = 0;
    fUniqueHash.foreach([&](const GrGpuResource& resource){
        if (0 == strcmp(tag, resource.getUniqueKey().tag())) {
            ++count;
        }
    });
    return count;
}

void GrResourceCache::changeTimestamp(uint32_t newTimestamp) {
    fTimestamp = newTimestamp;
}

void GrResourceCache::visitSurfaces(
        const std::function<void(const GrSurface*, bool purgeable)>& func) const {

    for (int i = 0; i < fNonpurgeableResources.size(); ++i) {
        if (const GrSurface* surf = fNonpurgeableResources[i]->asSurface()) {
            func(surf, /* purgeable= */ false);
        }
    }
    for (int i = 0; i < fPurgeableQueue.count(); ++i) {
        if (const GrSurface* surf = fPurgeableQueue.at(i)->asSurface()) {
            func(surf, /* purgeable= */ true);
        }
    }
}

#endif // defined(GPU_TEST_UTILS)