ResourceCacheTest.cpp revision 3e5f55542cbd23f1ad448cac3d29e8551204552c
1c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org/*
2c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * Copyright 2013 Google Inc.
3c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org *
4c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * found in the LICENSE file.
6c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org */
7c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
83f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon// Include here to ensure SK_SUPPORT_GPU is set correctly before it is examined.
93f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon#include "SkTypes.h"
103f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#if SK_SUPPORT_GPU
124ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org
13bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrContext.h"
14c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#include "GrContextFactory.h"
15bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrGpu.h"
163582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourceCacheAccess.h"
173582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h"
186bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTarget.h"
196bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h"
200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h"
216dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon#include "GrTest.h"
22bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "SkCanvas.h"
2371cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkGr.h"
2471cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkMessageBus.h"
2569f6f00fd975823e825c5aa0b1b8f4416e7c812breed#include "SkSurface.h"
264ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "Test.h"
27c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
28c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gWidth = 640;
29c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gHeight = 480;
30c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
31c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
32334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonstatic void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) {
33c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    const SkIRect size = SkIRect::MakeWH(gWidth, gHeight);
34c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
35c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    SkBitmap src;
36deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org    src.allocN32Pixels(size.width(), size.height());
37c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    src.eraseColor(SK_ColorBLACK);
38c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    size_t srcSize = src.getSize();
39c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
4095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    size_t initialCacheSize;
4195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    context->getResourceCacheUsage(NULL, &initialCacheSize);
42c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
43c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    int oldMaxNum;
44c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    size_t oldMaxBytes;
4595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes);
4617f1ae63d57a3f3d3a0ae50e1b25b3f8b18fd328skia.committer@gmail.com
47c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    // Set the cache limits so we can fit 10 "src" images and the
48c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    // max number of textures doesn't matter
49c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    size_t maxCacheSize = initialCacheSize + 10*srcSize;
5095c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    context->setResourceCacheLimits(1000, maxCacheSize);
51c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
52c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    SkBitmap readback;
53deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org    readback.allocN32Pixels(size.width(), size.height());
54c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
55c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    for (int i = 0; i < 100; ++i) {
56c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        canvas->drawBitmap(src, 0, 0);
57c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        canvas->readPixels(size, &readback);
58c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
59c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        // "modify" the src texture
60c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        src.notifyPixelsChanged();
61c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
6295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        size_t curCacheSize;
6395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        context->getResourceCacheUsage(NULL, &curCacheSize);
64c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
65c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        // we should never go over the size limit
66c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize);
67c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    }
68c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
6995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org    context->setResourceCacheLimits(oldMaxNum, oldMaxBytes);
70c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org}
71c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
7202a44a488605112aa6683c9d919e13b188112ce1bsalomonstatic void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* context) {
7302a44a488605112aa6683c9d919e13b188112ce1bsalomon    GrSurfaceDesc smallDesc;
7402a44a488605112aa6683c9d919e13b188112ce1bsalomon    smallDesc.fFlags = kRenderTarget_GrSurfaceFlag;
7502a44a488605112aa6683c9d919e13b188112ce1bsalomon    smallDesc.fConfig = kSkia8888_GrPixelConfig;
7602a44a488605112aa6683c9d919e13b188112ce1bsalomon    smallDesc.fWidth = 4;
7702a44a488605112aa6683c9d919e13b188112ce1bsalomon    smallDesc.fHeight = 4;
7802a44a488605112aa6683c9d919e13b188112ce1bsalomon    smallDesc.fSampleCnt = 0;
7902a44a488605112aa6683c9d919e13b188112ce1bsalomon
80d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    GrTextureProvider* cache = context->textureProvider();
8102a44a488605112aa6683c9d919e13b188112ce1bsalomon    // Test that two budgeted RTs with the same desc share a stencil buffer.
82d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> smallRT0(cache->createTexture(smallDesc, true));
836bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    if (smallRT0 && smallRT0->asRenderTarget()) {
848dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel        smallRT0->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
856bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    }
866bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon
87d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> smallRT1(cache->createTexture(smallDesc, true));
886bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    if (smallRT1 && smallRT1->asRenderTarget()) {
898dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel        smallRT1->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
906bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    }
916bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon
928dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel    REPORTER_ASSERT(reporter,
938dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0 && smallRT1 &&
948dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget() && smallRT1->asRenderTarget() &&
958dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget()->renderTargetPriv().getStencilAttachment() ==
968dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT1->asRenderTarget()->renderTargetPriv().getStencilAttachment());
9702a44a488605112aa6683c9d919e13b188112ce1bsalomon
9802a44a488605112aa6683c9d919e13b188112ce1bsalomon    // An unbudgeted RT with the same desc should also share.
99d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> smallRT2(cache->createTexture(smallDesc, false));
1006bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    if (smallRT2 && smallRT2->asRenderTarget()) {
1018dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel        smallRT2->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
1026bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    }
1038dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel    REPORTER_ASSERT(reporter,
1048dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0 && smallRT2 &&
1058dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget() && smallRT2->asRenderTarget() &&
1068dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget()->renderTargetPriv().getStencilAttachment() ==
1078dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT2->asRenderTarget()->renderTargetPriv().getStencilAttachment());
10802a44a488605112aa6683c9d919e13b188112ce1bsalomon
10902a44a488605112aa6683c9d919e13b188112ce1bsalomon    // An RT with a much larger size should not share.
11002a44a488605112aa6683c9d919e13b188112ce1bsalomon    GrSurfaceDesc bigDesc;
11102a44a488605112aa6683c9d919e13b188112ce1bsalomon    bigDesc.fFlags = kRenderTarget_GrSurfaceFlag;
11202a44a488605112aa6683c9d919e13b188112ce1bsalomon    bigDesc.fConfig = kSkia8888_GrPixelConfig;
11302a44a488605112aa6683c9d919e13b188112ce1bsalomon    bigDesc.fWidth = 400;
11402a44a488605112aa6683c9d919e13b188112ce1bsalomon    bigDesc.fHeight = 200;
11502a44a488605112aa6683c9d919e13b188112ce1bsalomon    bigDesc.fSampleCnt = 0;
116d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> bigRT(cache->createTexture(bigDesc, false));
1176bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    if (bigRT && bigRT->asRenderTarget()) {
1188dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel        bigRT->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
1196bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon    }
1208dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel    REPORTER_ASSERT(reporter,
1218dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0 && bigRT &&
1228dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget() && bigRT->asRenderTarget() &&
1238dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    smallRT0->asRenderTarget()->renderTargetPriv().getStencilAttachment() !=
1248dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                    bigRT->asRenderTarget()->renderTargetPriv().getStencilAttachment());
12502a44a488605112aa6683c9d919e13b188112ce1bsalomon
126762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    if (context->caps()->maxSampleCount() >= 4) {
12702a44a488605112aa6683c9d919e13b188112ce1bsalomon        // An RT with a different sample count should not share.
12802a44a488605112aa6683c9d919e13b188112ce1bsalomon        GrSurfaceDesc smallMSAADesc = smallDesc;
12902a44a488605112aa6683c9d919e13b188112ce1bsalomon        smallMSAADesc.fSampleCnt = 4;
130d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        SkAutoTUnref<GrTexture> smallMSAART0(cache->createTexture(smallMSAADesc, false));
1316bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        if (smallMSAART0 && smallMSAART0->asRenderTarget()) {
1328dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel            smallMSAART0->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
1336bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        }
134b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#ifdef SK_BUILD_FOR_ANDROID
135b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon        if (!smallMSAART0) {
136b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon            // The nexus player seems to fail to create MSAA textures.
137b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon            return;
138b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon        }
139b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#endif
1406bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        REPORTER_ASSERT(reporter,
1416bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon                        smallRT0 && smallMSAART0 &&
1426bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon                        smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() &&
1438dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallRT0->asRenderTarget()->renderTargetPriv().getStencilAttachment() !=
1448dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilAttachment());
14502a44a488605112aa6683c9d919e13b188112ce1bsalomon        // A second MSAA RT should share with the first MSAA RT.
146d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        SkAutoTUnref<GrTexture> smallMSAART1(cache->createTexture(smallMSAADesc, false));
1476bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
1488dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel            smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
1496bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        }
1506bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        REPORTER_ASSERT(reporter,
1516bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon                        smallMSAART0 && smallMSAART1 &&
1526bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon                        smallMSAART0->asRenderTarget() &&
1536bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon                        smallMSAART1->asRenderTarget() &&
1548dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilAttachment() ==
1558dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilAttachment());
15602a44a488605112aa6683c9d919e13b188112ce1bsalomon        // But not one with a larger sample count should not. (Also check that the request for 4
15702a44a488605112aa6683c9d919e13b188112ce1bsalomon        // samples didn't get rounded up to >= 8 or else they could share.).
158762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon        if (context->caps()->maxSampleCount() >= 8 &&
159762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon            smallMSAART0 && smallMSAART0->asRenderTarget() &&
160dded69693dd3779f081326cde24c3954505b129dvbuzinov            smallMSAART0->asRenderTarget()->numColorSamples() < 8) {
16102a44a488605112aa6683c9d919e13b188112ce1bsalomon            smallMSAADesc.fSampleCnt = 8;
162d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon            smallMSAART1.reset(cache->createTexture(smallMSAADesc, false));
163d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon            SkAutoTUnref<GrTexture> smallMSAART1(cache->createTexture(smallMSAADesc, false));
1646bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon            if (smallMSAART1 && smallMSAART1->asRenderTarget()) {
1658dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilAttachment();
1666bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon            }
1676bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon            REPORTER_ASSERT(reporter,
1688dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART0 && smallMSAART1 &&
1698dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART0->asRenderTarget() &&
1708dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART1->asRenderTarget() &&
1718dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilAttachment() !=
1728dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel                        smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilAttachment());
17302a44a488605112aa6683c9d919e13b188112ce1bsalomon        }
17402a44a488605112aa6683c9d919e13b188112ce1bsalomon    }
17502a44a488605112aa6683c9d919e13b188112ce1bsalomon}
17602a44a488605112aa6683c9d919e13b188112ce1bsalomon
1776dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomonstatic void test_wrapped_resources(skiatest::Reporter* reporter, GrContext* context) {
178672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    const GrGpu* gpu = context->getGpu();
179eeb8d99b4e58eb95cad3f7cd5438b9c2b3db7141jvanverth    // this test is only valid for GL
180eeb8d99b4e58eb95cad3f7cd5438b9c2b3db7141jvanverth    if (!gpu || !gpu->glContextForTesting()) {
1816dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon        return;
1826dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    }
1836dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
184672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth    GrBackendObject texIDs[2];
1856dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    static const int kW = 100;
1866dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    static const int kH = 100;
187672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
188889579287770ba35156a73aa02d9ef5d2313c490jvanverth    texIDs[0] = gpu->createTestingOnlyBackendTexture(NULL, kW, kH, kRGBA_8888_GrPixelConfig);
189889579287770ba35156a73aa02d9ef5d2313c490jvanverth    texIDs[1] = gpu->createTestingOnlyBackendTexture(NULL, kW, kH, kRGBA_8888_GrPixelConfig);
190672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth
1916dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    context->resetContext();
1926dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
1936dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    GrBackendTextureDesc desc;
1946dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    desc.fConfig = kBGRA_8888_GrPixelConfig;
1956dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    desc.fWidth = kW;
1966dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    desc.fHeight = kH;
1976dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
1986dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    desc.fTextureHandle = texIDs[0];
1996dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    SkAutoTUnref<GrTexture> borrowed(context->textureProvider()->wrapBackendTexture(
2003e5f55542cbd23f1ad448cac3d29e8551204552cjvanverth                                     desc, kBorrow_GrWrapOwnership));
2016dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2026dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    desc.fTextureHandle = texIDs[1];
2036dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    SkAutoTUnref<GrTexture> adopted(context->textureProvider()->wrapBackendTexture(
2043e5f55542cbd23f1ad448cac3d29e8551204552cjvanverth                                    desc, kAdopt_GrWrapOwnership));
2056dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2066dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    REPORTER_ASSERT(reporter, SkToBool(borrowed) && SkToBool(adopted));
2076dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    if (!SkToBool(borrowed) || !SkToBool(adopted)) {
2086dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon        return;
2096dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    }
2106dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2116dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    borrowed.reset(NULL);
2126dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    adopted.reset(NULL);
2136dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2146dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    context->flush();
2156dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
216889579287770ba35156a73aa02d9ef5d2313c490jvanverth    bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(texIDs[0]);
217889579287770ba35156a73aa02d9ef5d2313c490jvanverth    bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(texIDs[1]);
2186dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2196dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    REPORTER_ASSERT(reporter, borrowedIsAlive);
2206dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    REPORTER_ASSERT(reporter, !adoptedIsAlive);
2216dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
222889579287770ba35156a73aa02d9ef5d2313c490jvanverth    gpu->deleteTestingOnlyBackendTexture(texIDs[0]);
2236dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2246dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    context->resetContext();
2256dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon}
2266dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon
2276d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomonclass TestResource : public GrGpuResource {
22811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    static const size_t kDefaultSize = 100;
2291c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    enum ScratchConstructor { kScratchConstructor };
230c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgpublic:
2312766c00fc0b6a07d46e5f74cdad45da2ef625237mtklein
2321c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    /** Property that distinctly categorizes the resource.
2331c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon     * For example, textures have width, height, ... */
23423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };
2351c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
2365236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle)
2375236cf480daf82b2f36e42795abdbbc915533a59bsalomon        : INHERITED(gpu, lifeCycle)
2385236cf480daf82b2f36e42795abdbbc915533a59bsalomon        , fToDelete(NULL)
2391c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fSize(size)
24023e619cf462b2a8a500f3ca750e099f79601f508bsalomon        , fProperty(kA_SimulatedProperty) {
2415236cf480daf82b2f36e42795abdbbc915533a59bsalomon        ++fNumAlive;
2425236cf480daf82b2f36e42795abdbbc915533a59bsalomon        this->registerWithCache();
2435236cf480daf82b2f36e42795abdbbc915533a59bsalomon    }
2445236cf480daf82b2f36e42795abdbbc915533a59bsalomon
2455236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle)
2465236cf480daf82b2f36e42795abdbbc915533a59bsalomon        : INHERITED(gpu, lifeCycle)
247dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon        , fToDelete(NULL)
2481c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fSize(kDefaultSize)
24923e619cf462b2a8a500f3ca750e099f79601f508bsalomon        , fProperty(kA_SimulatedProperty) {
250dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon        ++fNumAlive;
251dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon        this->registerWithCache();
252dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    }
253dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
2548b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    TestResource(GrGpu* gpu)
2555236cf480daf82b2f36e42795abdbbc915533a59bsalomon        : INHERITED(gpu, kCached_LifeCycle)
25611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        , fToDelete(NULL)
2571c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fSize(kDefaultSize)
25823e619cf462b2a8a500f3ca750e099f79601f508bsalomon        , fProperty(kA_SimulatedProperty) {
2598b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        ++fNumAlive;
2608b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        this->registerWithCache();
2618b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    }
2628b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
26323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    static TestResource* CreateScratch(GrGpu* gpu, SimulatedProperty property, bool cached = true) {
264c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor));
265c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    }
266c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
267c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    ~TestResource() {
268334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon        --fNumAlive;
26971cb0c241e439b6ed746b90294d0b6916644a644bsalomon        SkSafeUnref(fToDelete);
270c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    }
271c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
27211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    void setSize(size_t size) {
27311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        fSize = size;
27411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        this->didChangeGpuMemorySize();
27511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    }
27611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
277334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    static int NumAlive() { return fNumAlive; }
278c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
27971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    void setUnrefWhenDestroyed(TestResource* resource) {
28071cb0c241e439b6ed746b90294d0b6916644a644bsalomon        SkRefCnt_SafeAssign(fToDelete, resource);
281c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    }
282c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
2831c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) {
2841c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType();
2851c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt);
28624db3b1c35fb935660229da164fc5ad31977387fbsalomon        for (int i = 0; i < kScratchKeyFieldCnt; ++i) {
28724db3b1c35fb935660229da164fc5ad31977387fbsalomon            builder[i] = static_cast<uint32_t>(i + property);
2881c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        }
2891c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    }
2901c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
2911c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    static size_t ExpectedScratchKeySize() {
2921c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
2931c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    }
2941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
295c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgprivate:
29624db3b1c35fb935660229da164fc5ad31977387fbsalomon    static const int kScratchKeyFieldCnt = 6;
2971c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
298c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
299c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        : INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
3001c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fToDelete(NULL)
3011c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fSize(kDefaultSize)
3021c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        , fProperty(property) {
3031c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        GrScratchKey scratchKey;
3041c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        ComputeScratchKey(fProperty, &scratchKey);
3051c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        this->setScratchKey(scratchKey);
3061c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        ++fNumAlive;
3071c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon        this->registerWithCache();
3081c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    }
3091c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
31036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    size_t onGpuMemorySize() const override { return fSize; }
31169ed47f42d4877c178fdc0031cb01af2966ae235bsalomon
312c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    TestResource* fToDelete;
31311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    size_t fSize;
314334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    static int fNumAlive;
3151c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    SimulatedProperty fProperty;
3166d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon    typedef GrGpuResource INHERITED;
317c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org};
318334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonint TestResource::fNumAlive = 0;
319c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
320c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonclass Mock {
321c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonpublic:
322c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock(int maxCnt, size_t maxBytes) {
323c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        fContext.reset(GrContext::CreateMockContext());
324c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        SkASSERT(fContext);
325c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        fContext->setResourceCacheLimits(maxCnt, maxBytes);
3260ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        GrResourceCache* cache = fContext->getResourceCache();
3270ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        cache->purgeAllUnlocked();
3280ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes());
32971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    }
330c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
3310ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache() { return fContext->getResourceCache(); }
332c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
333c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context() { return fContext; }
334c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
335c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonprivate:
336c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    SkAutoTUnref<GrContext> fContext;
337c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon};
338c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
339c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_no_key(skiatest::Reporter* reporter) {
340c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(10, 30000);
341c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
3420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
34371cb0c241e439b6ed746b90294d0b6916644a644bsalomon
34471cb0c241e439b6ed746b90294d0b6916644a644bsalomon    // Create a bunch of resources with no keys
3455236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
3465236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
3475236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
3485236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* d = SkNEW_ARGS(TestResource, (context->getGpu()));
34971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    a->setSize(11);
35071cb0c241e439b6ed746b90294d0b6916644a644bsalomon    b->setSize(12);
35171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    c->setSize(13);
35271cb0c241e439b6ed746b90294d0b6916644a644bsalomon    d->setSize(14);
35371cb0c241e439b6ed746b90294d0b6916644a644bsalomon
35471cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
3550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
35671cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() +
3570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              d->gpuMemorySize() == cache->getResourceBytes());
35871cb0c241e439b6ed746b90294d0b6916644a644bsalomon
35971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    // Should be safe to purge without deleting the resources since we still have refs.
3600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
36171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive());
36271cb0c241e439b6ed746b90294d0b6916644a644bsalomon
3638718aafec239c93485e45bbe8fed19d9a8def079bsalomon    // Since the resources have neither unique nor scratch keys, delete immediately upon unref.
36471cb0c241e439b6ed746b90294d0b6916644a644bsalomon
36571cb0c241e439b6ed746b90294d0b6916644a644bsalomon    a->unref();
36671cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
3670ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
36871cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() ==
3690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
37071cb0c241e439b6ed746b90294d0b6916644a644bsalomon
37171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    c->unref();
37271cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
3730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
37471cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() ==
3750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
37671cb0c241e439b6ed746b90294d0b6916644a644bsalomon
37771cb0c241e439b6ed746b90294d0b6916644a644bsalomon    d->unref();
37871cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
3790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
3800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
38171cb0c241e439b6ed746b90294d0b6916644a644bsalomon
38271cb0c241e439b6ed746b90294d0b6916644a644bsalomon    b->unref();
38371cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
3840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
3850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
38671cb0c241e439b6ed746b90294d0b6916644a644bsalomon}
38771cb0c241e439b6ed746b90294d0b6916644a644bsalomon
38824db3b1c35fb935660229da164fc5ad31977387fbsalomon// Each integer passed as a template param creates a new domain.
3898718aafec239c93485e45bbe8fed19d9a8def079bsalomontemplate <int> static void make_unique_key(GrUniqueKey* key, int data) {
3908718aafec239c93485e45bbe8fed19d9a8def079bsalomon    static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain();
3918718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey::Builder builder(key, d, 1);
39224db3b1c35fb935660229da164fc5ad31977387fbsalomon    builder[0] = data;
39324db3b1c35fb935660229da164fc5ad31977387fbsalomon}
39424db3b1c35fb935660229da164fc5ad31977387fbsalomon
39584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomonstatic void test_budgeting(skiatest::Reporter* reporter) {
396c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(10, 300);
397c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
3980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
399dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
4008718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey uniqueKey;
4018718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&uniqueKey, 0);
402dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
4038718aafec239c93485e45bbe8fed19d9a8def079bsalomon    // Create a scratch, a unique, and a wrapped resource
4041c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    TestResource* scratch =
40523e619cf462b2a8a500f3ca750e099f79601f508bsalomon            TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
406dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    scratch->setSize(10);
4078718aafec239c93485e45bbe8fed19d9a8def079bsalomon    TestResource* unique = SkNEW_ARGS(TestResource, (context->getGpu()));
4088718aafec239c93485e45bbe8fed19d9a8def079bsalomon    unique->setSize(11);
409f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    unique->resourcePriv().setUniqueKey(uniqueKey);
4105236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* wrapped = SkNEW_ARGS(TestResource,
4116dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon                                       (context->getGpu(), GrGpuResource::kBorrowed_LifeCycle));
4125236cf480daf82b2f36e42795abdbbc915533a59bsalomon    wrapped->setSize(12);
4135236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* unbudgeted = SkNEW_ARGS(TestResource,
4145236cf480daf82b2f36e42795abdbbc915533a59bsalomon                                          (context->getGpu(), GrGpuResource::kUncached_LifeCycle));
41584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    unbudgeted->setSize(13);
416dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
4178718aafec239c93485e45bbe8fed19d9a8def079bsalomon    // Make sure we can't add a unique key to the wrapped resource
4188718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey uniqueKey2;
4198718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&uniqueKey2, 1);
420f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    wrapped->resourcePriv().setUniqueKey(uniqueKey2);
4218718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, NULL == cache->findAndRefUniqueResource(uniqueKey2));
422dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
423dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    // Make sure sizes are as we expect
4240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
4258718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
42684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
4270ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
4280ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
4298718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
4300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getBudgetedResourceBytes());
431dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
43263c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon    // Our refs mean that the resources are non purgeable.
4330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
4340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 4 == cache->getResourceCount());
4358718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
43684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon                              wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() ==
4370ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
4380ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
4398718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() ==
4400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getBudgetedResourceBytes());
441dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
442dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    // Unreffing the wrapped resource should free it right away.
443dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    wrapped->unref();
4440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
4458718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() +
4460ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
447dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
44884c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    // Now try freeing the budgeted resources first
4496dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon    wrapped = SkNEW_ARGS(TestResource, (context->getGpu(), GrGpuResource::kBorrowed_LifeCycle));
450dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    scratch->setSize(12);
4518718aafec239c93485e45bbe8fed19d9a8def079bsalomon    unique->unref();
4520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
4530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
45484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() +
4550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              unbudgeted->gpuMemorySize() == cache->getResourceBytes());
4560ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
4570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes());
458dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
459dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    scratch->unref();
4600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
4610ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
46284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() ==
4630ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
4640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
4650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
466dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
467dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon    wrapped->unref();
4680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
4690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes());
4700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
4710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
47284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon
47384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    unbudgeted->unref();
4740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
4750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
4760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
4770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
478dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon}
479dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon
4805236cf480daf82b2f36e42795abdbbc915533a59bsalomonstatic void test_unbudgeted(skiatest::Reporter* reporter) {
481c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(10, 30000);
482c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
4830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
4845236cf480daf82b2f36e42795abdbbc915533a59bsalomon
4858718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey uniqueKey;
4868718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&uniqueKey, 0);
4875236cf480daf82b2f36e42795abdbbc915533a59bsalomon
4885236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* scratch;
4898718aafec239c93485e45bbe8fed19d9a8def079bsalomon    TestResource* unique;
4905236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* wrapped;
4915236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* unbudgeted;
4925236cf480daf82b2f36e42795abdbbc915533a59bsalomon
4935236cf480daf82b2f36e42795abdbbc915533a59bsalomon    // A large uncached or wrapped resource shouldn't evict anything.
49423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    scratch = TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
4955236cf480daf82b2f36e42795abdbbc915533a59bsalomon    scratch->setSize(10);
4965236cf480daf82b2f36e42795abdbbc915533a59bsalomon    scratch->unref();
4970ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
4980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes());
4990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
5000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes());
5015236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5028718aafec239c93485e45bbe8fed19d9a8def079bsalomon    unique = SkNEW_ARGS(TestResource, (context->getGpu()));
5038718aafec239c93485e45bbe8fed19d9a8def079bsalomon    unique->setSize(11);
504f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    unique->resourcePriv().setUniqueKey(uniqueKey);
5058718aafec239c93485e45bbe8fed19d9a8def079bsalomon    unique->unref();
5060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
5070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
5080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
5090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
5105236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    size_t large = 2 * cache->getResourceBytes();
5125236cf480daf82b2f36e42795abdbbc915533a59bsalomon    unbudgeted = SkNEW_ARGS(TestResource,
5135236cf480daf82b2f36e42795abdbbc915533a59bsalomon                            (context->getGpu(), large, GrGpuResource::kUncached_LifeCycle));
5140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
5150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
5160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
5170ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
5185236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5195236cf480daf82b2f36e42795abdbbc915533a59bsalomon    unbudgeted->unref();
5200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
5210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
5220ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
5230ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
5245236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5255236cf480daf82b2f36e42795abdbbc915533a59bsalomon    wrapped = SkNEW_ARGS(TestResource,
5266dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon                         (context->getGpu(), large, GrGpuResource::kBorrowed_LifeCycle));
5270ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
5280ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
5290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
5300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
5315236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5325236cf480daf82b2f36e42795abdbbc915533a59bsalomon    wrapped->unref();
5330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
5340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes());
5350ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
5360ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
5370ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon
5380ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
5390ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
5400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
5410ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
5420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
5435236cf480daf82b2f36e42795abdbbc915533a59bsalomon}
5445236cf480daf82b2f36e42795abdbbc915533a59bsalomon
5453582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon// This method can't be static because it needs to friended in GrGpuResource::CacheAccess.
5463582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomonvoid test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
5473582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) {
548c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(10, 300);
549c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
5500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
551c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
552c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    TestResource* resource =
55323e619cf462b2a8a500f3ca750e099f79601f508bsalomon        TestResource::CreateScratch(context->getGpu(), TestResource::kA_SimulatedProperty, false);
554c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrScratchKey key;
55523e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);
556c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
557c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    size_t size = resource->gpuMemorySize();
558c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    for (int i = 0; i < 2; ++i) {
559c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        // Since this resource is unbudgeted, it should not be reachable as scratch.
5603582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
561c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
5623582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon        REPORTER_ASSERT(reporter, !resource->resourcePriv().isBudgeted());
5630ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(key));
5640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
5650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
5660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
5670ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
568c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
569c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        // Once it is unrefed, it should become available as scratch.
570c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        resource->unref();
5710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
5720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
5730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
5740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
5750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key));
576c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        REPORTER_ASSERT(reporter, resource);
5773582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon        REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key);
578c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch());
5793582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon        REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
580c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
581c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        if (0 == i) {
582c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try
583c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            // the above tests again.
5843582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon            resource->resourcePriv().makeUnbudgeted();
585c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        } else {
586c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            // After the second time around, try removing the scratch key
5873582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon            resource->resourcePriv().removeScratchKey();
5880ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
5890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, size == cache->getResourceBytes());
5900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount());
5910ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes());
5923582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon            REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid());
593c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch());
5943582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon            REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted());
595c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
596c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            // now when it is unrefed it should die since it has no key.
597c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon            resource->unref();
5980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
5990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
6000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount());
6010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon            REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes());
602c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        }
6038b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    }
604c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon}
605c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon
606c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
607c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(5, 30000);
608c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
6090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
6108b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
6118b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    // Create two resources that have the same scratch key.
61223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* a = TestResource::CreateScratch(context->getGpu(),
61323e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
61423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* b = TestResource::CreateScratch(context->getGpu(),
61523e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
6168b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    a->setSize(11);
6178b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    b->setSize(12);
6181c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey1;
61923e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
6201c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Check for negative case consistency. (leaks upon test failure.)
6210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(scratchKey1));
6221c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
6231c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey;
62423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
6251c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
6260ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
627ac49acda520292b059bc37fd368dff912626c3d9bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
6280ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
6290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
63071cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() ==
6310ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon                              cache->getResourceBytes());
6328b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
63363c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon    // Our refs mean that the resources are non purgeable.
6340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
6358b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
6360ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
6378b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
6388b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    // Unref but don't purge
6398b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    a->unref();
6408b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    b->unref();
6418b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
6420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
6438b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
64463c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon    // Purge again. This time resources should be purgeable.
6450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
6468b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
6470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
6480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
6498b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon}
6508b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
65110e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_remove_scratch_key(skiatest::Reporter* reporter) {
652c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(5, 30000);
653c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
6540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
65510e23caea3106be125acea10a637789e5a15c728bsalomon
65610e23caea3106be125acea10a637789e5a15c728bsalomon    // Create two resources that have the same scratch key.
65723e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* a = TestResource::CreateScratch(context->getGpu(),
65823e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
65923e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* b = TestResource::CreateScratch(context->getGpu(),
66023e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
66110e23caea3106be125acea10a637789e5a15c728bsalomon    a->unref();
66210e23caea3106be125acea10a637789e5a15c728bsalomon    b->unref();
66310e23caea3106be125acea10a637789e5a15c728bsalomon
6641c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey;
6651c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Ensure that scratch key lookup is correct for negative case.
66623e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
6671c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // (following leaks upon test failure).
6680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
6691c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
6700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    // Scratch resources are registered with GrResourceCache just by existing. There are 2.
67123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
67210e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
6730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));)
6740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
67510e23caea3106be125acea10a637789e5a15c728bsalomon
67610e23caea3106be125acea10a637789e5a15c728bsalomon    // Find the first resource and remove its scratch key
67710e23caea3106be125acea10a637789e5a15c728bsalomon    GrGpuResource* find;
6780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    find = cache->findAndRefScratchResource(scratchKey);
6793582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    find->resourcePriv().removeScratchKey();
68010e23caea3106be125acea10a637789e5a15c728bsalomon    // It's still alive, but not cached by scratch key anymore
68110e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
6820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
6830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
68410e23caea3106be125acea10a637789e5a15c728bsalomon
68510e23caea3106be125acea10a637789e5a15c728bsalomon    // The cache should immediately delete it when it's unrefed since it isn't accessible.
68610e23caea3106be125acea10a637789e5a15c728bsalomon    find->unref();
68710e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
6880ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));)
6890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
69010e23caea3106be125acea10a637789e5a15c728bsalomon
69110e23caea3106be125acea10a637789e5a15c728bsalomon    // Repeat for the second resource.
6920ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    find = cache->findAndRefScratchResource(scratchKey);
6933582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    find->resourcePriv().removeScratchKey();
69410e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
6950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
6960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
69710e23caea3106be125acea10a637789e5a15c728bsalomon
69810e23caea3106be125acea10a637789e5a15c728bsalomon    // Should be able to call this multiple times with no problem.
6993582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon    find->resourcePriv().removeScratchKey();
70010e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
7010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
7020ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
70310e23caea3106be125acea10a637789e5a15c728bsalomon
70410e23caea3106be125acea10a637789e5a15c728bsalomon    find->unref();
70510e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
7060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));)
7070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
70810e23caea3106be125acea10a637789e5a15c728bsalomon}
70910e23caea3106be125acea10a637789e5a15c728bsalomon
7101c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomonstatic void test_scratch_key_consistency(skiatest::Reporter* reporter) {
711c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(5, 30000);
712c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
7130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
7141c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7151c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Create two resources that have the same scratch key.
71623e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* a = TestResource::CreateScratch(context->getGpu(),
71723e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
71823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* b = TestResource::CreateScratch(context->getGpu(),
71923e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kB_SimulatedProperty);
7201c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    a->unref();
7211c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    b->unref();
7221c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7231c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey;
7241c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Ensure that scratch key comparison and assignment is consistent.
7251c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey1;
72623e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1);
7271c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    GrScratchKey scratchKey2;
72823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2);
7291c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize());
7301c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2);
7311c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1);
7321c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    scratchKey = scratchKey1;
7331c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
7341c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey1 == scratchKey);
7351c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey == scratchKey1);
7361c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey2 != scratchKey);
7371c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey != scratchKey2);
7381c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    scratchKey = scratchKey2;
7391c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize());
7401c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey1 != scratchKey);
7411c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey != scratchKey1);
7421c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey2 == scratchKey);
7431c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, scratchKey == scratchKey2);
7441c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7451c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Ensure that scratch key lookup is correct for negative case.
74623e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
7471c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // (following leaks upon test failure).
7480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL);
7491c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7501c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    // Find the first resource with a scratch key and a copy of a scratch key.
75123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey);
7520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrGpuResource* find = cache->findAndRefScratchResource(scratchKey);
7531c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find != NULL);
7541c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    find->unref();
7551c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7561c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    scratchKey2 = scratchKey;
7570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    find = cache->findAndRefScratchResource(scratchKey2);
7581c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find != NULL);
7591c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find == a || find == b);
7601c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7610ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2);
7621c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find2 != NULL);
7631c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find2 == a || find2 == b);
7641c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    REPORTER_ASSERT(reporter, find2 != find);
7651c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    find2->unref();
7661c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    find->unref();
7671c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon}
7681c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon
7698718aafec239c93485e45bbe8fed19d9a8def079bsalomonstatic void test_duplicate_unique_key(skiatest::Reporter* reporter) {
770c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(5, 30000);
771c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
7720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
7738b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
7748718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key;
7758718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key, 0);
776334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon
7778718aafec239c93485e45bbe8fed19d9a8def079bsalomon    // Create two resources that we will attempt to register with the same unique key.
7785236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
7798b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    a->setSize(11);
78071cb0c241e439b6ed746b90294d0b6916644a644bsalomon
781f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Set key on resource a.
782f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    a->resourcePriv().setUniqueKey(key);
783f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
784f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    a->unref();
785f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon
786f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Make sure that redundantly setting a's key works.
787f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    a->resourcePriv().setUniqueKey(key);
788f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key));
789f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    a->unref();
790f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
791f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes());
792f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
793f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon
794f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Create resource b and set the same key. It should replace a's unique key cache entry.
795f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
796f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    b->setSize(12);
797f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    b->resourcePriv().setUniqueKey(key);
798f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key));
799f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    b->unref();
80071cb0c241e439b6ed746b90294d0b6916644a644bsalomon
801f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Still have two resources because a is still reffed.
8020ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
803f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes());
8048b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
8058b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
806f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    a->unref();
807f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Now a should be gone.
808f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
809f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes());
810f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
811f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon
812f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Now replace b with c, but make sure c can start with one unique key and change it to b's key.
813f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Also make b be unreffed when replacement occurs.
8148b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    b->unref();
815f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu()));
816f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    GrUniqueKey differentKey;
817f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    make_unique_key<0>(&differentKey, 1);
818f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->setSize(13);
819f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->resourcePriv().setUniqueKey(differentKey);
820f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
821f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes());
822f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
823f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // c replaces b and b should be immediately purged.
824f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->resourcePriv().setUniqueKey(key);
8250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
826f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
82771cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
82871cb0c241e439b6ed746b90294d0b6916644a644bsalomon
829f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // c shouldn't be purged because it is ref'ed.
8300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
8310ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
832f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
8338b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
8348b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
835f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Drop the ref on c, it should be kept alive because it has a unique key.
836f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->unref();
8370ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
838f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes());
83971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
84071cb0c241e439b6ed746b90294d0b6916644a644bsalomon
841f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    // Verify that we can find c, then remove its unique key. It should get purged immediately.
842f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key));
843f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->resourcePriv().removeUniqueKey();
844f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon    c->unref();
8450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
8460ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
8478b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
8488b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon}
8498b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
8508b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_purge_invalidated(skiatest::Reporter* reporter) {
851c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(5, 30000);
852c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
8530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
8548b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
8558718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key1, key2, key3;
8568718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key1, 1);
8578718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key2, 2);
8588718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key3, 3);
8598b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
86023e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // Add three resources to the cache. Only c is usable as scratch.
8615236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
8625236cf480daf82b2f36e42795abdbbc915533a59bsalomon    TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
86323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource* c = TestResource::CreateScratch(context->getGpu(),
86423e619cf462b2a8a500f3ca750e099f79601f508bsalomon                                                  TestResource::kA_SimulatedProperty);
8658718aafec239c93485e45bbe8fed19d9a8def079bsalomon    a->resourcePriv().setUniqueKey(key1);
8668718aafec239c93485e45bbe8fed19d9a8def079bsalomon    b->resourcePriv().setUniqueKey(key2);
8678718aafec239c93485e45bbe8fed19d9a8def079bsalomon    c->resourcePriv().setUniqueKey(key3);
868c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org    a->unref();
86923e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // hold b until *after* the message is sent.
8708b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    c->unref();
871c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
8728718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
8738718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
8748718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
875334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive());
87623e619cf462b2a8a500f3ca750e099f79601f508bsalomon
8778718aafec239c93485e45bbe8fed19d9a8def079bsalomon    typedef GrUniqueKeyInvalidatedMessage Msg;
8788718aafec239c93485e45bbe8fed19d9a8def079bsalomon    typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus;
87923e619cf462b2a8a500f3ca750e099f79601f508bsalomon
88023e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // Invalidate two of the three, they should be purged and no longer accessible via their keys.
88123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    Bus::Post(Msg(key1));
88223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    Bus::Post(Msg(key2));
8830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAsNeeded();
88423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // a should be deleted now, but we still have a ref on b.
8858718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
8868718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
88723e619cf462b2a8a500f3ca750e099f79601f508bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
8888718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3));
8898b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
8908b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    // Invalidate the third.
89123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    Bus::Post(Msg(key3));
8920ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAsNeeded();
89323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // we still have a ref on b, c should be recycled as scratch.
89423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
8958718aafec239c93485e45bbe8fed19d9a8def079bsalomon    REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3));
89671cb0c241e439b6ed746b90294d0b6916644a644bsalomon
89723e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // make b purgeable. It should be immediately deleted since it has no key.
89823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    b->unref();
89923e619cf462b2a8a500f3ca750e099f79601f508bsalomon    REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive());
90023e619cf462b2a8a500f3ca750e099f79601f508bsalomon
90123e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // Make sure we actually get to c via it's scratch key, before we say goodbye.
90223e619cf462b2a8a500f3ca750e099f79601f508bsalomon    GrScratchKey scratchKey;
90323e619cf462b2a8a500f3ca750e099f79601f508bsalomon    TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey);
9040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey);
90523e619cf462b2a8a500f3ca750e099f79601f508bsalomon    REPORTER_ASSERT(reporter, scratch == c);
90623e619cf462b2a8a500f3ca750e099f79601f508bsalomon    SkSafeUnref(scratch);
90723e619cf462b2a8a500f3ca750e099f79601f508bsalomon
90823e619cf462b2a8a500f3ca750e099f79601f508bsalomon    // Get rid of c.
9090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
9100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    scratch = cache->findAndRefScratchResource(scratchKey);
91171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
9120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
9130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes());
91423e619cf462b2a8a500f3ca750e099f79601f508bsalomon    REPORTER_ASSERT(reporter, !scratch);
91523e619cf462b2a8a500f3ca750e099f79601f508bsalomon    SkSafeUnref(scratch);
916c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org}
917c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org
91871cb0c241e439b6ed746b90294d0b6916644a644bsalomonstatic void test_cache_chained_purge(skiatest::Reporter* reporter) {
919c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(3, 30000);
920c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
9210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
9228b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
9238718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key1, key2;
9248718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key1, 1);
9258718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key2, 2);
926bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org
927334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon
928c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
929c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
9308718aafec239c93485e45bbe8fed19d9a8def079bsalomon    a->resourcePriv().setUniqueKey(key1);
9318718aafec239c93485e45bbe8fed19d9a8def079bsalomon    b->resourcePriv().setUniqueKey(key2);
93271cb0c241e439b6ed746b90294d0b6916644a644bsalomon
933c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    // Make a cycle
934c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    a->setUnrefWhenDestroyed(b);
935c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    b->setUnrefWhenDestroyed(a);
936334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon
937c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
938334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon
939c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    a->unref();
940c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    b->unref();
9418b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
942c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
9438b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon
9440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
945c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
946f21dab95405979a4aff9f6a741c818304a67f220bsalomon
947c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    // Break the cycle
948c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    a->setUnrefWhenDestroyed(NULL);
949c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive());
950ac49acda520292b059bc37fd368dff912626c3d9bsalomon
9510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
952c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive());
953bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org}
954bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org
9558b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_resource_size_changed(skiatest::Reporter* reporter) {
9568718aafec239c93485e45bbe8fed19d9a8def079bsalomon    GrUniqueKey key1, key2;
9578718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key1, 1);
9588718aafec239c93485e45bbe8fed19d9a8def079bsalomon    make_unique_key<0>(&key2, 2);
95911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
96011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    // Test changing resources sizes (both increase & decrease).
96111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    {
962c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        Mock mock(3, 30000);
963c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        GrContext* context = mock.context();
9640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        GrResourceCache* cache = mock.cache();
96511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
9665236cf480daf82b2f36e42795abdbbc915533a59bsalomon        TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
9678718aafec239c93485e45bbe8fed19d9a8def079bsalomon        a->resourcePriv().setUniqueKey(key1);
96811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        a->unref();
96911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
9705236cf480daf82b2f36e42795abdbbc915533a59bsalomon        TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
9718718aafec239c93485e45bbe8fed19d9a8def079bsalomon        b->resourcePriv().setUniqueKey(key2);
97211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        b->unref();
97311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
9740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
9750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
9768b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        {
9778718aafec239c93485e45bbe8fed19d9a8def079bsalomon            SkAutoTUnref<TestResource> find2(
9788718aafec239c93485e45bbe8fed19d9a8def079bsalomon                static_cast<TestResource*>(cache->findAndRefUniqueResource(key2)));
9798b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon            find2->setSize(200);
9808718aafec239c93485e45bbe8fed19d9a8def079bsalomon            SkAutoTUnref<TestResource> find1(
9818718aafec239c93485e45bbe8fed19d9a8def079bsalomon                static_cast<TestResource*>(cache->findAndRefUniqueResource(key1)));
9828b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon            find1->setSize(50);
9838b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        }
98411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
9850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes());
9860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
98711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    }
98811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
98911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    // Test increasing a resources size beyond the cache budget.
99011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    {
991c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        Mock mock(2, 300);
992c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon        GrContext* context = mock.context();
9930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        GrResourceCache* cache = mock.cache();
99411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
9955236cf480daf82b2f36e42795abdbbc915533a59bsalomon        TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu()));
9968b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        a->setSize(100);
9978718aafec239c93485e45bbe8fed19d9a8def079bsalomon        a->resourcePriv().setUniqueKey(key1);
99811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        a->unref();
99911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
10005236cf480daf82b2f36e42795abdbbc915533a59bsalomon        TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu()));
10018b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        b->setSize(100);
10028718aafec239c93485e45bbe8fed19d9a8def079bsalomon        b->resourcePriv().setUniqueKey(key2);
100311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org        b->unref();
100411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
10050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes());
10060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 2 == cache->getResourceCount());
100711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
10088b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        {
10098718aafec239c93485e45bbe8fed19d9a8def079bsalomon            SkAutoTUnref<TestResource> find2(static_cast<TestResource*>(
10108718aafec239c93485e45bbe8fed19d9a8def079bsalomon                cache->findAndRefUniqueResource(key2)));
10118b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon            find2->setSize(201);
10128b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon        }
10138718aafec239c93485e45bbe8fed19d9a8def079bsalomon        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
101411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
10150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes());
10160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
101711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org    }
101811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org}
101911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org
1020ddf30e64fe474847b204d7062fad3341d245062cbsalomonstatic void test_timestamp_wrap(skiatest::Reporter* reporter) {
1021ddf30e64fe474847b204d7062fad3341d245062cbsalomon    static const int kCount = 50;
1022ddf30e64fe474847b204d7062fad3341d245062cbsalomon    static const int kBudgetCnt = kCount / 2;
1023ddf30e64fe474847b204d7062fad3341d245062cbsalomon    static const int kLockedFreq = 8;
1024ddf30e64fe474847b204d7062fad3341d245062cbsalomon    static const int kBudgetSize = 0x80000000;
1025ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1026ddf30e64fe474847b204d7062fad3341d245062cbsalomon    SkRandom random;
1027ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1028ddf30e64fe474847b204d7062fad3341d245062cbsalomon    // Run the test 2*kCount times;
1029ddf30e64fe474847b204d7062fad3341d245062cbsalomon    for (int i = 0; i < 2 * kCount; ++i ) {
1030ddf30e64fe474847b204d7062fad3341d245062cbsalomon        Mock mock(kBudgetCnt, kBudgetSize);
1031ddf30e64fe474847b204d7062fad3341d245062cbsalomon        GrContext* context = mock.context();
1032ddf30e64fe474847b204d7062fad3341d245062cbsalomon        GrResourceCache* cache = mock.cache();
1033ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1034ddf30e64fe474847b204d7062fad3341d245062cbsalomon        // Pick a random number of resources to add before the timestamp will wrap.
1035ddf30e64fe474847b204d7062fad3341d245062cbsalomon        cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1));
1036ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1037ddf30e64fe474847b204d7062fad3341d245062cbsalomon        static const int kNumToPurge = kCount - kBudgetCnt;
1038ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1039ddf30e64fe474847b204d7062fad3341d245062cbsalomon        SkTDArray<int> shouldPurgeIdxs;
1040ddf30e64fe474847b204d7062fad3341d245062cbsalomon        int purgeableCnt = 0;
1041ddf30e64fe474847b204d7062fad3341d245062cbsalomon        SkTDArray<GrGpuResource*> resourcesToUnref;
1042ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1043ddf30e64fe474847b204d7062fad3341d245062cbsalomon        // Add kCount resources, holding onto resources at random so we have a mix of purgeable and
1044ddf30e64fe474847b204d7062fad3341d245062cbsalomon        // unpurgeable resources.
1045ddf30e64fe474847b204d7062fad3341d245062cbsalomon        for (int j = 0; j < kCount; ++j) {
1046ddf30e64fe474847b204d7062fad3341d245062cbsalomon            GrUniqueKey key;
1047ddf30e64fe474847b204d7062fad3341d245062cbsalomon            make_unique_key<0>(&key, j);
1048ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1049ddf30e64fe474847b204d7062fad3341d245062cbsalomon            TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu()));
1050ddf30e64fe474847b204d7062fad3341d245062cbsalomon            r->resourcePriv().setUniqueKey(key);
1051ddf30e64fe474847b204d7062fad3341d245062cbsalomon            if (random.nextU() % kLockedFreq) {
1052ddf30e64fe474847b204d7062fad3341d245062cbsalomon                // Make this is purgeable.
1053ddf30e64fe474847b204d7062fad3341d245062cbsalomon                r->unref();
1054ddf30e64fe474847b204d7062fad3341d245062cbsalomon                ++purgeableCnt;
1055ddf30e64fe474847b204d7062fad3341d245062cbsalomon                if (purgeableCnt <= kNumToPurge) {
1056ddf30e64fe474847b204d7062fad3341d245062cbsalomon                    *shouldPurgeIdxs.append() = j;
1057ddf30e64fe474847b204d7062fad3341d245062cbsalomon                }
1058ddf30e64fe474847b204d7062fad3341d245062cbsalomon            } else {
1059ddf30e64fe474847b204d7062fad3341d245062cbsalomon                *resourcesToUnref.append() = r;
1060ddf30e64fe474847b204d7062fad3341d245062cbsalomon            }
1061ddf30e64fe474847b204d7062fad3341d245062cbsalomon        }
1062ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1063ddf30e64fe474847b204d7062fad3341d245062cbsalomon        // Verify that the correct resources were purged.
1064ddf30e64fe474847b204d7062fad3341d245062cbsalomon        int currShouldPurgeIdx = 0;
1065ddf30e64fe474847b204d7062fad3341d245062cbsalomon        for (int j = 0; j < kCount; ++j) {
1066ddf30e64fe474847b204d7062fad3341d245062cbsalomon            GrUniqueKey key;
1067ddf30e64fe474847b204d7062fad3341d245062cbsalomon            make_unique_key<0>(&key, j);
1068ddf30e64fe474847b204d7062fad3341d245062cbsalomon            GrGpuResource* res = cache->findAndRefUniqueResource(key);
1069ddf30e64fe474847b204d7062fad3341d245062cbsalomon            if (currShouldPurgeIdx < shouldPurgeIdxs.count() &&
1070ddf30e64fe474847b204d7062fad3341d245062cbsalomon                shouldPurgeIdxs[currShouldPurgeIdx] == j) {
1071ddf30e64fe474847b204d7062fad3341d245062cbsalomon                ++currShouldPurgeIdx;
1072ddf30e64fe474847b204d7062fad3341d245062cbsalomon                REPORTER_ASSERT(reporter, NULL == res);
1073ddf30e64fe474847b204d7062fad3341d245062cbsalomon            } else {
1074ddf30e64fe474847b204d7062fad3341d245062cbsalomon                REPORTER_ASSERT(reporter, NULL != res);
1075ddf30e64fe474847b204d7062fad3341d245062cbsalomon            }
1076ddf30e64fe474847b204d7062fad3341d245062cbsalomon            SkSafeUnref(res);
1077ddf30e64fe474847b204d7062fad3341d245062cbsalomon        }
1078ddf30e64fe474847b204d7062fad3341d245062cbsalomon
1079ddf30e64fe474847b204d7062fad3341d245062cbsalomon        for (int j = 0; j < resourcesToUnref.count(); ++j) {
1080ddf30e64fe474847b204d7062fad3341d245062cbsalomon            resourcesToUnref[j]->unref();
1081ddf30e64fe474847b204d7062fad3341d245062cbsalomon        }
1082ddf30e64fe474847b204d7062fad3341d245062cbsalomon    }
1083ddf30e64fe474847b204d7062fad3341d245062cbsalomon}
1084ddf30e64fe474847b204d7062fad3341d245062cbsalomon
10853f324321cdd8fde7976d958e2888a1ec4e657e35bsalomonstatic void test_flush(skiatest::Reporter* reporter) {
10863f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    Mock mock(1000000, 1000000);
10873f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    GrContext* context = mock.context();
10883f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    GrResourceCache* cache = mock.cache();
10893f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
10903f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    // The current cache impl will round the max flush count to the next power of 2. So we choose a
10913f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    // power of two here to keep things simpler.
10923f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    static const int kFlushCount = 16;
10933f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    cache->setLimits(1000000, 1000000, kFlushCount);
10943f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
10953f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    {
10963f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        // Insert a resource and send a flush notification kFlushCount times.
10973f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount; ++i) {
10983f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu()));
10993f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            GrUniqueKey k;
11003f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            make_unique_key<1>(&k, i);
11013f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            r->resourcePriv().setUniqueKey(k);
11023f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            r->unref();
11033f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            cache->notifyFlushOccurred();
11043f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11053f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11063f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        // Send flush notifications to the cache. Each flush should purge the oldest resource.
11073f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount - 1; ++i) {
11083f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            // The first resource was purged after the last flush in the initial loop, hence the -1.
11093f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount());
11103f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            for (int j = 0; j < i; ++j) {
11113f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                GrUniqueKey k;
11123f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                make_unique_key<1>(&k, j);
11133f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                GrGpuResource* r = cache->findAndRefUniqueResource(k);
11143f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                REPORTER_ASSERT(reporter, !SkToBool(r));
11153f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                SkSafeUnref(r);
11163f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            }
11173f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            cache->notifyFlushOccurred();
11183f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11193f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11203f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
11213f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        cache->purgeAllUnlocked();
11223f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    }
11233f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11243f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    // Do a similar test but where we leave refs on some resources to prevent them from being
11253f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    // purged.
11263f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    {
11273f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        GrGpuResource* refedResources[kFlushCount >> 1];
11283f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount; ++i) {
11293f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu()));
11303f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            GrUniqueKey k;
11313f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            make_unique_key<1>(&k, i);
11323f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            r->resourcePriv().setUniqueKey(k);
11333f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            // Leave a ref on every other resource, beginning with the first.
11343f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            if (SkToBool(i & 0x1)) {
11353f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                refedResources[i/2] = r;
11363f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            } else {
11373f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon                r->unref();
11383f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            }
11393f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            cache->notifyFlushOccurred();
11403f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11413f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11423f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount; ++i) {
11433f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            // Should get a resource purged every other flush.
11443f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount());
11453f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            cache->notifyFlushOccurred();
11463f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11473f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11483f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        // Unref all the resources that we kept refs on in the first loop.
11493f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount >> 1; ++i) {
11503f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            refedResources[i]->unref();
11513f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11523f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11533f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        // When we unref'ed them their timestamps got updated. So nothing should be purged until we
11543f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        // get kFlushCount additional flushes. Then everything should be purged.
11553f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        for (int i = 0; i < kFlushCount; ++i) {
11563f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount());
11573f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon            cache->notifyFlushOccurred();
11583f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        }
11593f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
11603f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11613f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon        cache->purgeAllUnlocked();
11623f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    }
11633f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
11643f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    REPORTER_ASSERT(reporter, 0 == cache->getResourceCount());
11653f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon}
11663f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon
116710e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_large_resource_count(skiatest::Reporter* reporter) {
116810e23caea3106be125acea10a637789e5a15c728bsalomon    // Set the cache size to double the resource count because we're going to create 2x that number
116910e23caea3106be125acea10a637789e5a15c728bsalomon    // resources, using two different key domains. Add a little slop to the bytes because we resize
117010e23caea3106be125acea10a637789e5a15c728bsalomon    // down to 1 byte after creating the resource.
1171c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    static const int kResourceCnt = 2000;
117210e23caea3106be125acea10a637789e5a15c728bsalomon
1173c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000);
1174c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    GrContext* context = mock.context();
11750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    GrResourceCache* cache = mock.cache();
117610e23caea3106be125acea10a637789e5a15c728bsalomon
117710e23caea3106be125acea10a637789e5a15c728bsalomon    for (int i = 0; i < kResourceCnt; ++i) {
11788718aafec239c93485e45bbe8fed19d9a8def079bsalomon        GrUniqueKey key1, key2;
11798718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<1>(&key1, i);
11808718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<2>(&key2, i);
118124db3b1c35fb935660229da164fc5ad31977387fbsalomon
118210e23caea3106be125acea10a637789e5a15c728bsalomon        TestResource* resource;
118310e23caea3106be125acea10a637789e5a15c728bsalomon
118410e23caea3106be125acea10a637789e5a15c728bsalomon        resource = SkNEW_ARGS(TestResource, (context->getGpu()));
11858718aafec239c93485e45bbe8fed19d9a8def079bsalomon        resource->resourcePriv().setUniqueKey(key1);
118610e23caea3106be125acea10a637789e5a15c728bsalomon        resource->setSize(1);
118710e23caea3106be125acea10a637789e5a15c728bsalomon        resource->unref();
118810e23caea3106be125acea10a637789e5a15c728bsalomon
118910e23caea3106be125acea10a637789e5a15c728bsalomon        resource = SkNEW_ARGS(TestResource, (context->getGpu()));
11908718aafec239c93485e45bbe8fed19d9a8def079bsalomon        resource->resourcePriv().setUniqueKey(key2);
119110e23caea3106be125acea10a637789e5a15c728bsalomon        resource->setSize(1);
119210e23caea3106be125acea10a637789e5a15c728bsalomon        resource->unref();
119310e23caea3106be125acea10a637789e5a15c728bsalomon    }
119410e23caea3106be125acea10a637789e5a15c728bsalomon
119510e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt);
11960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt);
11970ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt);
11980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt);
11990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt);
120010e23caea3106be125acea10a637789e5a15c728bsalomon    for (int i = 0; i < kResourceCnt; ++i) {
12018718aafec239c93485e45bbe8fed19d9a8def079bsalomon        GrUniqueKey key1, key2;
12028718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<1>(&key1, i);
12038718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<2>(&key2, i);
120424db3b1c35fb935660229da164fc5ad31977387fbsalomon
12058718aafec239c93485e45bbe8fed19d9a8def079bsalomon        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1));
12068718aafec239c93485e45bbe8fed19d9a8def079bsalomon        REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2));
120710e23caea3106be125acea10a637789e5a15c728bsalomon    }
120810e23caea3106be125acea10a637789e5a15c728bsalomon
12090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    cache->purgeAllUnlocked();
121010e23caea3106be125acea10a637789e5a15c728bsalomon    REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0);
12110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0);
12120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0);
12130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0);
12140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    REPORTER_ASSERT(reporter, cache->getResourceCount() == 0);
121510e23caea3106be125acea10a637789e5a15c728bsalomon
121610e23caea3106be125acea10a637789e5a15c728bsalomon    for (int i = 0; i < kResourceCnt; ++i) {
12178718aafec239c93485e45bbe8fed19d9a8def079bsalomon        GrUniqueKey key1, key2;
12188718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<1>(&key1, i);
12198718aafec239c93485e45bbe8fed19d9a8def079bsalomon        make_unique_key<2>(&key2, i);
122024db3b1c35fb935660229da164fc5ad31977387fbsalomon
12218718aafec239c93485e45bbe8fed19d9a8def079bsalomon        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1));
12228718aafec239c93485e45bbe8fed19d9a8def079bsalomon        REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2));
122310e23caea3106be125acea10a637789e5a15c728bsalomon    }
122410e23caea3106be125acea10a637789e5a15c728bsalomon}
122510e23caea3106be125acea10a637789e5a15c728bsalomon
1226c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////////
12274ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(ResourceCache, reporter, factory) {
1228c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
1229c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
1230c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        if (!GrContextFactory::IsRenderingGLContext(glType)) {
1231c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org            continue;
1232c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        }
1233c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        GrContext* context = factory->get(glType);
1234fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon        if (NULL == context) {
1235fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon            continue;
1236fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon        }
1237f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon        GrSurfaceDesc desc;
1238c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        desc.fConfig = kSkia8888_GrPixelConfig;
1239f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon        desc.fFlags = kRenderTarget_GrSurfaceFlag;
1240c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        desc.fWidth = gWidth;
1241c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org        desc.fHeight = gHeight;
124269f6f00fd975823e825c5aa0b1b8f4416e7c812breed        SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight);
1243afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon        SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context,
1244afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon                                                                   SkSurface::kNo_Budgeted, info));
1245fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon        test_cache(reporter, context, surface->getCanvas());
124602a44a488605112aa6683c9d919e13b188112ce1bsalomon        test_stencil_buffers(reporter, context);
12476dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon        test_wrapped_resources(reporter, context);
1248820dd6c335411aad889c1d7e8a857642ecd87e30bsalomon    }
1249334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon
12508b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    // The below tests create their own mock contexts.
125171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    test_no_key(reporter);
125284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon    test_budgeting(reporter);
12535236cf480daf82b2f36e42795abdbbc915533a59bsalomon    test_unbudgeted(reporter);
1254c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon    test_unbudgeted_to_scratch(reporter);
12558718aafec239c93485e45bbe8fed19d9a8def079bsalomon    test_duplicate_unique_key(reporter);
12568b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    test_duplicate_scratch_key(reporter);
125710e23caea3106be125acea10a637789e5a15c728bsalomon    test_remove_scratch_key(reporter);
12581c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon    test_scratch_key_consistency(reporter);
12598b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    test_purge_invalidated(reporter);
126071cb0c241e439b6ed746b90294d0b6916644a644bsalomon    test_cache_chained_purge(reporter);
12618b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon    test_resource_size_changed(reporter);
1262ddf30e64fe474847b204d7062fad3341d245062cbsalomon    test_timestamp_wrap(reporter);
12633f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    test_flush(reporter);
126410e23caea3106be125acea10a637789e5a15c728bsalomon    test_large_resource_count(reporter);
1265c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org}
1266c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org
1267c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#endif
1268