* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tests/Test.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "src/core/SkCanvasPriv.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/Device.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Resource.h"
#include "src/gpu/graphite/ResourceCache.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/SharedContext.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureProxyView.h"
#include "src/gpu/graphite/TextureUtils.h"
#include "src/image/SkImage_Base.h"
#include "tools/Resources.h"
#include "tools/graphite/GraphiteTestContext.h"
namespace skgpu::graphite {
class TestResource : public Resource {
public:
static sk_sp<TestResource> Make(const SharedContext* sharedContext,
Ownership owned,
skgpu::Budgeted budgeted,
Shareable shareable,
size_t gpuMemorySize = 1) {
auto resource = sk_sp<TestResource>(new TestResource(sharedContext,
owned,
budgeted,
gpuMemorySize));
if (!resource) {
return nullptr;
}
GraphiteResourceKey key;
CreateKey(&key, shareable);
resource->setKey(key);
return resource;
}
const char* getResourceType() const override { return "Test Resource"; }
static void CreateKey(GraphiteResourceKey* key, Shareable shareable) {
static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
static const ResourceType kShareableType = GraphiteResourceKey::GenerateResourceType();
ResourceType type = shareable == Shareable::kNo ? kType : kShareableType;
GraphiteResourceKey::Builder(key, type, 0, shareable);
}
private:
TestResource(const SharedContext* sharedContext,
Ownership owned,
skgpu::Budgeted budgeted,
size_t gpuMemorySize)
: Resource(sharedContext, owned, budgeted, gpuMemorySize) {}
void freeGpuData() override {}
};
static sk_sp<SkData> create_image_data(const SkImageInfo& info) {
const size_t rowBytes = info.minRowBytes();
sk_sp<SkData> data(SkData::MakeUninitialized(rowBytes * info.height()));
{
SkBitmap bm;
bm.installPixels(info, data->writable_data(), rowBytes);
SkCanvas canvas(bm);
canvas.clear(SK_ColorRED);
}
return data;
}
static skgpu::graphite::TextureProxy* top_device_graphite_target_proxy(SkCanvas* canvas) {
if (auto gpuDevice = SkCanvasPriv::TopDevice(canvas)->asGraphiteDevice()) {
return gpuDevice->target();
}
return nullptr;
}
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteBudgetedResourcesTest,
reporter,
context,
testContext,
true,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 0);
auto resource = TestResource::Make(
sharedContext, Ownership::kOwned, skgpu::Budgeted::kNo, Shareable::kNo);
if (!resource) {
ERRORF(reporter, "Failed to make TestResource");
return;
}
Resource* resourcePtr = resource.get();
REPORTER_ASSERT(reporter, resource->budgeted() == skgpu::Budgeted::kNo);
resourceCache->insertResource(resourcePtr);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 0);
resource.reset();
resourceCache->forceProcessReturnedResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 1);
REPORTER_ASSERT(reporter, resourcePtr->budgeted() == skgpu::Budgeted::kYes);
GraphiteResourceKey key;
TestResource::CreateKey(&key, Shareable::kNo);
Resource* resourcePtr2 = resourceCache->findAndRefResource(key, skgpu::Budgeted::kNo);
REPORTER_ASSERT(reporter, resourcePtr == resourcePtr2);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 0);
REPORTER_ASSERT(reporter, resourcePtr2->budgeted() == skgpu::Budgeted::kNo);
resourcePtr2->unref();
resourceCache->forceProcessReturnedResources();
resource = TestResource::Make(
sharedContext, Ownership::kOwned, skgpu::Budgeted::kYes, Shareable::kYes);
if (!resource) {
ERRORF(reporter, "Failed to make TestResource");
return;
}
resourcePtr = resource.get();
REPORTER_ASSERT(reporter, resource->budgeted() == skgpu::Budgeted::kYes);
resourceCache->insertResource(resourcePtr);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
resource.reset();
resourceCache->forceProcessReturnedResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
REPORTER_ASSERT(reporter, resourcePtr->budgeted() == skgpu::Budgeted::kYes);
TestResource::CreateKey(&key, Shareable::kYes);
resourcePtr2 = resourceCache->findAndRefResource(key, skgpu::Budgeted::kYes);
REPORTER_ASSERT(reporter, resourcePtr == resourcePtr2);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
REPORTER_ASSERT(reporter, resourcePtr2->budgeted() == skgpu::Budgeted::kYes);
resourcePtr2->unref();
auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
sk_sp<SkData> data(create_image_data(info));
sk_sp<SkImage> image = SkImages::RasterFromData(info, std::move(data), info.minRowBytes());
REPORTER_ASSERT(reporter, image);
sk_sp<SkImage> imageGpu = SkImages::TextureFromImage(recorder.get(), image, {});
REPORTER_ASSERT(reporter, imageGpu);
TextureProxy* imageProxy = nullptr;
{
auto view = skgpu::graphite::AsView(imageGpu.get());
REPORTER_ASSERT(reporter, view);
imageProxy = view.proxy();
}
if (!imageProxy->instantiate(resourceProvider)) {
ERRORF(reporter, "Failed to instantiate Proxy");
return;
}
const Resource* imageResourcePtr = imageProxy->texture();
REPORTER_ASSERT(reporter, imageResourcePtr);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 4);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
REPORTER_ASSERT(reporter, imageResourcePtr->budgeted() == skgpu::Budgeted::kNo);
std::unique_ptr<Recording> recording = recorder->snap();
if (!recording) {
ERRORF(reporter, "Failed to make recording");
return;
}
InsertRecordingInfo insertInfo;
insertInfo.fRecording = recording.get();
context->insertRecording(insertInfo);
testContext->syncedSubmit(context);
recording.reset();
imageGpu.reset();
resourceCache->forceProcessReturnedResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 4);
if (!context->priv().caps()->bufferMapsAreAsync()) {
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 4);
}
REPORTER_ASSERT(reporter, imageResourcePtr->budgeted() == skgpu::Budgeted::kYes);
sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), info);
if (!surface) {
ERRORF(reporter, "Failed to make surface");
return;
}
TextureProxy* surfaceProxy = top_device_graphite_target_proxy(surface->getCanvas());
if (!surfaceProxy) {
ERRORF(reporter, "Failed to get surface proxy");
return;
}
if (!surfaceProxy->instantiate(resourceProvider)) {
ERRORF(reporter, "Failed to instantiate surface proxy");
return;
}
const Resource* surfaceResourcePtr = surfaceProxy->texture();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 5);
if (!context->priv().caps()->bufferMapsAreAsync()) {
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 4);
}
REPORTER_ASSERT(reporter, surfaceResourcePtr->budgeted() == skgpu::Budgeted::kNo);
recording = recorder->snap();
insertInfo.fRecording = recording.get();
context->insertRecording(insertInfo);
testContext->syncedSubmit(context);
recording.reset();
surface.reset();
resourceCache->forceProcessReturnedResources();
REPORTER_ASSERT(reporter, surfaceResourcePtr->budgeted() == skgpu::Budgeted::kYes);
}
namespace {
sk_sp<Resource> add_new_resource(skiatest::Reporter* reporter,
const SharedContext* sharedContext,
ResourceCache* resourceCache,
size_t gpuMemorySize,
skgpu::Budgeted budgeted = skgpu::Budgeted::kYes) {
auto resource = TestResource::Make(sharedContext,
Ownership::kOwned,
budgeted,
Shareable::kNo,
gpuMemorySize);
if (!resource) {
ERRORF(reporter, "Failed to make TestResource");
return nullptr;
}
resourceCache->insertResource(resource.get());
return resource;
}
Resource* add_new_purgeable_resource(skiatest::Reporter* reporter,
const SharedContext* sharedContext,
ResourceCache* resourceCache,
size_t gpuMemorySize) {
auto resource = add_new_resource(reporter, sharedContext, resourceCache, gpuMemorySize);
if (!resource) {
return nullptr;
}
Resource* ptr = resource.get();
resource.reset();
resourceCache->forceProcessReturnedResources();
return ptr;
}
}
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphitePurgeAsNeededResourcesTest, reporter, context,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
resourceCache->setMaxBudget(10);
auto resourceSize10 = add_new_resource(reporter,
sharedContext,
resourceCache,
10);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 10);
auto resourceSize1 = add_new_resource(reporter,
sharedContext,
resourceCache,
1);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 11);
resourceSize1.reset();
auto resourceSize2 = add_new_resource(reporter,
sharedContext,
resourceCache,
2);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 12);
resourceSize10.reset();
resourceSize2.reset();
resourceCache->forceProcessReturnedResources();
resourceCache->setMaxBudget(0);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 0);
resourceCache->setMaxBudget(10);
auto resourceSize1Ptr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
2);
auto resourceSize3Ptr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
3);
auto resourceSize4Ptr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
4);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 4);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourceSize1Ptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 10);
add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
2);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 3);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourceSize3Ptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 9);
resourceSize10 = add_new_resource(reporter,
sharedContext,
resourceCache,
10);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 10);
resourceSize4Ptr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
4);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourceSize4Ptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 14);
resourceCache->setMaxBudget(0);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 10);
resourceSize10.reset();
resourceCache->forceProcessReturnedResources();
resourceCache->forcePurgeAsNeeded();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 0);
}
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteZeroSizedResourcesTest, reporter, context,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
Resource* resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourcePtr);
resourceCache->setMaxBudget(0);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 0);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == nullptr);
resourceCache->setMaxBudget(100);
resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
0);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourcePtr);
resourceCache->setMaxBudget(0);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 1);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == resourcePtr);
resourceCache->setMaxBudget(100);
Resource* sizedResourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == sizedResourcePtr);
resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
0);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 3);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 3);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue() == sizedResourcePtr);
resourceCache->setMaxBudget(0);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 2);
REPORTER_ASSERT(reporter, resourceCache->topOfPurgeableQueue()->gpuMemorySize() == 0);
resourceCache->purgeResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
REPORTER_ASSERT(reporter, resourceCache->numFindableResources() == 0);
}
skgpu::StdSteadyClock::time_point force_newer_timepoint(
const skgpu::StdSteadyClock::time_point& prevTime) {
auto time = skgpu::StdSteadyClock::now();
while (time <= prevTime) {
time = skgpu::StdSteadyClock::now();
}
return time;
}
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphitePurgeNotUsedSinceResourcesTest, reporter, context,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
auto beforeTime = skgpu::StdSteadyClock::now();
auto resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
auto afterTime = force_newer_timepoint(skgpu::StdSteadyClock::now());
resourceCache->purgeResourcesNotUsedSince(beforeTime);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
resourceCache->purgeResourcesNotUsedSince(afterTime);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
Resource* resourcePtr1 = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
auto betweenTime = force_newer_timepoint(skgpu::StdSteadyClock::now());
Resource* resourcePtr2 = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
afterTime = force_newer_timepoint(skgpu::StdSteadyClock::now());
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr1));
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr2));
resourceCache->purgeResourcesNotUsedSince(betweenTime);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr2));
resourceCache->purgeResourcesNotUsedSince(afterTime);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
auto resource = add_new_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resource) {
return;
}
resourcePtr = resource.get();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
afterTime = force_newer_timepoint(skgpu::StdSteadyClock::now());
resourceCache->purgeResourcesNotUsedSince(afterTime);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, !resourceCache->testingInPurgeableQueue(resourcePtr));
resource.reset();
resourceCache->purgeResourcesNotUsedSince(skgpu::StdSteadyClock::now());
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr));
resourceCache->purgeResourcesNotUsedSince(force_newer_timepoint(skgpu::StdSteadyClock::now()));
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
}
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphitePurgeNotUsedOverBudgetTest, reporter, context,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
resourceCache->setMaxBudget(10);
auto resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr) {
return;
}
auto resource1 = add_new_resource(reporter,
sharedContext,
resourceCache,
15,
skgpu::Budgeted::kNo);
auto resource2 = add_new_resource(reporter,
sharedContext,
resourceCache,
16,
skgpu::Budgeted::kNo);
auto resource3 = add_new_resource(reporter,
sharedContext,
resourceCache,
3,
skgpu::Budgeted::kNo);
auto resource1Ptr = resource1.get();
auto resource2Ptr = resource2.get();
auto resource3Ptr = resource3.get();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 4);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 1);
auto timeBeforeReturningToCache = skgpu::StdSteadyClock::now();
resource1.reset();
resource2.reset();
resource3.reset();
resourceCache->forceProcessReturnedResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 4);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 35);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr));
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resource1Ptr));
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resource2Ptr));
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resource3Ptr));
resourceCache->purgeResourcesNotUsedSince(timeBeforeReturningToCache);
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, resourceCache->currentBudgetedBytes() == 3);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resource3Ptr));
}
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphitePurgeResourcesTest, reporter, context,
CtsEnforcement::kApiLevel_V) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
ResourceCache* resourceCache = resourceProvider->resourceCache();
const SharedContext* sharedContext = resourceProvider->sharedContext();
resourceCache->setMaxBudget(10);
auto resourcePtr = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
resourceCache->purgeResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
Resource* resourcePtr1 = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
Resource* resourcePtr2 = add_new_purgeable_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resourcePtr1 || !resourcePtr2) {
return;
}
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 2);
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr1));
REPORTER_ASSERT(reporter, resourceCache->testingInPurgeableQueue(resourcePtr2));
resourceCache->purgeResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
auto resource = add_new_resource(reporter,
sharedContext,
resourceCache,
1);
if (!resource) {
return;
}
resourcePtr = resource.get();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
resourceCache->purgeResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 1);
REPORTER_ASSERT(reporter, !resourceCache->testingInPurgeableQueue(resourcePtr));
resource.reset();
resourceCache->purgeResources();
REPORTER_ASSERT(reporter, resourceCache->getResourceCount() == 0);
}
}