1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2013 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Include here to ensure SK_SUPPORT_GPU is set correctly before it is examined.
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <thread>
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextFactory.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpu.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpuResourceCacheAccess.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpuResourcePriv.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrProxyProvider.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetPriv.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceCache.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceProvider.h"
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTest.h"
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h"
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkCanvas.h"
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h"
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMessageBus.h"
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMipMap.h"
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSurface.h"
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h"
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int gWidth = 640;
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int gHeight = 480;
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, ctxInfo) {
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceDesc desc;
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fConfig = kRGBA_8888_GrPixelConfig;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fFlags = kRenderTarget_GrSurfaceFlag;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fWidth = gWidth;
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fHeight = gHeight;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkCanvas* canvas = surface->getCanvas();
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap src;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    src.allocN32Pixels(size.width(), size.height());
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    src.eraseColor(SK_ColorBLACK);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t srcSize = src.computeByteSize();
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t initialCacheSize;
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->getResourceCacheUsage(nullptr, &initialCacheSize);
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int oldMaxNum;
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t oldMaxBytes;
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Set the cache limits so we can fit 10 "src" images and the
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // max number of textures doesn't matter
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t maxCacheSize = initialCacheSize + 10*srcSize;
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->setResourceCacheLimits(1000, maxCacheSize);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap readback;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    readback.allocN32Pixels(size.width(), size.height());
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 100; ++i) {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        canvas->drawBitmap(src, 0, 0);
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        surface->readPixels(readback, 0, 0);
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // "modify" the src texture
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        src.notifyPixelsChanged();
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t curCacheSize;
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->getResourceCacheUsage(nullptr, &curCacheSize);
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // we should never go over the size limit
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic bool is_rendering_and_not_angle_es3(sk_gpu_test::GrContextFactory::ContextType type) {
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (type == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES3_ContextType ||
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType) {
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return false;
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return sk_gpu_test::GrContextFactory::IsRenderingContext(type);
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic GrStencilAttachment* get_SB(GrRenderTarget* rt) {
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return rt->renderTargetPriv().getStencilAttachment();
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<GrRenderTarget> create_RT_with_SB(GrResourceProvider* provider,
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               int size, int sampleCount, SkBudgeted budgeted) {
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceDesc desc;
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fFlags = kRenderTarget_GrSurfaceFlag;
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fWidth = size;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fHeight = size;
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fConfig = kRGBA_8888_GrPixelConfig;
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fSampleCnt = sampleCount;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrTexture> tex(provider->createTexture(desc, budgeted));
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!tex || !tex->asRenderTarget()) {
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!provider->attachStencilAttachment(tex->asRenderTarget())) {
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(get_SB(tex->asRenderTarget()));
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return sk_ref_sp(tex->asRenderTarget());
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This currently fails on ES3 ANGLE contexts
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter,
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                         ctxInfo, nullptr) {
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (context->caps()->avoidStencilBuffers()) {
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return;
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrRenderTarget> smallRT0 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kYes);
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, smallRT0);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       // Two budgeted RTs with the same desc should share a stencil buffer.
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       sk_sp<GrRenderTarget> smallRT1 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kYes);
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       REPORTER_ASSERT(reporter, smallRT1);
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot       REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT1.get()));
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // An unbudgeted RT with the same desc should also share.
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTarget> smallRT2 = create_RT_with_SB(resourceProvider, 4, 1, SkBudgeted::kNo);
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, smallRT2);
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT2.get()));
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // An RT with a much larger size should not share.
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTarget> bigRT = create_RT_with_SB(resourceProvider, 400, 1, SkBudgeted::kNo);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, bigRT);
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(bigRT.get()));
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int smallSampleCount = context->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (smallSampleCount > 1) {
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // An RT with a different sample count should not share.
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTarget> smallMSAART0 = create_RT_with_SB(resourceProvider, 4,
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                               smallSampleCount, SkBudgeted::kNo);
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_BUILD_FOR_ANDROID
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (!smallMSAART0) {
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // The nexus player seems to fail to create MSAA textures.
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return;
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, smallMSAART0);
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(smallMSAART0.get()));
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // A second MSAA RT should share with the first MSAA RT.
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<GrRenderTarget> smallMSAART1 = create_RT_with_SB(resourceProvider, 4,
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   smallSampleCount,
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   SkBudgeted::kNo);
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, smallMSAART1);
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) == get_SB(smallMSAART1.get()));
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // But one with a larger sample count should not. (Also check that the two requests didn't
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // rounded up to the same actual sample count or else they could share.).
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int bigSampleCount = context->caps()->getSampleCount(5, kRGBA_8888_GrPixelConfig);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (bigSampleCount > 0 && bigSampleCount != smallSampleCount) {
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<GrRenderTarget> smallMSAART2 = create_RT_with_SB(resourceProvider, 4,
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   bigSampleCount,
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                   SkBudgeted::kNo);
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, smallMSAART2);
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) != get_SB(smallMSAART2.get()));
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxInfo) {
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // this test is only valid for GL
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!gpu || !gpu->glContextForTesting()) {
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return;
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrBackendTexture backendTextures[2];
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kW = 100;
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kH = 100;
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    backendTextures[0] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH,
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                              kRGBA_8888_GrPixelConfig,
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                              false, GrMipMapped::kNo);
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    backendTextures[1] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH,
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                              kRGBA_8888_GrPixelConfig,
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                              false, GrMipMapped::kNo);
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, backendTextures[0].isValid());
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, backendTextures[1].isValid());
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!backendTextures[0].isValid() || !backendTextures[1].isValid()) {
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return;
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->resetContext();
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrTexture> borrowed(resourceProvider->wrapBackendTexture(
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            backendTextures[0], kBorrow_GrWrapOwnership));
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrTexture> adopted(resourceProvider->wrapBackendTexture(
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            backendTextures[1], kAdopt_GrWrapOwnership));
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr);
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (!borrowed || !adopted) {
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return;
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    borrowed.reset(nullptr);
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    adopted.reset(nullptr);
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->flush();
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[0]);
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[1]);
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, borrowedIsAlive);
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, !adoptedIsAlive);
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    gpu->deleteTestingOnlyBackendTexture(&(backendTextures[0]), !borrowedIsAlive);
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    gpu->deleteTestingOnlyBackendTexture(&(backendTextures[1]), !adoptedIsAlive);
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->resetContext();
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass TestResource : public GrGpuResource {
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum ScratchConstructor { kScratchConstructor };
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const size_t kDefaultSize = 100;
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Property that distinctly categorizes the resource.
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot     * For example, textures have width, height, ... */
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource(GrGpu* gpu, SkBudgeted budgeted = SkBudgeted::kYes, size_t size = kDefaultSize)
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : INHERITED(gpu)
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fToDelete(nullptr)
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fSize(size)
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fProperty(kA_SimulatedProperty)
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fIsScratch(false) {
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fNumAlive;
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->registerWithCache(budgeted);
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static TestResource* CreateScratch(GrGpu* gpu, SkBudgeted budgeted,
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                       SimulatedProperty property) {
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return new TestResource(gpu, budgeted, property, kScratchConstructor);
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static TestResource* CreateWrapped(GrGpu* gpu, size_t size = kDefaultSize) {
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return new TestResource(gpu, size);
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~TestResource() override {
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        --fNumAlive;
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkSafeUnref(fToDelete);
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setSize(size_t size) {
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fSize = size;
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->didChangeGpuMemorySize();
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static int NumAlive() { return fNumAlive; }
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setUnrefWhenDestroyed(TestResource* resource) {
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkRefCnt_SafeAssign(fToDelete, resource);
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            builder[i] = static_cast<uint32_t>(i + property);
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static size_t ExpectedScratchKeySize() {
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kScratchKeyFieldCnt = 6;
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource(GrGpu* gpu, SkBudgeted budgeted, SimulatedProperty property, ScratchConstructor)
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : INHERITED(gpu)
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fToDelete(nullptr)
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fSize(kDefaultSize)
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fProperty(property)
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fIsScratch(true) {
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fNumAlive;
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->registerWithCache(budgeted);
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Constructor for simulating resources that wrap backend objects.
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource(GrGpu* gpu, size_t size)
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        : INHERITED(gpu)
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fToDelete(nullptr)
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fSize(size)
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fProperty(kA_SimulatedProperty)
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        , fIsScratch(false) {
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++fNumAlive;
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->registerWithCacheWrapped();
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void computeScratchKey(GrScratchKey* key) const override {
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fIsScratch) {
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ComputeScratchKey(fProperty, key);
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t onGpuMemorySize() const override { return fSize; }
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* fToDelete;
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t fSize;
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static int fNumAlive;
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SimulatedProperty fProperty;
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fIsScratch;
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrGpuResource INHERITED;
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotint TestResource::fNumAlive = 0;
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass Mock {
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock(int maxCnt, size_t maxBytes) {
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fContext = GrContext::MakeMock(nullptr);
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(fContext);
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fContext->setResourceCacheLimits(maxCnt, maxBytes);
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrResourceCache* cache = fContext->contextPriv().getResourceCache();
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        cache->purgeAllUnlocked();
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache() { return fContext->contextPriv().getResourceCache(); }
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context() { return fContext.get(); }
363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrContext> fContext;
366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_no_key(skiatest::Reporter* reporter) {
369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(10, 30000);
370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create a bunch of resources with no keys
375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = new TestResource(gpu);
376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = new TestResource(gpu);
377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* c = new TestResource(gpu);
378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* d = new TestResource(gpu);
379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->setSize(11);
380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->setSize(12);
381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->setSize(13);
382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    d->setSize(14);
383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              d->gpuMemorySize() == cache->getResourceBytes());
388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Should be safe to purge without deleting the resources since we still have refs.
390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Since the resources have neither unique nor scratch keys, delete immediately upon unref.
394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->unref();
402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    d->unref();
408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Each integer passed as a template param creates a new domain.
419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robottemplate <int>
420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void make_unique_key(GrUniqueKey* key, int data, const char* tag = nullptr) {
421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey::Builder builder(key, d, 1, tag);
423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    builder[0] = data;
424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_budgeting(skiatest::Reporter* reporter) {
427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(10, 300);
428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey uniqueKey;
433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&uniqueKey, 0);
434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create a scratch, a unique, and a wrapped resource
436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* scratch =
437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TestResource::CreateScratch(gpu, SkBudgeted::kYes, TestResource::kB_SimulatedProperty);
438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch->setSize(10);
439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* unique = new TestResource(gpu);
440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->setSize(11);
441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->resourcePriv().setUniqueKey(uniqueKey);
442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* wrapped = TestResource::CreateWrapped(gpu);
443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped->setSize(12);
444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* unbudgeted = new TestResource(gpu, SkBudgeted::kNo);
445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unbudgeted->setSize(13);
446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make sure we can add a unique key to the wrapped resource
448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey uniqueKey2;
449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&uniqueKey2, 1);
450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped->resourcePriv().setUniqueKey(uniqueKey2);
451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource* wrappedViaKey = cache->findAndRefUniqueResource(uniqueKey2);
452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, wrappedViaKey != nullptr);
453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Remove the extra ref we just added.
455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrappedViaKey->unref();
456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make sure sizes are as we expect
458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getBudgetedResourceBytes());
465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Our refs mean that the resources are non purgeable.
468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getBudgetedResourceBytes());
476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Unreffing the wrapped resource should free it right away.
479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped->unref();
480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Now try freeing the budgeted resources first
486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped = TestResource::CreateWrapped(gpu);
487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch->setSize(12);
488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->unref();
489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 11 == cache->getPurgeableBytes());
490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes());
496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch->unref();
499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 12 == cache->getPurgeableBytes());
500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped->unref();
509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes());
511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unbudgeted->unref();
516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_unbudgeted(skiatest::Reporter* reporter) {
524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(10, 30000);
525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey uniqueKey;
530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&uniqueKey, 0);
531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* scratch;
533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* unique;
534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* wrapped;
535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* unbudgeted;
536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // A large uncached or wrapped resource shouldn't evict anything.
538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          TestResource::kB_SimulatedProperty);
540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch->setSize(10);
542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch->unref();
543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes());
545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes());
547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 10 == cache->getPurgeableBytes());
548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique = new TestResource(gpu);
550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->setSize(11);
551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->resourcePriv().setUniqueKey(uniqueKey);
552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unique->unref();
553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());
558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t large = 2 * cache->getResourceBytes();
560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unbudgeted = new TestResource(gpu, SkBudgeted::kNo, large);
561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());
566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    unbudgeted->unref();
568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());
573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped = TestResource::CreateWrapped(gpu, large);
575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());
580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    wrapped->unref();
582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes());
587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This method can't be static because it needs to friended in GrGpuResource::CacheAccess.
597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(10, 300);
600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* resource =
605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource::CreateScratch(gpu, SkBudgeted::kNo, TestResource::kA_SimulatedProperty);
606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey key;
607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);
608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t size = resource->gpuMemorySize();
610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 2; ++i) {
611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Since this resource is unbudgeted, it should not be reachable as scratch.
612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, SkBudgeted::kNo == resource->resourcePriv().isBudgeted());
615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0));
616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Once it is unrefed, it should become available as scratch.
623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->unref();
624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, size == cache->getPurgeableBytes());
629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0));
630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, resource);
631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted());
634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (0 == i) {
636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // the above tests again.
638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            resource->resourcePriv().makeUnbudgeted();
639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // After the second time around, try removing the scratch key
641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            resource->resourcePriv().removeScratchKey();
642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid());
648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted());
650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // now when it is unrefed it should die since it has no key.
652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            resource->unref();
653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(5, 30000);
664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create two resources that have the same scratch key.
669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = TestResource::CreateScratch(gpu,
670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  SkBudgeted::kYes,
671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = TestResource::CreateScratch(gpu,
673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  SkBudgeted::kYes,
674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->setSize(11);
676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->setSize(12);
677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey1;
678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Check for negative case consistency. (leaks upon test failure.)
680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(scratchKey1, TestResource::kDefaultSize, 0));
681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey;
683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              cache->getResourceBytes());
691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Our refs mean that the resources are non purgeable.
693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Unref but don't purge
698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Purge again. This time resources should be purgeable.
704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_remove_scratch_key(skiatest::Reporter* reporter) {
711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(5, 30000);
712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create two resources that have the same scratch key.
717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey;
725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Ensure that scratch key lookup is correct for negative case.
726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // (following leaks upon test failure).
728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr);
729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Find the first resource and remove its scratch key
737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource* find;
738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->resourcePriv().removeScratchKey();
740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // It's still alive, but not cached by scratch key anymore
741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The cache should immediately delete it when it's unrefed since it isn't accessible.
746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->unref();
747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Repeat for the second resource.
752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->resourcePriv().removeScratchKey();
754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Should be able to call this multiple times with no problem.
759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->resourcePriv().removeScratchKey();
760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->unref();
765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_scratch_key_consistency(skiatest::Reporter* reporter) {
771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(5, 30000);
772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create two resources that have the same scratch key.
777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kB_SimulatedProperty);
781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey;
785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Ensure that scratch key comparison and assignment is consistent.
786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey1;
787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey2;
789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2);
790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratchKey = scratchKey1;
794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratchKey = scratchKey2;
800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratchKey == scratchKey2);
805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Ensure that scratch key lookup is correct for negative case.
807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // (following leaks upon test failure).
809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr);
810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Find the first resource with a scratch key and a copy of a scratch key.
812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource* find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find != nullptr);
815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->unref();
816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratchKey2 = scratchKey;
818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0);
819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find != nullptr);
820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find == a || find == b);
821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0);
823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find2 != nullptr);
824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find2 == a || find2 == b);
825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, find2 != find);
826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find2->unref();
827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    find->unref();
828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_duplicate_unique_key(skiatest::Reporter* reporter) {
831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(5, 30000);
832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key;
837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key, 0);
838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create two resources that we will attempt to register with the same unique key.
840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = new TestResource(gpu);
841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->setSize(11);
842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Set key on resource a.
844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->resourcePriv().setUniqueKey(key);
845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make sure that redundantly setting a's key works.
849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->resourcePriv().setUniqueKey(key);
850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes());
854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Create resource b and set the same key. It should replace a's unique key cache entry.
857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = new TestResource(gpu);
858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->setSize(12);
859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->resourcePriv().setUniqueKey(key);
860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key));
861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
863fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Still have two resources because a is still reffed.
864fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
865fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes());
866fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
867fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
868fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
869fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Now a should be gone.
870fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
871fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
872fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
873fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
874fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Now replace b with c, but make sure c can start with one unique key and change it to b's key.
875fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Also make b be unreffed when replacement occurs.
876fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
877fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* c = new TestResource(gpu);
878fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey differentKey;
879fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&differentKey, 1);
880fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->setSize(13);
881fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->resourcePriv().setUniqueKey(differentKey);
882fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
883fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes());
884fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
885fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // c replaces b and b should be immediately purged.
886fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->resourcePriv().setUniqueKey(key);
887fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
888fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
889fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
890fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
891fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // c shouldn't be purged because it is ref'ed.
892fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
893fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
894fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
895fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
896fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
897fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Drop the ref on c, it should be kept alive because it has a unique key.
898fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->unref();
899fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
900fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
901fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
902fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
903fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Verify that we can find c, then remove its unique key. It should get purged immediately.
904fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key));
905fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->resourcePriv().removeUniqueKey();
906fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->unref();
907fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
908fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
909fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
910fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
911fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
912fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key2;
913fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<0>(&key2, 0);
914fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<TestResource> d(new TestResource(gpu));
915fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int foo = 4132;
916fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        key2.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo)));
917fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        d->resourcePriv().setUniqueKey(key2);
918fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
919fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
920fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key3;
921fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key3, 0);
922fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrGpuResource> d2(cache->findAndRefUniqueResource(key3));
923fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, *(int*) d2->getUniqueKey().getCustomData()->data() == 4132);
924fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
925fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
926fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_purge_invalidated(skiatest::Reporter* reporter) {
927fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(5, 30000);
928fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
929fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
930fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
931fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
932fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key1, key2, key3;
933fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key1, 1);
934fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key2, 2);
935fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key3, 3);
936fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
937fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Add three resources to the cache. Only c is usable as scratch.
938fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = new TestResource(gpu);
939fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = new TestResource(gpu);
940fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* c = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
941fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                  TestResource::kA_SimulatedProperty);
942fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->resourcePriv().setUniqueKey(key1);
943fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->resourcePriv().setUniqueKey(key2);
944fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->resourcePriv().setUniqueKey(key3);
945fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
946fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // hold b until *after* the message is sent.
947fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    c->unref();
948fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
949fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
950fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
951fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
952fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
953fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
954fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrUniqueKeyInvalidatedMessage Msg;
955fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus;
956fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
957fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Invalidate two of the three, they should be purged and no longer accessible via their keys.
958fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Bus::Post(Msg(key1));
959fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Bus::Post(Msg(key2));
960fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAsNeeded();
961fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // a should be deleted now, but we still have a ref on b.
962fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
963fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
964fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
965fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
966fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
967fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Invalidate the third.
968fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Bus::Post(Msg(key3));
969fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAsNeeded();
970fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // we still have a ref on b, c should be recycled as scratch.
971fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
972fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3));
973fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
974fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // make b purgeable. It should be immediately deleted since it has no key.
975fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
976fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
977fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
978fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make sure we actually get to c via it's scratch key, before we say goodbye.
979fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrScratchKey scratchKey;
980fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
981fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
982fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, scratch == c);
983fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkSafeUnref(scratch);
984fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
985fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Get rid of c.
986fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
987fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0);
988fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
989fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
990fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
991fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, !scratch);
992fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkSafeUnref(scratch);
993fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
994fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
995fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_cache_chained_purge(skiatest::Reporter* reporter) {
996fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(3, 30000);
997fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
998fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
999fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1000fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1001fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key1, key2;
1002fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key1, 1);
1003fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key2, 2);
1004fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1005fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* a = new TestResource(gpu);
1006fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    TestResource* b = new TestResource(gpu);
1007fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->resourcePriv().setUniqueKey(key1);
1008fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->resourcePriv().setUniqueKey(key2);
1009fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1010fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Make a cycle
1011fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->setUnrefWhenDestroyed(b);
1012fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->setUnrefWhenDestroyed(a);
1013fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1014fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
1015fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1016fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->unref();
1017fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    b->unref();
1018fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1019fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
1020fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1021fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
1022fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
1023fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1024fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Break the cycle
1025fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    a->setUnrefWhenDestroyed(nullptr);
1026fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
1027fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1028fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
1029fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
1030fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1031fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1032fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_resource_size_changed(skiatest::Reporter* reporter) {
1033fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key1, key2;
1034fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key1, 1);
1035fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key2, 2);
1036fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1037fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test changing resources sizes (both increase & decrease).
1038fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1039fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Mock mock(3, 30000);
1040fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContext* context = mock.context();
1041fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrResourceCache* cache = mock.cache();
1042fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrGpu* gpu = context->contextPriv().getGpu();
1043fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1044fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* a = new TestResource(gpu);
1045fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a->resourcePriv().setUniqueKey(key1);
1046fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a->unref();
1047fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1048fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* b = new TestResource(gpu);
1049fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b->resourcePriv().setUniqueKey(key2);
1050fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b->unref();
1051fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1052fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
1053fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
1054fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
1055fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<TestResource> find2(
1056fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                static_cast<TestResource*>(cache->findAndRefUniqueResource(key2)));
1057fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            find2->setSize(200);
1058fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<TestResource> find1(
1059fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                static_cast<TestResource*>(cache->findAndRefUniqueResource(key1)));
1060fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            find1->setSize(50);
1061fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1062fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1063fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes());
1064fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
1065fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1066fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1067fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test increasing a resources size beyond the cache budget.
1068fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1069fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Mock mock(2, 300);
1070fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContext* context = mock.context();
1071fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrResourceCache* cache = mock.cache();
1072fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrGpu* gpu = context->contextPriv().getGpu();
1073fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1074fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* a = new TestResource(gpu);
1075fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a->setSize(100);
1076fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a->resourcePriv().setUniqueKey(key1);
1077fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a->unref();
1078fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1079fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* b = new TestResource(gpu);
1080fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b->setSize(100);
1081fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b->resourcePriv().setUniqueKey(key2);
1082fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        b->unref();
1083fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1084fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
1085fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
1086fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1087fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
1088fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            sk_sp<TestResource> find2(static_cast<TestResource*>(
1089fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                cache->findAndRefUniqueResource(key2)));
1090fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            find2->setSize(201);
1091fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1092fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
1093fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1094fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes());
1095fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
1096fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1097fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1098fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1099fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_timestamp_wrap(skiatest::Reporter* reporter) {
1100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kCount = 50;
1101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kBudgetCnt = kCount / 2;
1102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kLockedFreq = 8;
1103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kBudgetSize = 0x80000000;
1104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkRandom random;
1106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Run the test 2*kCount times;
1108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 2 * kCount; ++i ) {
1109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Mock mock(kBudgetCnt, kBudgetSize);
1110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrContext* context = mock.context();
1111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrResourceCache* cache = mock.cache();
1112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrGpu* gpu = context->contextPriv().getGpu();
1113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Pick a random number of resources to add before the timestamp will wrap.
1115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1));
1116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        static const int kNumToPurge = kCount - kBudgetCnt;
1118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkTDArray<int> shouldPurgeIdxs;
1120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int purgeableCnt = 0;
1121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkTDArray<GrGpuResource*> resourcesToUnref;
1122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Add kCount resources, holding onto resources at random so we have a mix of purgeable and
1124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // unpurgeable resources.
1125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 0; j < kCount; ++j) {
1126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrUniqueKey key;
1127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            make_unique_key<0>(&key, j);
1128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TestResource* r = new TestResource(gpu);
1130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->resourcePriv().setUniqueKey(key);
1131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (random.nextU() % kLockedFreq) {
1132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // Make this is purgeable.
1133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                r->unref();
1134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ++purgeableCnt;
1135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (purgeableCnt <= kNumToPurge) {
1136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    *shouldPurgeIdxs.append() = j;
1137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
1139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *resourcesToUnref.append() = r;
1140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Verify that the correct resources were purged.
1144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int currShouldPurgeIdx = 0;
1145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 0; j < kCount; ++j) {
1146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrUniqueKey key;
1147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            make_unique_key<0>(&key, j);
1148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrGpuResource* res = cache->findAndRefUniqueResource(key);
1149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (currShouldPurgeIdx < shouldPurgeIdxs.count() &&
1150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                shouldPurgeIdxs[currShouldPurgeIdx] == j) {
1151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ++currShouldPurgeIdx;
1152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, nullptr == res);
1153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
1154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, nullptr != res);
1155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkSafeUnref(res);
1157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int j = 0; j < resourcesToUnref.count(); ++j) {
1160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            resourcesToUnref[j]->unref();
1161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_flush(skiatest::Reporter* reporter) {
1166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(1000000, 1000000);
1167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
1169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The current cache impl will round the max flush count to the next power of 2. So we choose a
1172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // power of two here to keep things simpler.
1173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kFlushCount = 16;
1174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->setLimits(1000000, 1000000, kFlushCount);
1175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Insert a resource and send a flush notification kFlushCount times.
1178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount; ++i) {
1179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TestResource* r = new TestResource(gpu);
1180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrUniqueKey k;
1181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            make_unique_key<1>(&k, i);
1182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->resourcePriv().setUniqueKey(k);
1183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->unref();
1184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->notifyFlushOccurred(GrResourceCache::kExternal);
1185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Send flush notifications to the cache. Each flush should purge the oldest resource.
1188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount; ++i) {
1189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->notifyFlushOccurred(GrResourceCache::kExternal);
1190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount());
1191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int j = 0; j < i; ++j) {
1192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                GrUniqueKey k;
1193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                make_unique_key<1>(&k, j);
1194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                GrGpuResource* r = cache->findAndRefUniqueResource(k);
1195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, !SkToBool(r));
1196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                SkSafeUnref(r);
1197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        cache->purgeAllUnlocked();
1202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Do a similar test but where we leave refs on some resources to prevent them from being
1205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // purged.
1206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrGpuResource* refedResources[kFlushCount >> 1];
1208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount; ++i) {
1209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TestResource* r = new TestResource(gpu);
1210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrUniqueKey k;
1211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            make_unique_key<1>(&k, i);
1212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->resourcePriv().setUniqueKey(k);
1213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Leave a ref on every other resource, beginning with the first.
1214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (SkToBool(i & 0x1)) {
1215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                refedResources[i/2] = r;
1216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            } else {
1217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                r->unref();
1218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->notifyFlushOccurred(GrResourceCache::kExternal);
1220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount; ++i) {
1223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Should get a resource purged every other flush.
1224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->notifyFlushOccurred(GrResourceCache::kExternal);
1225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount());
1226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Unref all the resources that we kept refs on in the first loop.
1229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount >> 1; ++i) {
1230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            refedResources[i]->unref();
1231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // After kFlushCount + 1 flushes they all will have sat in the purgeable queue for
1234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // kFlushCount full flushes.
1235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < kFlushCount + 1; ++i) {
1236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount());
1237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->notifyFlushOccurred(GrResourceCache::kExternal);
1238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        cache->purgeAllUnlocked();
1242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Verify that calling flush() on a GrContext with nothing to do will not trigger resource
1247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // eviction.
1248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->flush();
1249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 10; ++i) {
1250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* r = new TestResource(gpu);
1251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey k;
1252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<1>(&k, i);
1253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r->resourcePriv().setUniqueKey(k);
1254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        r->unref();
1255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
1257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < 10 * kFlushCount; ++i) {
1258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->flush();
1259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
1261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_time_purge(skiatest::Reporter* reporter) {
1264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(1000000, 1000000);
1265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
1267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kCnts[] = {1, 10, 1024};
1270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto nowish = []() {
1271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // We sleep so that we ensure we get a value that is greater than the last call to
1272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // GrStdSteadyClock::now().
1273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::this_thread::sleep_for(GrStdSteadyClock::duration(5));
1274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        auto result = GrStdSteadyClock::now();
1275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Also sleep afterwards so we don't get this value again.
1276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::this_thread::sleep_for(GrStdSteadyClock::duration(5));
1277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
1278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int cnt : kCnts) {
1281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::unique_ptr<GrStdSteadyClock::time_point[]> timeStamps(
1282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                new GrStdSteadyClock::time_point[cnt]);
1283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
1284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Insert resources and get time points between each addition.
1285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = 0; i < cnt; ++i) {
1286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                TestResource* r = new TestResource(gpu);
1287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                GrUniqueKey k;
1288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                make_unique_key<1>(&k, i);
1289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                r->resourcePriv().setUniqueKey(k);
1290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                r->unref();
1291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                timeStamps.get()[i] = nowish();
1292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Purge based on the time points between resource additions. Each purge should remove
1295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // the oldest resource.
1296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = 0; i < cnt; ++i) {
1297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                cache->purgeResourcesNotUsedSince(timeStamps[i]);
1298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, cnt - i - 1 == cache->getResourceCount());
1299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                for (int j = 0; j < i; ++j) {
1300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrUniqueKey k;
1301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    make_unique_key<1>(&k, j);
1302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrGpuResource* r = cache->findAndRefUniqueResource(k);
1303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(reporter, !SkToBool(r));
1304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    SkSafeUnref(r);
1305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->purgeAllUnlocked();
1310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Do a similar test but where we leave refs on some resources to prevent them from being
1313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // purged.
1314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        {
1315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::unique_ptr<GrGpuResource* []> refedResources(new GrGpuResource*[cnt / 2]);
1316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = 0; i < cnt; ++i) {
1317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                TestResource* r = new TestResource(gpu);
1318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                GrUniqueKey k;
1319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                make_unique_key<1>(&k, i);
1320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                r->resourcePriv().setUniqueKey(k);
1321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // Leave a ref on every other resource, beginning with the first.
1322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (SkToBool(i & 0x1)) {
1323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    refedResources.get()[i / 2] = r;
1324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
1325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    r->unref();
1326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
1327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                timeStamps.get()[i] = nowish();
1328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = 0; i < cnt; ++i) {
1331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                // Should get a resource purged every other frame.
1332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                cache->purgeResourcesNotUsedSince(timeStamps[i]);
1333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, cnt - i / 2 - 1 == cache->getResourceCount());
1334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // Unref all the resources that we kept refs on in the first loop.
1337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            for (int i = 0; i < (cnt / 2); ++i) {
1338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                refedResources.get()[i]->unref();
1339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                cache->purgeResourcesNotUsedSince(nowish());
1340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, cnt / 2 - i - 1 == cache->getResourceCount());
1341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            cache->purgeAllUnlocked();
1344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Verify that calling flush() on a GrContext with nothing to do will not trigger resource
1349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // eviction
1350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->flush();
1351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for (int i = 0; i < 10; ++i) {
1352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            TestResource* r = new TestResource(gpu);
1353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrUniqueKey k;
1354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            make_unique_key<1>(&k, i);
1355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->resourcePriv().setUniqueKey(k);
1356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            r->unref();
1357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
1359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->flush();
1360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 10 == cache->getResourceCount());
1361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        cache->purgeResourcesNotUsedSince(nowish());
1362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
1363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_partial_purge(skiatest::Reporter* reporter) {
1367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(6, 100);
1368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
1370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum TestsCase {
1373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOnlyScratch_TestCase = 0,
1374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPartialScratch_TestCase = 1,
1375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAllScratch_TestCase = 2,
1376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPartial_TestCase = 3,
1377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kAll_TestCase = 4,
1378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNone_TestCase = 5,
1379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kEndTests_TestCase = kNone_TestCase + 1
1380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
1381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int testCase = 0; testCase < kEndTests_TestCase; testCase++) {
1383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key1, key2, key3;
1385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<0>(&key1, 1);
1386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<0>(&key2, 2);
1387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<0>(&key3, 3);
1388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Add three unique resources to the cache.
1390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource *unique1 = new TestResource(gpu);
1391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource *unique2 = new TestResource(gpu);
1392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource *unique3 = new TestResource(gpu);
1393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique1->resourcePriv().setUniqueKey(key1);
1395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique2->resourcePriv().setUniqueKey(key2);
1396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique3->resourcePriv().setUniqueKey(key3);
1397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique1->setSize(10);
1399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique2->setSize(11);
1400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique3->setSize(12);
1401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Add two scratch resources to the cache.
1403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource *scratch1 = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
1404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             TestResource::kA_SimulatedProperty);
1405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource *scratch2 = TestResource::CreateScratch(gpu, SkBudgeted::kYes,
1406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                             TestResource::kB_SimulatedProperty);
1407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        scratch1->setSize(13);
1408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        scratch2->setSize(14);
1409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
1412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
1413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
1414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // Add resources to the purgeable queue
1416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique1->unref();
1417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        scratch1->unref();
1418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique2->unref();
1419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        scratch2->unref();
1420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unique3->unref();
1421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
1423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
1424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes());
1425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch(testCase) {
1427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kOnlyScratch_TestCase: {
1428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(14, true);
1429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount());
1430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 33 == cache->getBudgetedResourceBytes());
1431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kPartialScratch_TestCase: {
1434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(3, true);
1435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 4 == cache->getBudgetedResourceCount());
1436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 47 == cache->getBudgetedResourceBytes());
1437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kAllScratch_TestCase: {
1440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(50, true);
1441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
1442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
1443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kPartial_TestCase: {
1446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(13, false);
1447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount());
1448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 37 == cache->getBudgetedResourceBytes());
1449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kAll_TestCase: {
1452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(50, false);
1453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
1454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
1455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kNone_TestCase: {
1458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(0, true);
1459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                context->purgeUnlockedResources(0, false);
1460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount());
1461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes());
1462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes());
1463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
1464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
1465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        };
1466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // ensure all are purged before the next
1468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        context->purgeAllUnlockedResources();
1469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
1470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes());
1471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_large_resource_count(skiatest::Reporter* reporter) {
1476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Set the cache size to double the resource count because we're going to create 2x that number
1477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // resources, using two different key domains. Add a little slop to the bytes because we resize
1478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // down to 1 byte after creating the resource.
1479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kResourceCnt = 2000;
1480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
1482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
1484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < kResourceCnt; ++i) {
1487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key1, key2;
1488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<1>(&key1, i);
1489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<2>(&key2, i);
1490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TestResource* resource;
1492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource = new TestResource(gpu);
1494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->resourcePriv().setUniqueKey(key1);
1495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->setSize(1);
1496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->unref();
1497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource = new TestResource(gpu);
1499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->resourcePriv().setUniqueKey(key2);
1500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->setSize(1);
1501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->unref();
1502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
1505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 2 * kResourceCnt);
1506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt);
1507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt);
1508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt);
1509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt);
1510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < kResourceCnt; ++i) {
1511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key1, key2;
1512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<1>(&key1, i);
1513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<2>(&key2, i);
1514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
1516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
1517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    cache->purgeAllUnlocked();
1520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
1521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 0);
1522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0);
1523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0);
1524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0);
1525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, cache->getResourceCount() == 0);
1526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < kResourceCnt; ++i) {
1528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key1, key2;
1529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<1>(&key1, i);
1530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<2>(&key2, i);
1531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
1533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
1534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_custom_data(skiatest::Reporter* reporter) {
1538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key1, key2;
1539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key1, 1);
1540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key2, 2);
1541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int foo = 4132;
1542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    key1.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo)));
1543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, *(int*) key1.getCustomData()->data() == 4132);
1544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, key2.getCustomData() == nullptr);
1545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test that copying a key also takes a ref on its custom data.
1547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key3 = key1;
1548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, *(int*) key3.getCustomData()->data() == 4132);
1549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_abandoned(skiatest::Reporter* reporter) {
1552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(10, 300);
1553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrGpuResource> resource(new TestResource(gpu));
1557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->abandonContext();
1558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    REPORTER_ASSERT(reporter, resource->wasDestroyed());
1560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Call all the public methods on resource in the abandoned state. They shouldn't crash.
1562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->uniqueID();
1564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->getUniqueKey();
1565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->wasDestroyed();
1566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->gpuMemorySize();
1567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->getContext();
1568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->abandon();
1570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().getScratchKey();
1571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().isBudgeted();
1572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().makeBudgeted();
1573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().makeUnbudgeted();
1574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().removeScratchKey();
1575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrUniqueKey key;
1576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    make_unique_key<0>(&key, 1);
1577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().setUniqueKey(key);
1578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    resource->resourcePriv().removeUniqueKey();
1579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic void test_tags(skiatest::Reporter* reporter) {
1582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG
1583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // We will insert 1 resource with tag "tag1", 2 with "tag2", and so on, up through kLastTagIdx.
1584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kLastTagIdx = 10;
1585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr int kNumResources = kLastTagIdx * (kLastTagIdx + 1) / 2;
1586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Mock mock(kNumResources, kNumResources * TestResource::kDefaultSize);
1588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = mock.context();
1589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceCache* cache = mock.cache();
1590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrGpu* gpu = context->contextPriv().getGpu();
1591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString tagStr;
1593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int tagIdx = 0;
1594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int currTagCnt = 0;
1595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < kNumResources; ++i, ++currTagCnt) {
1597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrGpuResource> resource(new TestResource(gpu));
1598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrUniqueKey key;
1599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (currTagCnt == tagIdx) {
1600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            tagIdx += 1;
1601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            currTagCnt = 0;
1602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            tagStr.printf("tag%d", tagIdx);
1603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        make_unique_key<1>(&key, i, tagStr.c_str());
1605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resource->resourcePriv().setUniqueKey(key);
1606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(kLastTagIdx == tagIdx);
1608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(currTagCnt == kLastTagIdx);
1609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Test i = 0 to exercise unused tag string.
1611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i <= kLastTagIdx; ++i) {
1612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        tagStr.printf("tag%d", i);
1613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, cache->countUniqueKeysWithTag(tagStr.c_str()) == i);
1614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
1616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST(ResourceCacheMisc, reporter, /* options */) {
1619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // The below tests create their own mock contexts.
1620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_no_key(reporter);
1621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_budgeting(reporter);
1622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_unbudgeted(reporter);
1623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_unbudgeted_to_scratch(reporter);
1624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_duplicate_unique_key(reporter);
1625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_duplicate_scratch_key(reporter);
1626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_remove_scratch_key(reporter);
1627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_scratch_key_consistency(reporter);
1628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_purge_invalidated(reporter);
1629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_cache_chained_purge(reporter);
1630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_resource_size_changed(reporter);
1631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_timestamp_wrap(reporter);
1632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_flush(reporter);
1633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_time_purge(reporter);
1634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_partial_purge(reporter);
1635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_large_resource_count(reporter);
1636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_custom_data(reporter);
1637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_abandoned(reporter);
1638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    test_tags(reporter);
1639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////////
1642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<GrTexture> make_normal_texture(GrResourceProvider* provider,
1643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            GrSurfaceFlags flags,
1644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            int width, int height,
1645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            int sampleCnt) {
1646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceDesc desc;
1647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fFlags = flags;
1648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
1649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fWidth = width;
1650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fHeight = height;
1651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fConfig = kRGBA_8888_GrPixelConfig;
1652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fSampleCnt = sampleCnt;
1653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return provider->createTexture(desc, SkBudgeted::kYes);
1655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic sk_sp<GrTextureProxy> make_mipmap_proxy(GrProxyProvider* proxyProvider,
1658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               GrSurfaceFlags flags,
1659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               int width, int height,
1660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                               int sampleCnt) {
1661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkBitmap bm;
1662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm.allocN32Pixels(width, height, true);
1664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bm.eraseColor(SK_ColorBLUE);
1665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkMipMap> mipmaps(SkMipMap::Build(bm, SkDestinationSurfaceColorMode::kLegacy, nullptr));
1667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(mipmaps);
1668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(mipmaps->countLevels() > 1);
1669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int mipLevelCount = mipmaps->countLevels() + 1;
1671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
1673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    texels[0].fPixels = bm.getPixels();
1675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    texels[0].fRowBytes = bm.rowBytes();
1676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 1; i < mipLevelCount; ++i) {
1678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkMipMap::Level generatedMipLevel;
1679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        mipmaps->getLevel(i - 1, &generatedMipLevel);
1680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        texels[i].fPixels = generatedMipLevel.fPixmap.addr();
1681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
1682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceDesc desc;
1685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fFlags = flags;
1686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fOrigin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin
1687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                         : kTopLeft_GrSurfaceOrigin;
1688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fWidth = width;
1689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fHeight = height;
1690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fConfig = kRGBA_8888_GrPixelConfig;
1691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fSampleCnt = sampleCnt;
1692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes, texels.get(), mipLevelCount);
1694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only,
1697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Texture-only, both-RT-and-Texture and MIPmapped
1698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
1699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = ctxInfo.grContext();
1700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
1701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrResourceProvider* resourceProvider = context->contextPriv().resourceProvider();
1702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const int kSize = 64;
1704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Normal versions
1706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    {
1707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrTexture> tex;
1708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        tex = make_normal_texture(resourceProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 1);
1710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t size = tex->gpuMemorySize();
1711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, kSize*kSize*4 == size);
1712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
1714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (sampleCount >= 4) {
1715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            tex = make_normal_texture(resourceProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
1716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      sampleCount);
1717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            size = tex->gpuMemorySize();
1718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter,
1719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            kSize*kSize*4 == size ||                  // msaa4 failed
1720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            kSize*kSize*4*sampleCount == size ||      // auto-resolving
1721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                            kSize*kSize*4*(sampleCount+1) == size);   // explicit resolve buffer
1722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        tex = make_normal_texture(resourceProvider, kNone_GrSurfaceFlags, kSize, kSize, 1);
1725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size = tex->gpuMemorySize();
1726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, kSize*kSize*4 == size);
1727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // Mipmapped versions
1731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (context->caps()->mipMapSupport()) {
1732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrTextureProxy> proxy;
1733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 1);
1735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t size = proxy->gpuMemorySize();
1736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
1737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
1739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (sampleCount >= 4) {
1740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            proxy = make_mipmap_proxy(proxyProvider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
1741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      sampleCount);
1742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            size = proxy->gpuMemorySize();
1743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter,
1744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               kSize*kSize*4+(kSize*kSize*4)/3 == size ||                 // msaa4 failed
1745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               kSize*kSize*4*sampleCount+(kSize*kSize*4)/3 == size ||     // auto-resolving
1746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size);  // explicit resolve buffer
1747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
1748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        proxy = make_mipmap_proxy(proxyProvider, kNone_GrSurfaceFlags, kSize, kSize, 1);
1750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        size = proxy->gpuMemorySize();
1751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
1752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
1753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
1754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
1755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
1756