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

#include "SkTypes.h"

#include <thread>
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrContextFactory.h"
#include "GrGpu.h"
#include "GrGpuResourceCacheAccess.h"
#include "GrGpuResourcePriv.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetPriv.h"
#include "GrResourceCache.h"
#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTexture.h"

#include "SkCanvas.h"
#include "SkGr.h"
#include "SkMessageBus.h"
#include "SkMipMap.h"
#include "SkSurface.h"
#include "Test.h"

static const int gWidth = 640;
static const int gHeight = 480;

////////////////////////////////////////////////////////////////////////////////
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    GrSurfaceDesc desc;
    desc.fConfig = kRGBA_8888_GrPixelConfig;
    desc.fFlags = kRenderTarget_GrSurfaceFlag;
    desc.fWidth = gWidth;
    desc.fHeight = gHeight;
    SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
    auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
    SkCanvas* canvas = surface->getCanvas();

    const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);

    SkBitmap src;
    src.allocN32Pixels(size.width(), size.height());
    src.eraseColor(SK_ColorBLACK);
    size_t srcSize = src.computeByteSize();

    size_t initialCacheSize;
    context->getResourceCacheUsage(nullptr, &initialCacheSize);

    int oldMaxNum;
    size_t oldMaxBytes;
    context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);

    // Set the cache limits so we can fit 10 "src" images and the
    // max number of textures doesn't matter
    size_t maxCacheSize = initialCacheSize + 10*srcSize;
    context->setResourceCacheLimits(1000, maxCacheSize);

    SkBitmap readback;
    readback.allocN32Pixels(size.width(), size.height());

    for (int i = 0; i < 100; ++i) {
        canvas->drawBitmap(src, 0, 0);
        surface->readPixels(readback, 0, 0);

        // "modify" the src texture
        src.notifyPixelsChanged();

        size_t curCacheSize;
        context->getResourceCacheUsage(nullptr, &curCacheSize);

        // we should never go over the size limit
        REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
    }

    context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
}

static bool is_rendering_and_not_angle_es3(sk_gpu_test::GrContextFactory::ContextType type) {
    if (type == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES3_ContextType ||
        type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType) {
        return false;
    }
    return sk_gpu_test::GrContextFactory::IsRenderingContext(type);
}

static GrStencilAttachment* get_SB(GrRenderTarget* rt) {
    return rt->renderTargetPriv().getStencilAttachment();
}

static sk_sp<GrRenderTarget> create_RT_with_SB(GrResourceProvider* provider,
                                               int size, int sampleCount, SkBudgeted budgeted) {
    GrSurfaceDesc desc;
    desc.fFlags = kRenderTarget_GrSurfaceFlag;
    desc.fWidth = size;
    desc.fHeight = size;
    desc.fConfig = kRGBA_8888_GrPixelConfig;
    desc.fSampleCnt = sampleCount;

    sk_sp<GrTexture> tex(provider->createTexture(desc, budgeted));
    if (!tex || !tex->asRenderTarget()) {
        return nullptr;
    }

    if (!provider->attachStencilAttachment(tex->asRenderTarget())) {
        return nullptr;
    }
    SkASSERT(get_SB(tex->asRenderTarget()));

    return sk_ref_sp(tex->asRenderTarget());
}

// This currently fails on ES3 ANGLE contexts
DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter,
                         ctxInfo, nullptr) {
    GrContext* context = ctxInfo.grContext();
    if (context->contextPriv().caps()->avoidStencilBuffers()) {
        return;
    }

    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();

    sk_sp<GrRenderTarget> smallRT0 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kYes);
    REPORTER_ASSERT(reporter, smallRT0);

    {
       // Two budgeted RTs with the same desc should share a stencil buffer.
       sk_sp<GrRenderTarget> smallRT1 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kYes);
       REPORTER_ASSERT(reporter, smallRT1);

       REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT1.get()));
    }

    {
        // An unbudgeted RT with the same desc should also share.
        sk_sp<GrRenderTarget> smallRT2 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kNo);
        REPORTER_ASSERT(reporter, smallRT2);

        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT2.get()));
    }

    {
        // An RT with a much larger size should not share.
        sk_sp<GrRenderTarget> bigRT = create_RT_with_SB(resourceProvider, 400, 1, SkBudgeted::kNo);
        REPORTER_ASSERT(reporter, bigRT);

        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(bigRT.get()));
    }

    int smallSampleCount =
            context->contextPriv().caps()->getRenderTargetSampleCount(2, kRGBA_8888_GrPixelConfig);
    if (smallSampleCount > 1) {
        // An RT with a different sample count should not share.
        sk_sp<GrRenderTarget> smallMSAART0 = create_RT_with_SB(resourceProvider, 4,
                                                               smallSampleCount, SkBudgeted::kNo);
#ifdef SK_BUILD_FOR_ANDROID
        if (!smallMSAART0) {
            // The nexus player seems to fail to create MSAA textures.
            return;
        }
#else
        REPORTER_ASSERT(reporter, smallMSAART0);
#endif

        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(smallMSAART0.get()));

        {
            // A second MSAA RT should share with the first MSAA RT.
            sk_sp<GrRenderTarget> smallMSAART1 = create_RT_with_SB(resourceProvider, 4,
                                                                   smallSampleCount,
                                                                   SkBudgeted::kNo);
            REPORTER_ASSERT(reporter, smallMSAART1);

            REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) == get_SB(smallMSAART1.get()));
        }

        // But one with a larger sample count should not. (Also check that the two requests didn't
        // rounded up to the same actual sample count or else they could share.).
        int bigSampleCount = context->contextPriv().caps()->getRenderTargetSampleCount(
                5, kRGBA_8888_GrPixelConfig);
        if (bigSampleCount > 0 && bigSampleCount != smallSampleCount) {
            sk_sp<GrRenderTarget> smallMSAART2 = create_RT_with_SB(resourceProvider, 4,
                                                                   bigSampleCount,
                                                                   SkBudgeted::kNo);
            REPORTER_ASSERT(reporter, smallMSAART2);

            REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) != get_SB(smallMSAART2.get()));
        }
    }
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
    GrGpu* gpu = context->contextPriv().getGpu();
    // this test is only valid for GL
    if (!gpu || !gpu->glContextForTesting()) {
        return;
    }

    GrBackendTexture backendTextures[2];
    static const int kW = 100;
    static const int kH = 100;

    backendTextures[0] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH,
                                                              kRGBA_8888_GrPixelConfig,
                                                              false, GrMipMapped::kNo);
    backendTextures[1] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH,
                                                              kRGBA_8888_GrPixelConfig,
                                                              false, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTextures[0].isValid());
    REPORTER_ASSERT(reporter, backendTextures[1].isValid());
    if (!backendTextures[0].isValid() || !backendTextures[1].isValid()) {
        return;
    }

    context->resetContext();

    sk_sp<GrTexture> borrowed(resourceProvider->wrapBackendTexture(
            backendTextures[0], kBorrow_GrWrapOwnership));

    sk_sp<GrTexture> adopted(resourceProvider->wrapBackendTexture(
            backendTextures[1], kAdopt_GrWrapOwnership));

    REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr);
    if (!borrowed || !adopted) {
        return;
    }

    borrowed.reset(nullptr);
    adopted.reset(nullptr);

    context->flush();

    bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[0]);
    bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[1]);

    REPORTER_ASSERT(reporter, borrowedIsAlive);
    REPORTER_ASSERT(reporter, !adoptedIsAlive);

    if (borrowedIsAlive) {
        gpu->deleteTestingOnlyBackendTexture(backendTextures[0]);
    }
    if (adoptedIsAlive) {
        gpu->deleteTestingOnlyBackendTexture(backendTextures[1]);
    }

    context->resetContext();
}

class TestResource : public GrGpuResource {
    enum ScratchConstructor { kScratchConstructor };
public:
    static const size_t kDefaultSize = 100;

    /** Property that distinctly categorizes the resource.
     * For example, textures have width, height, ... */
    enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };

    TestResource(GrGpu* gpu, SkBudgeted budgeted = SkBudgeted::kYes, size_t size = kDefaultSize)
        : INHERITED(gpu)
        , fToDelete(nullptr)
        , fSize(size)
        , fProperty(kA_SimulatedProperty)
        , fIsScratch(false) {
        ++fNumAlive;
        this->registerWithCache(budgeted);
    }

    static TestResource* CreateScratch(GrGpu* gpu, SkBudgeted budgeted,
                                       SimulatedProperty property, size_t size = kDefaultSize) {
        return new TestResource(gpu, budgeted, property, kScratchConstructor, size);
    }
    static TestResource* CreateWrapped(GrGpu* gpu, size_t size = kDefaultSize) {
        return new TestResource(gpu, size);
    }

    ~TestResource() override {
        --fNumAlive;
        SkSafeUnref(fToDelete);
    }

    static int NumAlive() { return fNumAlive; }

    void setUnrefWhenDestroyed(TestResource* resource) {
        SkRefCnt_SafeAssign(fToDelete, resource);
    }

    static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
        static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
        GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
        for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
            builder[i] = static_cast<uint32_t>(i + property);
        }
    }

    static size_t ExpectedScratchKeySize() {
        return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
    }
private:
    static const int kScratchKeyFieldCnt = 6;

    TestResource(GrGpu* gpu, SkBudgeted budgeted, SimulatedProperty property, ScratchConstructor,
                 size_t size = kDefaultSize)
        : INHERITED(gpu)
        , fToDelete(nullptr)
        , fSize(size)
        , fProperty(property)
        , fIsScratch(true) {
        ++fNumAlive;
        this->registerWithCache(budgeted);
    }

    // Constructor for simulating resources that wrap backend objects.
    TestResource(GrGpu* gpu, size_t size)
        : INHERITED(gpu)
        , fToDelete(nullptr)
        , fSize(size)
        , fProperty(kA_SimulatedProperty)
        , fIsScratch(false) {
        ++fNumAlive;
        this->registerWithCacheWrapped();
    }

    void computeScratchKey(GrScratchKey* key) const override {
        if (fIsScratch) {
            ComputeScratchKey(fProperty, key);
        }
    }

    size_t onGpuMemorySize() const override { return fSize; }
    const char* getResourceType() const override { return "Test"; }

    TestResource* fToDelete;
    size_t fSize;
    static int fNumAlive;
    SimulatedProperty fProperty;
    bool fIsScratch;
    typedef GrGpuResource INHERITED;
};
int TestResource::fNumAlive = 0;

class Mock {
public:
    Mock(int maxCnt, size_t maxBytes) {
        fContext = GrContext::MakeMock(nullptr);
        SkASSERT(fContext);
        fContext->setResourceCacheLimits(maxCnt, maxBytes);
        GrResourceCache* cache = fContext->contextPriv().getResourceCache();
        cache->purgeAllUnlocked();
        SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
    }

    GrResourceCache* cache() { return fContext->contextPriv().getResourceCache(); }

    GrContext* context() { return fContext.get(); }

private:
    sk_sp<GrContext> fContext;
};

static void test_no_key(skiatest::Reporter* reporter) {
    Mock mock(10, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // Create a bunch of resources with no keys
    TestResource* a = new TestResource(gpu, SkBudgeted::kYes, 11);
    TestResource* b = new TestResource(gpu, SkBudgeted::kYes, 12);
    TestResource* c = new TestResource(gpu, SkBudgeted::kYes, 13 );
    TestResource* d = new TestResource(gpu, SkBudgeted::kYes, 14 );

    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
                              d->gpuMemorySize() == cache->getResourceBytes());

    // Should be safe to purge without deleting the resources since we still have refs.
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());

    // Since the resources have neither unique nor scratch keys, delete immediately upon unref.

    a->unref();
    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
                              cache->getResourceBytes());

    c->unref();
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
                              cache->getResourceBytes());

    d->unref();
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());

    b->unref();
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
}

// Each integer passed as a template param creates a new domain.
template <int>
static void make_unique_key(GrUniqueKey* key, int data, const char* tag = nullptr) {
    static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
    GrUniqueKey::Builder builder(key, d, 1, tag);
    builder[0] = data;
}

static void test_purge_unlocked(skiatest::Reporter* reporter) {
    Mock mock(10, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // Create two resource w/ a unique key and two w/o but all of which have scratch keys.
    TestResource* a = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kA_SimulatedProperty, 11);

    GrUniqueKey uniqueKey;
    make_unique_key<0>(&uniqueKey, 0);

    TestResource* b = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kA_SimulatedProperty, 12);
    b->resourcePriv().setUniqueKey(uniqueKey);

    TestResource* c = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kA_SimulatedProperty, 13);

    GrUniqueKey uniqueKey2;
    make_unique_key<0>(&uniqueKey2, 1);

    TestResource* d = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kA_SimulatedProperty, 14);
    d->resourcePriv().setUniqueKey(uniqueKey2);


    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
                              d->gpuMemorySize() == cache->getResourceBytes());

    // Should be safe to purge without deleting the resources since we still have refs.
    cache->purgeUnlockedResources(false);
    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());

    // Unref them all. Since they all have keys they should remain in the cache.

    a->unref();
    b->unref();
    c->unref();
    d->unref();
    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
                              d->gpuMemorySize() == cache->getResourceBytes());

    // Purge only the two scratch resources
    cache->purgeUnlockedResources(true);

    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
                              cache->getResourceBytes());

    // Purge the uniquely keyed resources
    cache->purgeUnlockedResources(false);

    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
}

static void test_budgeting(skiatest::Reporter* reporter) {
    Mock mock(10, 300);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    GrUniqueKey uniqueKey;
    make_unique_key<0>(&uniqueKey, 0);

    // Create a scratch, a unique, and a wrapped resource
    TestResource* scratch =
            TestResource::CreateScratch(gpu, SkBudgeted::kYes, TestResource::kB_SimulatedProperty,
                                        10);
    TestResource* unique = new TestResource(gpu, SkBudgeted::kYes, 11);
    unique->resourcePriv().setUniqueKey(uniqueKey);
    TestResource* wrapped = TestResource::CreateWrapped(gpu, 12);
    TestResource* unbudgeted = new TestResource(gpu, SkBudgeted::kNo, 13);

    // Make sure we can add a unique key to the wrapped resource
    GrUniqueKey uniqueKey2;
    make_unique_key<0>(&uniqueKey2, 1);
    wrapped->resourcePriv().setUniqueKey(uniqueKey2);
    GrGpuResource* wrappedViaKey = cache->findAndRefUniqueResource(uniqueKey2);
    REPORTER_ASSERT(reporter, wrappedViaKey != nullptr);

    // Remove the extra ref we just added.
    wrappedViaKey->unref();

    // Make sure sizes are as we expect
    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
                              cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
                              cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    // Our refs mean that the resources are non purgeable.
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
                              cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
                              cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    // Unreffing the wrapped resource should free it right away.
    wrapped->unref();
    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    // Now try freeing the budgeted resources first
    wrapped = TestResource::CreateWrapped(gpu);
    unique->unref();
    REPORTER_ASSERT(reporter, 11 == cache->getPurgeableBytes());
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    scratch->unref();
    REPORTER_ASSERT(reporter, 10 == cache->getPurgeableBytes());
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
                              cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    wrapped->unref();
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    unbudgeted->unref();
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
}

static void test_unbudgeted(skiatest::Reporter* reporter) {
    Mock mock(10, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    GrUniqueKey uniqueKey;
    make_unique_key<0>(&uniqueKey, 0);

    TestResource* scratch;
    TestResource* unique;
    TestResource* wrapped;
    TestResource* unbudgeted;

    // A large uncached or wrapped resource shouldn't evict anything.
    scratch = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                          TestResource::kB_SimulatedProperty, 10);

    scratch->unref();
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 10 == cache->getPurgeableBytes());

    unique = new TestResource(gpu, SkBudgeted::kYes, 11);
    unique->resourcePriv().setUniqueKey(uniqueKey);
    unique->unref();
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());

    size_t large = 2 * cache->getResourceBytes();
    unbudgeted = new TestResource(gpu, SkBudgeted::kNo, large);
    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());

    unbudgeted->unref();
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());

    wrapped = TestResource::CreateWrapped(gpu, large);
    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());

    wrapped->unref();
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());

    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
}

// This method can't be static because it needs to friended in GrGpuResource::CacheAccess.
void test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
    Mock mock(10, 300);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    TestResource* resource =
        TestResource::CreateScratch(gpu, SkBudgeted::kNo, TestResource::kA_SimulatedProperty);
    GrScratchKey key;
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);

    size_t size = resource->gpuMemorySize();
    for (int i = 0; i < 2; ++i) {
        // Since this resource is unbudgeted, it should not be reachable as scratch.
        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
        REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
        REPORTER_ASSERT(reporter, SkBudgeted::kNo == resource->resourcePriv().isBudgeted());
        REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0));
        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

        // Once it is unrefed, it should become available as scratch.
        resource->unref();
        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
        REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
        REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
        REPORTER_ASSERT(reporter, size == cache->getPurgeableBytes());
        resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0));
        REPORTER_ASSERT(reporter, resource);
        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
        REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
        REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted());

        if (0 == i) {
            // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
            // the above tests again.
            resource->resourcePriv().makeUnbudgeted();
        } else {
            // After the second time around, try removing the scratch key
            resource->resourcePriv().removeScratchKey();
            REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
            REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
            REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
            REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
            REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
            REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid());
            REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
            REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted());

            // now when it is unrefed it should die since it has no key.
            resource->unref();
            REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
            REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
            REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
        }
    }
}

static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
    Mock mock(5, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // Create two resources that have the same scratch key.
    TestResource* a = TestResource::CreateScratch(gpu,
                                                  SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty, 11);
    TestResource* b = TestResource::CreateScratch(gpu,
                                                  SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty, 12);
    GrScratchKey scratchKey1;
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
    // Check for negative case consistency. (leaks upon test failure.)
    REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(scratchKey1, TestResource::kDefaultSize, 0));

    GrScratchKey scratchKey;
    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);

    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
                              cache->getResourceBytes());

    // Our refs mean that the resources are non purgeable.
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());

    // Unref but don't purge
    a->unref();
    b->unref();
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)

    // Purge again. This time resources should be purgeable.
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
}

static void test_remove_scratch_key(skiatest::Reporter* reporter) {
    Mock mock(5, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // Create two resources that have the same scratch key.
    TestResource* a = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty);
    TestResource* b = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty);
    a->unref();
    b->unref();

    GrScratchKey scratchKey;
    // Ensure that scratch key lookup is correct for negative case.
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
    // (following leaks upon test failure).
    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr);

    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());

    // Find the first resource and remove its scratch key
    GrGpuResource* find;
    find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
    find->resourcePriv().removeScratchKey();
    // It's still alive, but not cached by scratch key anymore
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());

    // The cache should immediately delete it when it's unrefed since it isn't accessible.
    find->unref();
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());

    // Repeat for the second resource.
    find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
    find->resourcePriv().removeScratchKey();
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());

    // Should be able to call this multiple times with no problem.
    find->resourcePriv().removeScratchKey();
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());

    find->unref();
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
}

static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
    Mock mock(5, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // Create two resources that have the same scratch key.
    TestResource* a = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty);
    TestResource* b = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kB_SimulatedProperty);
    a->unref();
    b->unref();

    GrScratchKey scratchKey;
    // Ensure that scratch key comparison and assignment is consistent.
    GrScratchKey scratchKey1;
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
    GrScratchKey scratchKey2;
    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2);
    REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
    scratchKey = scratchKey1;
    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
    REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
    REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
    REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
    scratchKey = scratchKey2;
    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
    REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
    REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
    REPORTER_ASSERT(reporter, scratchKey == scratchKey2);

    // Ensure that scratch key lookup is correct for negative case.
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
    // (following leaks upon test failure).
    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr);

    // Find the first resource with a scratch key and a copy of a scratch key.
    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
    GrGpuResource* find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
    REPORTER_ASSERT(reporter, find != nullptr);
    find->unref();

    scratchKey2 = scratchKey;
    find = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0);
    REPORTER_ASSERT(reporter, find != nullptr);
    REPORTER_ASSERT(reporter, find == a || find == b);

    GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0);
    REPORTER_ASSERT(reporter, find2 != nullptr);
    REPORTER_ASSERT(reporter, find2 == a || find2 == b);
    REPORTER_ASSERT(reporter, find2 != find);
    find2->unref();
    find->unref();
}

static void test_duplicate_unique_key(skiatest::Reporter* reporter) {
    Mock mock(5, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    GrUniqueKey key;
    make_unique_key<0>(&key, 0);

    // Create two resources that we will attempt to register with the same unique key.
    TestResource* a = new TestResource(gpu, SkBudgeted::kYes, 11);

    // Set key on resource a.
    a->resourcePriv().setUniqueKey(key);
    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
    a->unref();

    // Make sure that redundantly setting a's key works.
    a->resourcePriv().setUniqueKey(key);
    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
    a->unref();
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // Create resource b and set the same key. It should replace a's unique key cache entry.
    TestResource* b = new TestResource(gpu, SkBudgeted::kYes, 12);
    b->resourcePriv().setUniqueKey(key);
    REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key));
    b->unref();

    // Still have two resources because a is still reffed.
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());

    a->unref();
    // Now a should be gone.
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // Now replace b with c, but make sure c can start with one unique key and change it to b's key.
    // Also make b be unreffed when replacement occurs.
    b->unref();
    TestResource* c = new TestResource(gpu, SkBudgeted::kYes, 13);
    GrUniqueKey differentKey;
    make_unique_key<0>(&differentKey, 1);
    c->resourcePriv().setUniqueKey(differentKey);
    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    // c replaces b and b should be immediately purged.
    c->resourcePriv().setUniqueKey(key);
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // c shouldn't be purged because it is ref'ed.
    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // Drop the ref on c, it should be kept alive because it has a unique key.
    c->unref();
    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // Verify that we can find c, then remove its unique key. It should get purged immediately.
    REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key));
    c->resourcePriv().removeUniqueKey();
    c->unref();
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());

    {
        GrUniqueKey key2;
        make_unique_key<0>(&key2, 0);
        sk_sp<TestResource> d(new TestResource(gpu));
        int foo = 4132;
        key2.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo)));
        d->resourcePriv().setUniqueKey(key2);
    }

    GrUniqueKey key3;
    make_unique_key<0>(&key3, 0);
    sk_sp<GrGpuResource> d2(cache->findAndRefUniqueResource(key3));
    REPORTER_ASSERT(reporter, *(int*) d2->getUniqueKey().getCustomData()->data() == 4132);
}

static void test_purge_invalidated(skiatest::Reporter* reporter) {
    Mock mock(5, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    GrUniqueKey key1, key2, key3;
    make_unique_key<0>(&key1, 1);
    make_unique_key<0>(&key2, 2);
    make_unique_key<0>(&key3, 3);

    // Add three resources to the cache. Only c is usable as scratch.
    TestResource* a = new TestResource(gpu);
    TestResource* b = new TestResource(gpu);
    TestResource* c = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                  TestResource::kA_SimulatedProperty);
    a->resourcePriv().setUniqueKey(key1);
    b->resourcePriv().setUniqueKey(key2);
    c->resourcePriv().setUniqueKey(key3);
    a->unref();
    // hold b until *after* the message is sent.
    c->unref();

    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());

    typedef GrUniqueKeyInvalidatedMessage Msg;
    typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus;

    // Invalidate two of the three, they should be purged and no longer accessible via their keys.
    Bus::Post(Msg(key1));
    Bus::Post(Msg(key2));
    cache->purgeAsNeeded();
    // a should be deleted now, but we still have a ref on b.
    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));

    // Invalidate the third.
    Bus::Post(Msg(key3));
    cache->purgeAsNeeded();
    // we still have a ref on b, c should be recycled as scratch.
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3));

    // make b purgeable. It should be immediately deleted since it has no key.
    b->unref();
    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());

    // Make sure we actually get to c via it's scratch key, before we say goodbye.
    GrScratchKey scratchKey;
    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
    GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
    REPORTER_ASSERT(reporter, scratch == c);
    SkSafeUnref(scratch);

    // Get rid of c.
    cache->purgeAllUnlocked();
    scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
    REPORTER_ASSERT(reporter, !scratch);
    SkSafeUnref(scratch);
}

static void test_cache_chained_purge(skiatest::Reporter* reporter) {
    Mock mock(3, 30000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    GrUniqueKey key1, key2;
    make_unique_key<0>(&key1, 1);
    make_unique_key<0>(&key2, 2);

    TestResource* a = new TestResource(gpu);
    TestResource* b = new TestResource(gpu);
    a->resourcePriv().setUniqueKey(key1);
    b->resourcePriv().setUniqueKey(key2);

    // Make a cycle
    a->setUnrefWhenDestroyed(b);
    b->setUnrefWhenDestroyed(a);

    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());

    a->unref();
    b->unref();

    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());

    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());

    // Break the cycle
    a->setUnrefWhenDestroyed(nullptr);
    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());

    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
}

static void test_timestamp_wrap(skiatest::Reporter* reporter) {
    static const int kCount = 50;
    static const int kBudgetCnt = kCount / 2;
    static const int kLockedFreq = 8;
    static const int kBudgetSize = 0x80000000;

    SkRandom random;

    // Run the test 2*kCount times;
    for (int i = 0; i < 2 * kCount; ++i ) {
        Mock mock(kBudgetCnt, kBudgetSize);
        GrContext* context = mock.context();
        GrResourceCache* cache = mock.cache();
        GrGpu* gpu = context->contextPriv().getGpu();

        // Pick a random number of resources to add before the timestamp will wrap.
        cache->changeTimestamp(UINT32_MAX - random.nextULessThan(kCount + 1));

        static const int kNumToPurge = kCount - kBudgetCnt;

        SkTDArray<int> shouldPurgeIdxs;
        int purgeableCnt = 0;
        SkTDArray<GrGpuResource*> resourcesToUnref;

        // Add kCount resources, holding onto resources at random so we have a mix of purgeable and
        // unpurgeable resources.
        for (int j = 0; j < kCount; ++j) {
            GrUniqueKey key;
            make_unique_key<0>(&key, j);

            TestResource* r = new TestResource(gpu);
            r->resourcePriv().setUniqueKey(key);
            if (random.nextU() % kLockedFreq) {
                // Make this is purgeable.
                r->unref();
                ++purgeableCnt;
                if (purgeableCnt <= kNumToPurge) {
                    *shouldPurgeIdxs.append() = j;
                }
            } else {
                *resourcesToUnref.append() = r;
            }
        }

        // Verify that the correct resources were purged.
        int currShouldPurgeIdx = 0;
        for (int j = 0; j < kCount; ++j) {
            GrUniqueKey key;
            make_unique_key<0>(&key, j);
            GrGpuResource* res = cache->findAndRefUniqueResource(key);
            if (currShouldPurgeIdx < shouldPurgeIdxs.count() &&
                shouldPurgeIdxs[currShouldPurgeIdx] == j) {
                ++currShouldPurgeIdx;
                REPORTER_ASSERT(reporter, nullptr == res);
            } else {
                REPORTER_ASSERT(reporter, nullptr != res);
            }
            SkSafeUnref(res);
        }

        for (int j = 0; j < resourcesToUnref.count(); ++j) {
            resourcesToUnref[j]->unref();
        }
    }
}

static void test_flush(skiatest::Reporter* reporter) {
    Mock mock(1000000, 1000000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // The current cache impl will round the max flush count to the next power of 2. So we choose a
    // power of two here to keep things simpler.
    static const int kFlushCount = 16;
    cache->setLimits(1000000, 1000000, kFlushCount);

    {
        // Insert a resource and send a flush notification kFlushCount times.
        for (int i = 0; i < kFlushCount; ++i) {
            TestResource* r = new TestResource(gpu);
            GrUniqueKey k;
            make_unique_key<1>(&k, i);
            r->resourcePriv().setUniqueKey(k);
            r->unref();
            cache->notifyFlushOccurred(GrResourceCache::kExternal);
        }

        // Send flush notifications to the cache. Each flush should purge the oldest resource.
        for (int i = 0; i < kFlushCount; ++i) {
            cache->notifyFlushOccurred(GrResourceCache::kExternal);
            REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount());
            for (int j = 0; j < i; ++j) {
                GrUniqueKey k;
                make_unique_key<1>(&k, j);
                GrGpuResource* r = cache->findAndRefUniqueResource(k);
                REPORTER_ASSERT(reporter, !SkToBool(r));
                SkSafeUnref(r);
            }
        }

        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
        cache->purgeAllUnlocked();
    }

    // Do a similar test but where we leave refs on some resources to prevent them from being
    // purged.
    {
        GrGpuResource* refedResources[kFlushCount >> 1];
        for (int i = 0; i < kFlushCount; ++i) {
            TestResource* r = new TestResource(gpu);
            GrUniqueKey k;
            make_unique_key<1>(&k, i);
            r->resourcePriv().setUniqueKey(k);
            // Leave a ref on every other resource, beginning with the first.
            if (SkToBool(i & 0x1)) {
                refedResources[i/2] = r;
            } else {
                r->unref();
            }
            cache->notifyFlushOccurred(GrResourceCache::kExternal);
        }

        for (int i = 0; i < kFlushCount; ++i) {
            // Should get a resource purged every other flush.
            cache->notifyFlushOccurred(GrResourceCache::kExternal);
            REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount());
        }

        // Unref all the resources that we kept refs on in the first loop.
        for (int i = 0; i < kFlushCount >> 1; ++i) {
            refedResources[i]->unref();
        }

        // After kFlushCount + 1 flushes they all will have sat in the purgeable queue for
        // kFlushCount full flushes.
        for (int i = 0; i < kFlushCount + 1; ++i) {
            REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount());
            cache->notifyFlushOccurred(GrResourceCache::kExternal);
        }
        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());

        cache->purgeAllUnlocked();
    }

    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());

    // Verify that calling flush() on a GrContext with nothing to do will not trigger resource
    // eviction.
    context->flush();
    for (int i = 0; i < 10; ++i) {
        TestResource* r = new TestResource(gpu);
        GrUniqueKey k;
        make_unique_key<1>(&k, i);
        r->resourcePriv().setUniqueKey(k);
        r->unref();
    }
    REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
    for (int i = 0; i < 10 * kFlushCount; ++i) {
        context->flush();
    }
    REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
}

static void test_time_purge(skiatest::Reporter* reporter) {
    Mock mock(1000000, 1000000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    static constexpr int kCnts[] = {1, 10, 1024};
    auto nowish = []() {
        // We sleep so that we ensure we get a value that is greater than the last call to
        // GrStdSteadyClock::now().
        std::this_thread::sleep_for(GrStdSteadyClock::duration(5));
        auto result = GrStdSteadyClock::now();
        // Also sleep afterwards so we don't get this value again.
        std::this_thread::sleep_for(GrStdSteadyClock::duration(5));
        return result;
    };

    for (int cnt : kCnts) {
        std::unique_ptr<GrStdSteadyClock::time_point[]> timeStamps(
                new GrStdSteadyClock::time_point[cnt]);
        {
            // Insert resources and get time points between each addition.
            for (int i = 0; i < cnt; ++i) {
                TestResource* r = new TestResource(gpu);
                GrUniqueKey k;
                make_unique_key<1>(&k, i);
                r->resourcePriv().setUniqueKey(k);
                r->unref();
                timeStamps.get()[i] = nowish();
            }

            // Purge based on the time points between resource additions. Each purge should remove
            // the oldest resource.
            for (int i = 0; i < cnt; ++i) {
                cache->purgeResourcesNotUsedSince(timeStamps[i]);
                REPORTER_ASSERT(reporter, cnt - i - 1 == cache->getResourceCount());
                for (int j = 0; j < i; ++j) {
                    GrUniqueKey k;
                    make_unique_key<1>(&k, j);
                    GrGpuResource* r = cache->findAndRefUniqueResource(k);
                    REPORTER_ASSERT(reporter, !SkToBool(r));
                    SkSafeUnref(r);
                }
            }

            REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
            cache->purgeAllUnlocked();
        }

        // Do a similar test but where we leave refs on some resources to prevent them from being
        // purged.
        {
            std::unique_ptr<GrGpuResource* []> refedResources(new GrGpuResource*[cnt / 2]);
            for (int i = 0; i < cnt; ++i) {
                TestResource* r = new TestResource(gpu);
                GrUniqueKey k;
                make_unique_key<1>(&k, i);
                r->resourcePriv().setUniqueKey(k);
                // Leave a ref on every other resource, beginning with the first.
                if (SkToBool(i & 0x1)) {
                    refedResources.get()[i / 2] = r;
                } else {
                    r->unref();
                }
                timeStamps.get()[i] = nowish();
            }

            for (int i = 0; i < cnt; ++i) {
                // Should get a resource purged every other frame.
                cache->purgeResourcesNotUsedSince(timeStamps[i]);
                REPORTER_ASSERT(reporter, cnt - i / 2 - 1 == cache->getResourceCount());
            }

            // Unref all the resources that we kept refs on in the first loop.
            for (int i = 0; i < (cnt / 2); ++i) {
                refedResources.get()[i]->unref();
                cache->purgeResourcesNotUsedSince(nowish());
                REPORTER_ASSERT(reporter, cnt / 2 - i - 1 == cache->getResourceCount());
            }

            cache->purgeAllUnlocked();
        }

        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());

        // Verify that calling flush() on a GrContext with nothing to do will not trigger resource
        // eviction
        context->flush();
        for (int i = 0; i < 10; ++i) {
            TestResource* r = new TestResource(gpu);
            GrUniqueKey k;
            make_unique_key<1>(&k, i);
            r->resourcePriv().setUniqueKey(k);
            r->unref();
        }
        REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
        context->flush();
        REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
        cache->purgeResourcesNotUsedSince(nowish());
        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
    }
}

static void test_partial_purge(skiatest::Reporter* reporter) {
    Mock mock(6, 100);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    enum TestsCase {
        kOnlyScratch_TestCase = 0,
        kPartialScratch_TestCase = 1,
        kAllScratch_TestCase = 2,
        kPartial_TestCase = 3,
        kAll_TestCase = 4,
        kNone_TestCase = 5,
        kEndTests_TestCase = kNone_TestCase + 1
    };

    for (int testCase = 0; testCase < kEndTests_TestCase; testCase++) {

        GrUniqueKey key1, key2, key3;
        make_unique_key<0>(&key1, 1);
        make_unique_key<0>(&key2, 2);
        make_unique_key<0>(&key3, 3);

        // Add three unique resources to the cache.
        TestResource *unique1 = new TestResource(gpu, SkBudgeted::kYes, 10);
        TestResource *unique2 = new TestResource(gpu, SkBudgeted::kYes, 11);
        TestResource *unique3 = new TestResource(gpu, SkBudgeted::kYes, 12);

        unique1->resourcePriv().setUniqueKey(key1);
        unique2->resourcePriv().setUniqueKey(key2);
        unique3->resourcePriv().setUniqueKey(key3);

        // Add two scratch resources to the cache.
        TestResource *scratch1 = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                             TestResource::kA_SimulatedProperty,
                                                             13);
        TestResource *scratch2 = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
                                                             TestResource::kB_SimulatedProperty,
                                                             14);

        REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
        REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

        // Add resources to the purgeable queue
        unique1->unref();
        scratch1->unref();
        unique2->unref();
        scratch2->unref();
        unique3->unref();

        REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
        REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
        REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes());

        switch(testCase) {
            case kOnlyScratch_TestCase: {
                context->purgeUnlockedResources(14, true);
                REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 33 == cache->getBudgetedResourceBytes());
                break;
            }
            case kPartialScratch_TestCase: {
                context->purgeUnlockedResources(3, true);
                REPORTER_ASSERT(reporter, 4 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 47 == cache->getBudgetedResourceBytes());
                break;
            }
            case kAllScratch_TestCase: {
                context->purgeUnlockedResources(50, true);
                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
                break;
            }
            case kPartial_TestCase: {
                context->purgeUnlockedResources(13, false);
                REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 37 == cache->getBudgetedResourceBytes());
                break;
            }
            case kAll_TestCase: {
                context->purgeUnlockedResources(50, false);
                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
                break;
            }
            case kNone_TestCase: {
                context->purgeUnlockedResources(0, true);
                context->purgeUnlockedResources(0, false);
                REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
                REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
                REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes());
                break;
            }
        };

        // ensure all are purged before the next
        context->contextPriv().purgeAllUnlockedResources_ForTesting();
        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());

    }
}

static void test_large_resource_count(skiatest::Reporter* reporter) {
    // Set the cache size to double the resource count because we're going to create 2x that number
    // resources, using two different key domains. Add a little slop to the bytes because we resize
    // down to 1 byte after creating the resource.
    static const int kResourceCnt = 2000;

    Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    for (int i = 0; i < kResourceCnt; ++i) {
        GrUniqueKey key1, key2;
        make_unique_key<1>(&key1, i);
        make_unique_key<2>(&key2, i);

        TestResource* resource;

        resource = new TestResource(gpu, SkBudgeted::kYes, 1);
        resource->resourcePriv().setUniqueKey(key1);
        resource->unref();

        resource = new TestResource(gpu, SkBudgeted::kYes, 1);
        resource->resourcePriv().setUniqueKey(key2);
        resource->unref();
    }

    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
    REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 2 * kResourceCnt);
    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt);
    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt);
    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt);
    REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt);
    for (int i = 0; i < kResourceCnt; ++i) {
        GrUniqueKey key1, key2;
        make_unique_key<1>(&key1, i);
        make_unique_key<2>(&key2, i);

        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
    }

    cache->purgeAllUnlocked();
    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
    REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 0);
    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0);
    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0);
    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0);
    REPORTER_ASSERT(reporter, cache->getResourceCount() == 0);

    for (int i = 0; i < kResourceCnt; ++i) {
        GrUniqueKey key1, key2;
        make_unique_key<1>(&key1, i);
        make_unique_key<2>(&key2, i);

        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
    }
}

static void test_custom_data(skiatest::Reporter* reporter) {
    GrUniqueKey key1, key2;
    make_unique_key<0>(&key1, 1);
    make_unique_key<0>(&key2, 2);
    int foo = 4132;
    key1.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo)));
    REPORTER_ASSERT(reporter, *(int*) key1.getCustomData()->data() == 4132);
    REPORTER_ASSERT(reporter, key2.getCustomData() == nullptr);

    // Test that copying a key also takes a ref on its custom data.
    GrUniqueKey key3 = key1;
    REPORTER_ASSERT(reporter, *(int*) key3.getCustomData()->data() == 4132);
}

static void test_abandoned(skiatest::Reporter* reporter) {
    Mock mock(10, 300);
    GrContext* context = mock.context();
    GrGpu* gpu = context->contextPriv().getGpu();

    sk_sp<GrGpuResource> resource(new TestResource(gpu));
    context->abandonContext();

    REPORTER_ASSERT(reporter, resource->wasDestroyed());

    // Call all the public methods on resource in the abandoned state. They shouldn't crash.

    resource->uniqueID();
    resource->getUniqueKey();
    resource->wasDestroyed();
    resource->gpuMemorySize();
    resource->getContext();

    resource->abandon();
    resource->resourcePriv().getScratchKey();
    resource->resourcePriv().isBudgeted();
    resource->resourcePriv().makeBudgeted();
    resource->resourcePriv().makeUnbudgeted();
    resource->resourcePriv().removeScratchKey();
    GrUniqueKey key;
    make_unique_key<0>(&key, 1);
    resource->resourcePriv().setUniqueKey(key);
    resource->resourcePriv().removeUniqueKey();
}

static void test_tags(skiatest::Reporter* reporter) {
#ifdef SK_DEBUG
    // We will insert 1 resource with tag "tag1", 2 with "tag2", and so on, up through kLastTagIdx.
    static constexpr int kLastTagIdx = 10;
    static constexpr int kNumResources = kLastTagIdx * (kLastTagIdx + 1) / 2;

    Mock mock(kNumResources, kNumResources * TestResource::kDefaultSize);
    GrContext* context = mock.context();
    GrResourceCache* cache = mock.cache();
    GrGpu* gpu = context->contextPriv().getGpu();

    // tag strings are expected to be long lived
    std::vector<SkString> tagStrings;

    SkString tagStr;
    int tagIdx = 0;
    int currTagCnt = 0;

    for (int i = 0; i < kNumResources; ++i, ++currTagCnt) {

        sk_sp<GrGpuResource> resource(new TestResource(gpu));
        GrUniqueKey key;
        if (currTagCnt == tagIdx) {
            tagIdx += 1;
            currTagCnt = 0;
            tagStr.printf("tag%d", tagIdx);
            tagStrings.emplace_back(tagStr);
        }
        make_unique_key<1>(&key, i, tagStrings.back().c_str());
        resource->resourcePriv().setUniqueKey(key);
    }
    SkASSERT(kLastTagIdx == tagIdx);
    SkASSERT(currTagCnt == kLastTagIdx);

    // Test i = 0 to exercise unused tag string.
    for (int i = 0; i <= kLastTagIdx; ++i) {
        tagStr.printf("tag%d", i);
        REPORTER_ASSERT(reporter, cache->countUniqueKeysWithTag(tagStr.c_str()) == i);
    }
#endif
}

DEF_GPUTEST(ResourceCacheMisc, reporter, /* options */) {
    // The below tests create their own mock contexts.
    test_no_key(reporter);
    test_purge_unlocked(reporter);
    test_budgeting(reporter);
    test_unbudgeted(reporter);
    test_unbudgeted_to_scratch(reporter);
    test_duplicate_unique_key(reporter);
    test_duplicate_scratch_key(reporter);
    test_remove_scratch_key(reporter);
    test_scratch_key_consistency(reporter);
    test_purge_invalidated(reporter);
    test_cache_chained_purge(reporter);
    test_timestamp_wrap(reporter);
    test_flush(reporter);
    test_time_purge(reporter);
    test_partial_purge(reporter);
    test_large_resource_count(reporter);
    test_custom_data(reporter);
    test_abandoned(reporter);
    test_tags(reporter);
}

////////////////////////////////////////////////////////////////////////////////
static sk_sp<GrTexture> make_normal_texture(GrResourceProvider* provider,
                                            GrSurfaceDescFlags descFlags,
                                            int width, int height,
                                            int sampleCnt) {
    GrSurfaceDesc desc;
    desc.fFlags = descFlags;
    desc.fWidth = width;
    desc.fHeight = height;
    desc.fConfig = kRGBA_8888_GrPixelConfig;
    desc.fSampleCnt = sampleCnt;

    return provider->createTexture(desc, SkBudgeted::kYes);
}

static sk_sp<GrTextureProxy> make_mipmap_proxy(GrProxyProvider* proxyProvider,
                                               GrSurfaceDescFlags descFlags,
                                               int width, int height,
                                               int sampleCnt) {
    GrSurfaceDesc desc;
    desc.fFlags = descFlags;
    desc.fWidth = width;
    desc.fHeight = height;
    desc.fConfig = kRGBA_8888_GrPixelConfig;
    desc.fSampleCnt = sampleCnt;

    auto origin = (descFlags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
                                                            : kTopLeft_GrSurfaceOrigin;

    return proxyProvider->createMipMapProxy(desc, origin, SkBudgeted::kYes);
}

// Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only,
// Texture-only, both-RT-and-Texture and MIPmapped
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();

    static const int kSize = 64;

    // Normal versions
    {
        sk_sp<GrTexture> tex;

        tex = make_normal_texture(resourceProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 1);
        size_t size = tex->gpuMemorySize();
        REPORTER_ASSERT(reporter, kSize*kSize*4 == size);

        size_t sampleCount = (size_t)context->contextPriv().caps()->getRenderTargetSampleCount(
                4, kRGBA_8888_GrPixelConfig);
        if (sampleCount >= 4) {
            tex = make_normal_texture(resourceProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
                                      sampleCount);
            size = tex->gpuMemorySize();
            REPORTER_ASSERT(reporter,
                            kSize*kSize*4 == size ||                  // msaa4 failed
                            kSize*kSize*4*sampleCount == size ||      // auto-resolving
                            kSize*kSize*4*(sampleCount+1) == size);   // explicit resolve buffer
        }

        tex = make_normal_texture(resourceProvider, kNone_GrSurfaceFlags, kSize, kSize, 1);
        size = tex->gpuMemorySize();
        REPORTER_ASSERT(reporter, kSize*kSize*4 == size);
    }


    // Mipmapped versions
    if (context->contextPriv().caps()->mipMapSupport()) {
        sk_sp<GrTextureProxy> proxy;

        proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 1);
        size_t size = proxy->gpuMemorySize();
        REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);

        size_t sampleCount = (size_t)context->contextPriv().caps()->getRenderTargetSampleCount(
                4, kRGBA_8888_GrPixelConfig);
        if (sampleCount >= 4) {
            proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
                                      sampleCount);
            size = proxy->gpuMemorySize();
            REPORTER_ASSERT(reporter,
               kSize*kSize*4+(kSize*kSize*4)/3 == size ||                 // msaa4 failed
               kSize*kSize*4*sampleCount+(kSize*kSize*4)/3 == size ||     // auto-resolving
               kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size);  // explicit resolve buffer
        }

        proxy = make_mipmap_proxy(proxyProvider, kNone_GrSurfaceFlags, kSize, kSize, 1);
        size = proxy->gpuMemorySize();
        REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
    }
}
