ResourceCacheTest.cpp revision 36352bf5e38f45a70ee4f4fc132a38048d38206d
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 8c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#if SK_SUPPORT_GPU 94ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org 10bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrContext.h" 11c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#include "GrContextFactory.h" 12bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrGpu.h" 133582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourceCacheAccess.h" 143582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 156bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTarget.h" 166bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h" 170ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h" 18bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "SkCanvas.h" 1971cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkGr.h" 2071cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkMessageBus.h" 2169f6f00fd975823e825c5aa0b1b8f4416e7c812breed#include "SkSurface.h" 224ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "Test.h" 23c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 24c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gWidth = 640; 25c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gHeight = 480; 26c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 27c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 28334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonstatic void test_cache(skiatest::Reporter* reporter, GrContext* context, SkCanvas* canvas) { 29c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org const SkIRect size = SkIRect::MakeWH(gWidth, gHeight); 30c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 31c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org SkBitmap src; 32deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org src.allocN32Pixels(size.width(), size.height()); 33c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org src.eraseColor(SK_ColorBLACK); 34c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t srcSize = src.getSize(); 35c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 3695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org size_t initialCacheSize; 3795c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->getResourceCacheUsage(NULL, &initialCacheSize); 38c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 39c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org int oldMaxNum; 40c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t oldMaxBytes; 4195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes); 4217f1ae63d57a3f3d3a0ae50e1b25b3f8b18fd328skia.committer@gmail.com 43c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // Set the cache limits so we can fit 10 "src" images and the 44c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // max number of textures doesn't matter 45c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t maxCacheSize = initialCacheSize + 10*srcSize; 4695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->setResourceCacheLimits(1000, maxCacheSize); 47c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 48c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org SkBitmap readback; 49deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org readback.allocN32Pixels(size.width(), size.height()); 50c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 51c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org for (int i = 0; i < 100; ++i) { 52c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org canvas->drawBitmap(src, 0, 0); 53c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org canvas->readPixels(size, &readback); 54c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 55c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // "modify" the src texture 56c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org src.notifyPixelsChanged(); 57c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 5895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org size_t curCacheSize; 5995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->getResourceCacheUsage(NULL, &curCacheSize); 60c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 61c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // we should never go over the size limit 62c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize); 63c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org } 64c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 6595c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->setResourceCacheLimits(oldMaxNum, oldMaxBytes); 66c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org} 67c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 6802a44a488605112aa6683c9d919e13b188112ce1bsalomonstatic void test_stencil_buffers(skiatest::Reporter* reporter, GrContext* context) { 6902a44a488605112aa6683c9d919e13b188112ce1bsalomon GrSurfaceDesc smallDesc; 7002a44a488605112aa6683c9d919e13b188112ce1bsalomon smallDesc.fFlags = kRenderTarget_GrSurfaceFlag; 7102a44a488605112aa6683c9d919e13b188112ce1bsalomon smallDesc.fConfig = kSkia8888_GrPixelConfig; 7202a44a488605112aa6683c9d919e13b188112ce1bsalomon smallDesc.fWidth = 4; 7302a44a488605112aa6683c9d919e13b188112ce1bsalomon smallDesc.fHeight = 4; 7402a44a488605112aa6683c9d919e13b188112ce1bsalomon smallDesc.fSampleCnt = 0; 7502a44a488605112aa6683c9d919e13b188112ce1bsalomon 7602a44a488605112aa6683c9d919e13b188112ce1bsalomon // Test that two budgeted RTs with the same desc share a stencil buffer. 7702a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> smallRT0(context->createTexture(smallDesc, true)); 786bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallRT0 && smallRT0->asRenderTarget()) { 796bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 806bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 816bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon 8202a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> smallRT1(context->createTexture(smallDesc, true)); 836bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallRT1 && smallRT1->asRenderTarget()) { 846bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT1->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 856bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 866bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon 8702a44a488605112aa6683c9d919e13b188112ce1bsalomon REPORTER_ASSERT(reporter, smallRT0 && smallRT1 && 8802a44a488605112aa6683c9d919e13b188112ce1bsalomon smallRT0->asRenderTarget() && smallRT1->asRenderTarget() && 896bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() == 906bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT1->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 9102a44a488605112aa6683c9d919e13b188112ce1bsalomon 9202a44a488605112aa6683c9d919e13b188112ce1bsalomon // An unbudgeted RT with the same desc should also share. 9302a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> smallRT2(context->createTexture(smallDesc, false)); 946bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallRT2 && smallRT2->asRenderTarget()) { 956bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT2->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 966bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 9702a44a488605112aa6683c9d919e13b188112ce1bsalomon REPORTER_ASSERT(reporter, smallRT0 && smallRT2 && 9802a44a488605112aa6683c9d919e13b188112ce1bsalomon smallRT0->asRenderTarget() && smallRT2->asRenderTarget() && 996bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() == 1006bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT2->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 10102a44a488605112aa6683c9d919e13b188112ce1bsalomon 10202a44a488605112aa6683c9d919e13b188112ce1bsalomon // An RT with a much larger size should not share. 10302a44a488605112aa6683c9d919e13b188112ce1bsalomon GrSurfaceDesc bigDesc; 10402a44a488605112aa6683c9d919e13b188112ce1bsalomon bigDesc.fFlags = kRenderTarget_GrSurfaceFlag; 10502a44a488605112aa6683c9d919e13b188112ce1bsalomon bigDesc.fConfig = kSkia8888_GrPixelConfig; 10602a44a488605112aa6683c9d919e13b188112ce1bsalomon bigDesc.fWidth = 400; 10702a44a488605112aa6683c9d919e13b188112ce1bsalomon bigDesc.fHeight = 200; 10802a44a488605112aa6683c9d919e13b188112ce1bsalomon bigDesc.fSampleCnt = 0; 10902a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> bigRT(context->createTexture(bigDesc, false)); 1106bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (bigRT && bigRT->asRenderTarget()) { 1116bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon bigRT->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 1126bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 11302a44a488605112aa6683c9d919e13b188112ce1bsalomon REPORTER_ASSERT(reporter, smallRT0 && bigRT && 11402a44a488605112aa6683c9d919e13b188112ce1bsalomon smallRT0->asRenderTarget() && bigRT->asRenderTarget() && 1156bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() != 1166bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon bigRT->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 11702a44a488605112aa6683c9d919e13b188112ce1bsalomon 11802a44a488605112aa6683c9d919e13b188112ce1bsalomon if (context->getMaxSampleCount() >= 4) { 11902a44a488605112aa6683c9d919e13b188112ce1bsalomon // An RT with a different sample count should not share. 12002a44a488605112aa6683c9d919e13b188112ce1bsalomon GrSurfaceDesc smallMSAADesc = smallDesc; 12102a44a488605112aa6683c9d919e13b188112ce1bsalomon smallMSAADesc.fSampleCnt = 4; 12202a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> smallMSAART0(context->createTexture(smallMSAADesc, false)); 1236bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallMSAART0 && smallMSAART0->asRenderTarget()) { 1246bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 1256bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 126b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#ifdef SK_BUILD_FOR_ANDROID 127b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon if (!smallMSAART0) { 128b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon // The nexus player seems to fail to create MSAA textures. 129b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon return; 130b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon } 131b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#endif 1326bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon REPORTER_ASSERT(reporter, 1336bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0 && smallMSAART0 && 1346bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget() && smallMSAART0->asRenderTarget() && 1356bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallRT0->asRenderTarget()->renderTargetPriv().getStencilBuffer() != 1366bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 13702a44a488605112aa6683c9d919e13b188112ce1bsalomon // A second MSAA RT should share with the first MSAA RT. 13802a44a488605112aa6683c9d919e13b188112ce1bsalomon SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false)); 1396bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallMSAART1 && smallMSAART1->asRenderTarget()) { 1406bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 1416bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 1426bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon REPORTER_ASSERT(reporter, 1436bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0 && smallMSAART1 && 1446bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget() && 1456bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget() && 1466bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() == 1476bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 14802a44a488605112aa6683c9d919e13b188112ce1bsalomon // But not one with a larger sample count should not. (Also check that the request for 4 14902a44a488605112aa6683c9d919e13b188112ce1bsalomon // samples didn't get rounded up to >= 8 or else they could share.). 15002a44a488605112aa6683c9d919e13b188112ce1bsalomon if (context->getMaxSampleCount() >= 8 && smallMSAART0 && smallMSAART0->asRenderTarget() && 15102a44a488605112aa6683c9d919e13b188112ce1bsalomon smallMSAART0->asRenderTarget()->numSamples() < 8) { 15202a44a488605112aa6683c9d919e13b188112ce1bsalomon smallMSAADesc.fSampleCnt = 8; 15302a44a488605112aa6683c9d919e13b188112ce1bsalomon smallMSAART1.reset(context->createTexture(smallMSAADesc, false)); 1546bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon SkAutoTUnref<GrTexture> smallMSAART1(context->createTexture(smallMSAADesc, false)); 1556bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon if (smallMSAART1 && smallMSAART1->asRenderTarget()) { 1566bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget()->renderTargetPriv().attachStencilBuffer(); 1576bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 1586bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon REPORTER_ASSERT(reporter, 1596bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0 && smallMSAART1 && 1606bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget() && 1616bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget() && 1626bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART0->asRenderTarget()->renderTargetPriv().getStencilBuffer() != 1636bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon smallMSAART1->asRenderTarget()->renderTargetPriv().getStencilBuffer()); 16402a44a488605112aa6683c9d919e13b188112ce1bsalomon } 16502a44a488605112aa6683c9d919e13b188112ce1bsalomon } 16602a44a488605112aa6683c9d919e13b188112ce1bsalomon} 16702a44a488605112aa6683c9d919e13b188112ce1bsalomon 1686d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomonclass TestResource : public GrGpuResource { 16911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org static const size_t kDefaultSize = 100; 1701c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon enum ScratchConstructor { kScratchConstructor }; 171c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgpublic: 172c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org SK_DECLARE_INST_COUNT(TestResource); 1731c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon /** Property that distinctly categorizes the resource. 1741c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon * For example, textures have width, height, ... */ 17523e619cf462b2a8a500f3ca750e099f79601f508bsalomon enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty }; 1761c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 1775236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle) 1785236cf480daf82b2f36e42795abdbbc915533a59bsalomon : INHERITED(gpu, lifeCycle) 1795236cf480daf82b2f36e42795abdbbc915533a59bsalomon , fToDelete(NULL) 1801c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(size) 18123e619cf462b2a8a500f3ca750e099f79601f508bsalomon , fProperty(kA_SimulatedProperty) { 1825236cf480daf82b2f36e42795abdbbc915533a59bsalomon ++fNumAlive; 1835236cf480daf82b2f36e42795abdbbc915533a59bsalomon this->registerWithCache(); 1845236cf480daf82b2f36e42795abdbbc915533a59bsalomon } 1855236cf480daf82b2f36e42795abdbbc915533a59bsalomon 1865236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle) 1875236cf480daf82b2f36e42795abdbbc915533a59bsalomon : INHERITED(gpu, lifeCycle) 188dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon , fToDelete(NULL) 1891c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(kDefaultSize) 19023e619cf462b2a8a500f3ca750e099f79601f508bsalomon , fProperty(kA_SimulatedProperty) { 191dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon ++fNumAlive; 192dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon this->registerWithCache(); 193dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon } 194dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 1958b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon TestResource(GrGpu* gpu) 1965236cf480daf82b2f36e42795abdbbc915533a59bsalomon : INHERITED(gpu, kCached_LifeCycle) 19711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org , fToDelete(NULL) 1981c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(kDefaultSize) 19923e619cf462b2a8a500f3ca750e099f79601f508bsalomon , fProperty(kA_SimulatedProperty) { 2008b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon ++fNumAlive; 2018b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon this->registerWithCache(); 2028b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 2038b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 20423e619cf462b2a8a500f3ca750e099f79601f508bsalomon static TestResource* CreateScratch(GrGpu* gpu, SimulatedProperty property, bool cached = true) { 205c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon return SkNEW_ARGS(TestResource, (gpu, property, cached, kScratchConstructor)); 206c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 207c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 208c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org ~TestResource() { 209334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon --fNumAlive; 21071cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkSafeUnref(fToDelete); 211c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 212c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 21311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void setSize(size_t size) { 21411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org fSize = size; 21511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org this->didChangeGpuMemorySize(); 21611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 21711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 218334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int NumAlive() { return fNumAlive; } 219c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 22071cb0c241e439b6ed746b90294d0b6916644a644bsalomon void setUnrefWhenDestroyed(TestResource* resource) { 22171cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkRefCnt_SafeAssign(fToDelete, resource); 222c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 223c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 2241c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) { 2251c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType(); 2261c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt); 22724db3b1c35fb935660229da164fc5ad31977387fbsalomon for (int i = 0; i < kScratchKeyFieldCnt; ++i) { 22824db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[i] = static_cast<uint32_t>(i + property); 2291c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2301c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2311c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 2321c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static size_t ExpectedScratchKeySize() { 2331c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt); 2341c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2351c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 236c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgprivate: 23724db3b1c35fb935660229da164fc5ad31977387fbsalomon static const int kScratchKeyFieldCnt = 6; 2381c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 239c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor) 240c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon : INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle) 2411c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fToDelete(NULL) 2421c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(kDefaultSize) 2431c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fProperty(property) { 2441c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 2451c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon ComputeScratchKey(fProperty, &scratchKey); 2461c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon this->setScratchKey(scratchKey); 2471c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon ++fNumAlive; 2481c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon this->registerWithCache(); 2491c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2501c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 25136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein size_t onGpuMemorySize() const override { return fSize; } 25269ed47f42d4877c178fdc0031cb01af2966ae235bsalomon 253c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org TestResource* fToDelete; 25411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org size_t fSize; 255334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int fNumAlive; 2561c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon SimulatedProperty fProperty; 2576d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon typedef GrGpuResource INHERITED; 258c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org}; 259334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonint TestResource::fNumAlive = 0; 260c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 261c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonclass Mock { 262c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonpublic: 263c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock(int maxCnt, size_t maxBytes) { 264c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon fContext.reset(GrContext::CreateMockContext()); 265c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon SkASSERT(fContext); 266c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon fContext->setResourceCacheLimits(maxCnt, maxBytes); 2670ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = fContext->getResourceCache(); 2680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 2690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes()); 27071cb0c241e439b6ed746b90294d0b6916644a644bsalomon } 271c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 2720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache() { return fContext->getResourceCache(); } 273c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 274c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context() { return fContext; } 275c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 276c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonprivate: 277c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon SkAutoTUnref<GrContext> fContext; 278c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon}; 279c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 280c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_no_key(skiatest::Reporter* reporter) { 281c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 282c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 2830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 28471cb0c241e439b6ed746b90294d0b6916644a644bsalomon 28571cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Create a bunch of resources with no keys 2865236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 2875236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 2885236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu())); 2895236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* d = SkNEW_ARGS(TestResource, (context->getGpu())); 29071cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->setSize(11); 29171cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->setSize(12); 29271cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->setSize(13); 29371cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->setSize(14); 29471cb0c241e439b6ed746b90294d0b6916644a644bsalomon 29571cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 2960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 29771cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() + 2980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon d->gpuMemorySize() == cache->getResourceBytes()); 29971cb0c241e439b6ed746b90294d0b6916644a644bsalomon 30071cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Should be safe to purge without deleting the resources since we still have refs. 3010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 30271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 30371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 3048718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Since the resources have neither unique nor scratch keys, delete immediately upon unref. 30571cb0c241e439b6ed746b90294d0b6916644a644bsalomon 30671cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->unref(); 30771cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 3080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 30971cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() == 3100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 31171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 31271cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->unref(); 31371cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 3140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 31571cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() == 3160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 31771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 31871cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->unref(); 31971cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 3200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 3210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 32271cb0c241e439b6ed746b90294d0b6916644a644bsalomon 32371cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->unref(); 32471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 3250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 3260ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 32771cb0c241e439b6ed746b90294d0b6916644a644bsalomon} 32871cb0c241e439b6ed746b90294d0b6916644a644bsalomon 32924db3b1c35fb935660229da164fc5ad31977387fbsalomon// Each integer passed as a template param creates a new domain. 3308718aafec239c93485e45bbe8fed19d9a8def079bsalomontemplate <int> static void make_unique_key(GrUniqueKey* key, int data) { 3318718aafec239c93485e45bbe8fed19d9a8def079bsalomon static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain(); 3328718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey::Builder builder(key, d, 1); 33324db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[0] = data; 33424db3b1c35fb935660229da164fc5ad31977387fbsalomon} 33524db3b1c35fb935660229da164fc5ad31977387fbsalomon 33684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomonstatic void test_budgeting(skiatest::Reporter* reporter) { 337c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 338c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 3390ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 340dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 3418718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 3428718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 343dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 3448718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create a scratch, a unique, and a wrapped resource 3451c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon TestResource* scratch = 34623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty); 347dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(10); 3488718aafec239c93485e45bbe8fed19d9a8def079bsalomon TestResource* unique = SkNEW_ARGS(TestResource, (context->getGpu())); 3498718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 350f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 3515236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* wrapped = SkNEW_ARGS(TestResource, 3525236cf480daf82b2f36e42795abdbbc915533a59bsalomon (context->getGpu(), GrGpuResource::kWrapped_LifeCycle)); 3535236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->setSize(12); 3545236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* unbudgeted = SkNEW_ARGS(TestResource, 3555236cf480daf82b2f36e42795abdbbc915533a59bsalomon (context->getGpu(), GrGpuResource::kUncached_LifeCycle)); 35684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->setSize(13); 357dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 3588718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Make sure we can't add a unique key to the wrapped resource 3598718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey2; 3608718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey2, 1); 361f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon wrapped->resourcePriv().setUniqueKey(uniqueKey2); 3628718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, NULL == cache->findAndRefUniqueResource(uniqueKey2)); 363dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 364dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Make sure sizes are as we expect 3650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 3668718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 36784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 3680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 3690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 3708718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 3710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 372dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 37363c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 3740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 3750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 3768718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 37784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 3780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 3790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 3808718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 3810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 382dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 383dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Unreffing the wrapped resource should free it right away. 384dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 3850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 3868718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 3870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 388dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 38984c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon // Now try freeing the budgeted resources first 3905236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped = SkNEW_ARGS(TestResource, (context->getGpu(), GrGpuResource::kWrapped_LifeCycle)); 391dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(12); 3928718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 3930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 3940ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 39584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() + 3960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 3970ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 3980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes()); 399dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 400dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->unref(); 4010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4020ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 40384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() == 4040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 4060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 407dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 408dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 4090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 4100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 4110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 4120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 41384c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon 41484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->unref(); 4150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 4160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 4170ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 4180ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 419dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon} 420dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4215236cf480daf82b2f36e42795abdbbc915533a59bsalomonstatic void test_unbudgeted(skiatest::Reporter* reporter) { 422c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 423c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 4240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 4255236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4268718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 4278718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 4285236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4295236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* scratch; 4308718aafec239c93485e45bbe8fed19d9a8def079bsalomon TestResource* unique; 4315236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* wrapped; 4325236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* unbudgeted; 4335236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4345236cf480daf82b2f36e42795abdbbc915533a59bsalomon // A large uncached or wrapped resource shouldn't evict anything. 43523e619cf462b2a8a500f3ca750e099f79601f508bsalomon scratch = TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty); 4365236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->setSize(10); 4375236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->unref(); 4380ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 4390ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes()); 4400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 4410ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes()); 4425236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4438718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique = SkNEW_ARGS(TestResource, (context->getGpu())); 4448718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 445f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 4468718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 4470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 4480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 4490ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 4515236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon size_t large = 2 * cache->getResourceBytes(); 4535236cf480daf82b2f36e42795abdbbc915533a59bsalomon unbudgeted = SkNEW_ARGS(TestResource, 4545236cf480daf82b2f36e42795abdbbc915533a59bsalomon (context->getGpu(), large, GrGpuResource::kUncached_LifeCycle)); 4550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 4560ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 4570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 4595236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4605236cf480daf82b2f36e42795abdbbc915533a59bsalomon unbudgeted->unref(); 4610ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 4620ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 4630ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 4655236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4665236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped = SkNEW_ARGS(TestResource, 4675236cf480daf82b2f36e42795abdbbc915533a59bsalomon (context->getGpu(), large, GrGpuResource::kWrapped_LifeCycle)); 4680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 4690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 4700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 4725236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4735236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->unref(); 4740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 4750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 4760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 4780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon 4790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 4810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 4820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 4830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 4845236cf480daf82b2f36e42795abdbbc915533a59bsalomon} 4855236cf480daf82b2f36e42795abdbbc915533a59bsalomon 4863582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon// This method can't be static because it needs to friended in GrGpuResource::CacheAccess. 4873582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomonvoid test_unbudgeted_to_scratch(skiatest::Reporter* reporter); 4883582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) { 489c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 490c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 4910ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 492c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 493c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource* resource = 49423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::CreateScratch(context->getGpu(), TestResource::kA_SimulatedProperty, false); 495c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrScratchKey key; 49623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key); 497c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 498c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon size_t size = resource->gpuMemorySize(); 499c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon for (int i = 0; i < 2; ++i) { 500c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Since this resource is unbudgeted, it should not be reachable as scratch. 5013582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 502c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 5033582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, !resource->resourcePriv().isBudgeted()); 5040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(key)); 5050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 5070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 509c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 510c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Once it is unrefed, it should become available as scratch. 511c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 5120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 5140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 5150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 5160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key)); 517c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource); 5183582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 519c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch()); 5203582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted()); 521c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 522c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon if (0 == i) { 523c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try 524c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // the above tests again. 5253582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().makeUnbudgeted(); 526c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } else { 527c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // After the second time around, try removing the scratch key 5283582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().removeScratchKey(); 5290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 5310ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 5320ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 5333582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid()); 534c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 5353582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().isBudgeted()); 536c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 537c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // now when it is unrefed it should die since it has no key. 538c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 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()); 543c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } 5448b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 545c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon} 546c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 547c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_duplicate_scratch_key(skiatest::Reporter* reporter) { 548c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 549c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 5518b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 5528b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Create two resources that have the same scratch key. 55323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* a = TestResource::CreateScratch(context->getGpu(), 55423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 55523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* b = TestResource::CreateScratch(context->getGpu(), 55623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 5578b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 5588b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(12); 5591c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 56023e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 5611c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Check for negative case consistency. (leaks upon test failure.) 5620ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, NULL == cache->findAndRefScratchResource(scratchKey1)); 5631c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 5641c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 56523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 5661c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 5670ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 568ac49acda520292b059bc37fd368dff912626c3d9bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 5690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 5700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 57171cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == 5720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 5738b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 57463c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 5750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 5768b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 5770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5788b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 5798b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Unref but don't purge 5808b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->unref(); 5818b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 5828b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 5830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 5848b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 58563c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Purge again. This time resources should be purgeable. 5860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 5878b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 5880ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 5890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 5908b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 5918b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 59210e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_remove_scratch_key(skiatest::Reporter* reporter) { 593c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 594c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 59610e23caea3106be125acea10a637789e5a15c728bsalomon 59710e23caea3106be125acea10a637789e5a15c728bsalomon // Create two resources that have the same scratch key. 59823e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* a = TestResource::CreateScratch(context->getGpu(), 59923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 60023e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* b = TestResource::CreateScratch(context->getGpu(), 60123e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 60210e23caea3106be125acea10a637789e5a15c728bsalomon a->unref(); 60310e23caea3106be125acea10a637789e5a15c728bsalomon b->unref(); 60410e23caea3106be125acea10a637789e5a15c728bsalomon 6051c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 6061c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 60723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 6081c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 6090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL); 6101c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 61223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 61310e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 6150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 61610e23caea3106be125acea10a637789e5a15c728bsalomon 61710e23caea3106be125acea10a637789e5a15c728bsalomon // Find the first resource and remove its scratch key 61810e23caea3106be125acea10a637789e5a15c728bsalomon GrGpuResource* find; 6190ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon find = cache->findAndRefScratchResource(scratchKey); 6203582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 62110e23caea3106be125acea10a637789e5a15c728bsalomon // It's still alive, but not cached by scratch key anymore 62210e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6230ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 6240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 62510e23caea3106be125acea10a637789e5a15c728bsalomon 62610e23caea3106be125acea10a637789e5a15c728bsalomon // The cache should immediately delete it when it's unrefed since it isn't accessible. 62710e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 62810e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 6290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 6300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 63110e23caea3106be125acea10a637789e5a15c728bsalomon 63210e23caea3106be125acea10a637789e5a15c728bsalomon // Repeat for the second resource. 6330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon find = cache->findAndRefScratchResource(scratchKey); 6343582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 63510e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 6360ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 6370ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 63810e23caea3106be125acea10a637789e5a15c728bsalomon 63910e23caea3106be125acea10a637789e5a15c728bsalomon // Should be able to call this multiple times with no problem. 6403582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 64110e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 6420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 6430ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 64410e23caea3106be125acea10a637789e5a15c728bsalomon 64510e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 64610e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 6470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 6480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 64910e23caea3106be125acea10a637789e5a15c728bsalomon} 65010e23caea3106be125acea10a637789e5a15c728bsalomon 6511c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomonstatic void test_scratch_key_consistency(skiatest::Reporter* reporter) { 652c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 653c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 6540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 6551c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6561c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // 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); 6611c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon a->unref(); 6621c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon b->unref(); 6631c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6641c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 6651c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key comparison and assignment is consistent. 6661c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 66723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 6681c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey2; 66923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2); 6701c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize()); 6711c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2); 6721c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1); 6731c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey = scratchKey1; 6741c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize()); 6751c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 == scratchKey); 6761c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey == scratchKey1); 6771c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 != scratchKey); 6781c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey != scratchKey2); 6791c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey = scratchKey2; 6801c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize()); 6811c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey); 6821c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey != scratchKey1); 6831c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 == scratchKey); 6841c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey == scratchKey2); 6851c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6861c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 68723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 6881c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 6890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey) == NULL); 6901c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6911c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Find the first resource with a scratch key and a copy of a scratch key. 69223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 6930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrGpuResource* find = cache->findAndRefScratchResource(scratchKey); 6941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find != NULL); 6951c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 6961c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6971c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey2 = scratchKey; 6980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon find = cache->findAndRefScratchResource(scratchKey2); 6991c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find != NULL); 7001c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find == a || find == b); 7011c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7020ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2); 7031c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 != NULL); 7041c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 == a || find2 == b); 7051c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 != find); 7061c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find2->unref(); 7071c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 7081c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon} 7091c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7108718aafec239c93485e45bbe8fed19d9a8def079bsalomonstatic void test_duplicate_unique_key(skiatest::Reporter* reporter) { 711c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 712c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 7148b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 7158718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key; 7168718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key, 0); 717334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 7188718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create two resources that we will attempt to register with the same unique key. 7195236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 7208b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 72171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 722f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Set key on resource a. 723f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 724f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 725f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 726f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 727f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Make sure that redundantly setting a's key works. 728f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 729f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 730f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 731f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 732f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes()); 733f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 734f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 735f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Create resource b and set the same key. It should replace a's unique key cache entry. 736f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 737f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->setSize(12); 738f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->resourcePriv().setUniqueKey(key); 739f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key)); 740f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->unref(); 74171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 742f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Still have two resources because a is still reffed. 7430ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 744f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes()); 7458b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 7468b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 747f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 748f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now a should be gone. 749f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 750f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 751f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 752f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 753f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now replace b with c, but make sure c can start with one unique key and change it to b's key. 754f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Also make b be unreffed when replacement occurs. 7558b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 756f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon TestResource* c = SkNEW_ARGS(TestResource, (context->getGpu())); 757f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon GrUniqueKey differentKey; 758f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon make_unique_key<0>(&differentKey, 1); 759f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->setSize(13); 760f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(differentKey); 761f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 762f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes()); 763f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 764f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c replaces b and b should be immediately purged. 765f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(key); 7660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 767f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 76871cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 76971cb0c241e439b6ed746b90294d0b6916644a644bsalomon 770f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c shouldn't be purged because it is ref'ed. 7710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 7720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 773f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 7748b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7758b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 776f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Drop the ref on c, it should be kept alive because it has a unique key. 777f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 7780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 779f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 78071cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 78171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 782f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Verify that we can find c, then remove its unique key. It should get purged immediately. 783f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key)); 784f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().removeUniqueKey(); 785f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 7860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 7870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 7888b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 7898b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 7908b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 7918b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_purge_invalidated(skiatest::Reporter* reporter) { 792c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 793c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7940ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 7958b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 7968718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2, key3; 7978718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 7988718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 7998718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key3, 3); 8008b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 80123e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Add three resources to the cache. Only c is usable as scratch. 8025236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 8035236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 80423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* c = TestResource::CreateScratch(context->getGpu(), 80523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kA_SimulatedProperty); 8068718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 8078718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 8088718aafec239c93485e45bbe8fed19d9a8def079bsalomon c->resourcePriv().setUniqueKey(key3); 809c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org a->unref(); 81023e619cf462b2a8a500f3ca750e099f79601f508bsalomon // hold b until *after* the message is sent. 8118b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon c->unref(); 812c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 8138718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 8148718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 8158718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 816334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 81723e619cf462b2a8a500f3ca750e099f79601f508bsalomon 8188718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef GrUniqueKeyInvalidatedMessage Msg; 8198718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus; 82023e619cf462b2a8a500f3ca750e099f79601f508bsalomon 82123e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Invalidate two of the three, they should be purged and no longer accessible via their keys. 82223e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key1)); 82323e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key2)); 8240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 82523e619cf462b2a8a500f3ca750e099f79601f508bsalomon // a should be deleted now, but we still have a ref on b. 8268718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 8278718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 82823e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 8298718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 8308b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 8318b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Invalidate the third. 83223e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key3)); 8330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 83423e619cf462b2a8a500f3ca750e099f79601f508bsalomon // we still have a ref on b, c should be recycled as scratch. 83523e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 8368718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3)); 83771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 83823e619cf462b2a8a500f3ca750e099f79601f508bsalomon // make b purgeable. It should be immediately deleted since it has no key. 83923e619cf462b2a8a500f3ca750e099f79601f508bsalomon b->unref(); 84023e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 84123e619cf462b2a8a500f3ca750e099f79601f508bsalomon 84223e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Make sure we actually get to c via it's scratch key, before we say goodbye. 84323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrScratchKey scratchKey; 84423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 8450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey); 84623e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, scratch == c); 84723e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 84823e619cf462b2a8a500f3ca750e099f79601f508bsalomon 84923e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Get rid of c. 8500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 8510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon scratch = cache->findAndRefScratchResource(scratchKey); 85271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 8530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 8540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 85523e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, !scratch); 85623e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 857c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org} 858c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 85971cb0c241e439b6ed746b90294d0b6916644a644bsalomonstatic void test_cache_chained_purge(skiatest::Reporter* reporter) { 860c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 861c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 8620ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 8638b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 8648718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 8658718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 8668718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 867bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 868334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 869c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 870c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 8718718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 8728718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 87371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 874c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Make a cycle 875c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->setUnrefWhenDestroyed(b); 876c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->setUnrefWhenDestroyed(a); 877334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 878c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 879334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 880c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->unref(); 881c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->unref(); 8828b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 883c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 8848b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 8850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 886c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 887f21dab95405979a4aff9f6a741c818304a67f220bsalomon 888c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Break the cycle 889c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->setUnrefWhenDestroyed(NULL); 890c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 891ac49acda520292b059bc37fd368dff912626c3d9bsalomon 8920ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 893c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 894bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org} 895bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 8968b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_resource_size_changed(skiatest::Reporter* reporter) { 8978718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 8988718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 8998718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 90011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 90111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test changing resources sizes (both increase & decrease). 90211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 903c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 904c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 90611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9075236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 9088718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 90911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 91011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9115236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 9128718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 91311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 91411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 9160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 9178b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 9188718aafec239c93485e45bbe8fed19d9a8def079bsalomon SkAutoTUnref<TestResource> find2( 9198718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key2))); 9208b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(200); 9218718aafec239c93485e45bbe8fed19d9a8def079bsalomon SkAutoTUnref<TestResource> find1( 9228718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key1))); 9238b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find1->setSize(50); 9248b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 92511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9260ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes()); 9270ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 92811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 92911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 93011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test increasing a resources size beyond the cache budget. 93111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 932c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2, 300); 933c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 93511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9365236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* a = SkNEW_ARGS(TestResource, (context->getGpu())); 9378b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(100); 9388718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 93911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 94011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9415236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* b = SkNEW_ARGS(TestResource, (context->getGpu())); 9428b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(100); 9438718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 94411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 94511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9460ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 9470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 94811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9498b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 9508718aafec239c93485e45bbe8fed19d9a8def079bsalomon SkAutoTUnref<TestResource> find2(static_cast<TestResource*>( 9518718aafec239c93485e45bbe8fed19d9a8def079bsalomon cache->findAndRefUniqueResource(key2))); 9528b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(201); 9538b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 9548718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 95511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 9560ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes()); 9570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 95811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 95911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org} 96011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 961ddf30e64fe474847b204d7062fad3341d245062cbsalomonstatic void test_timestamp_wrap(skiatest::Reporter* reporter) { 962ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kCount = 50; 963ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetCnt = kCount / 2; 964ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kLockedFreq = 8; 965ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetSize = 0x80000000; 966ddf30e64fe474847b204d7062fad3341d245062cbsalomon 967ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkRandom random; 968ddf30e64fe474847b204d7062fad3341d245062cbsalomon 969ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Run the test 2*kCount times; 970ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int i = 0; i < 2 * kCount; ++i ) { 971ddf30e64fe474847b204d7062fad3341d245062cbsalomon Mock mock(kBudgetCnt, kBudgetSize); 972ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrContext* context = mock.context(); 973ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrResourceCache* cache = mock.cache(); 974ddf30e64fe474847b204d7062fad3341d245062cbsalomon 975ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Pick a random number of resources to add before the timestamp will wrap. 976ddf30e64fe474847b204d7062fad3341d245062cbsalomon cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1)); 977ddf30e64fe474847b204d7062fad3341d245062cbsalomon 978ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kNumToPurge = kCount - kBudgetCnt; 979ddf30e64fe474847b204d7062fad3341d245062cbsalomon 980ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<int> shouldPurgeIdxs; 981ddf30e64fe474847b204d7062fad3341d245062cbsalomon int purgeableCnt = 0; 982ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<GrGpuResource*> resourcesToUnref; 983ddf30e64fe474847b204d7062fad3341d245062cbsalomon 984ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Add kCount resources, holding onto resources at random so we have a mix of purgeable and 985ddf30e64fe474847b204d7062fad3341d245062cbsalomon // unpurgeable resources. 986ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 987ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 988ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 989ddf30e64fe474847b204d7062fad3341d245062cbsalomon 990ddf30e64fe474847b204d7062fad3341d245062cbsalomon TestResource* r = SkNEW_ARGS(TestResource, (context->getGpu())); 991ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->resourcePriv().setUniqueKey(key); 992ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (random.nextU() % kLockedFreq) { 993ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Make this is purgeable. 994ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->unref(); 995ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++purgeableCnt; 996ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (purgeableCnt <= kNumToPurge) { 997ddf30e64fe474847b204d7062fad3341d245062cbsalomon *shouldPurgeIdxs.append() = j; 998ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 999ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 1000ddf30e64fe474847b204d7062fad3341d245062cbsalomon *resourcesToUnref.append() = r; 1001ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1002ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1003ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1004ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Verify that the correct resources were purged. 1005ddf30e64fe474847b204d7062fad3341d245062cbsalomon int currShouldPurgeIdx = 0; 1006ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 1007ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 1008ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 1009ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrGpuResource* res = cache->findAndRefUniqueResource(key); 1010ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (currShouldPurgeIdx < shouldPurgeIdxs.count() && 1011ddf30e64fe474847b204d7062fad3341d245062cbsalomon shouldPurgeIdxs[currShouldPurgeIdx] == j) { 1012ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++currShouldPurgeIdx; 1013ddf30e64fe474847b204d7062fad3341d245062cbsalomon REPORTER_ASSERT(reporter, NULL == res); 1014ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 1015ddf30e64fe474847b204d7062fad3341d245062cbsalomon REPORTER_ASSERT(reporter, NULL != res); 1016ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1017ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkSafeUnref(res); 1018ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1019ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1020ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < resourcesToUnref.count(); ++j) { 1021ddf30e64fe474847b204d7062fad3341d245062cbsalomon resourcesToUnref[j]->unref(); 1022ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1023ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1024ddf30e64fe474847b204d7062fad3341d245062cbsalomon} 1025ddf30e64fe474847b204d7062fad3341d245062cbsalomon 102610e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_large_resource_count(skiatest::Reporter* reporter) { 102710e23caea3106be125acea10a637789e5a15c728bsalomon // Set the cache size to double the resource count because we're going to create 2x that number 102810e23caea3106be125acea10a637789e5a15c728bsalomon // resources, using two different key domains. Add a little slop to the bytes because we resize 102910e23caea3106be125acea10a637789e5a15c728bsalomon // down to 1 byte after creating the resource. 1030c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon static const int kResourceCnt = 2000; 103110e23caea3106be125acea10a637789e5a15c728bsalomon 1032c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000); 1033c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 10340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 103510e23caea3106be125acea10a637789e5a15c728bsalomon 103610e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 10378718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 10388718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 10398718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 104024db3b1c35fb935660229da164fc5ad31977387fbsalomon 104110e23caea3106be125acea10a637789e5a15c728bsalomon TestResource* resource; 104210e23caea3106be125acea10a637789e5a15c728bsalomon 104310e23caea3106be125acea10a637789e5a15c728bsalomon resource = SkNEW_ARGS(TestResource, (context->getGpu())); 10448718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key1); 104510e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 104610e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 104710e23caea3106be125acea10a637789e5a15c728bsalomon 104810e23caea3106be125acea10a637789e5a15c728bsalomon resource = SkNEW_ARGS(TestResource, (context->getGpu())); 10498718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key2); 105010e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 105110e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 105210e23caea3106be125acea10a637789e5a15c728bsalomon } 105310e23caea3106be125acea10a637789e5a15c728bsalomon 105410e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt); 10550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt); 10560ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt); 10570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt); 10580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt); 105910e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 10608718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 10618718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 10628718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 106324db3b1c35fb935660229da164fc5ad31977387fbsalomon 10648718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 10658718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 106610e23caea3106be125acea10a637789e5a15c728bsalomon } 106710e23caea3106be125acea10a637789e5a15c728bsalomon 10680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 106910e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0); 10700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0); 10710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0); 10720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0); 10730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 0); 107410e23caea3106be125acea10a637789e5a15c728bsalomon 107510e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 10768718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 10778718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 10788718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 107924db3b1c35fb935660229da164fc5ad31977387fbsalomon 10808718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 10818718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 108210e23caea3106be125acea10a637789e5a15c728bsalomon } 108310e23caea3106be125acea10a637789e5a15c728bsalomon} 108410e23caea3106be125acea10a637789e5a15c728bsalomon 1085c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 10864ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(ResourceCache, reporter, factory) { 1087c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 1088c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type); 1089c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org if (!GrContextFactory::IsRenderingGLContext(glType)) { 1090c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org continue; 1091c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org } 1092c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org GrContext* context = factory->get(glType); 1093fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon if (NULL == context) { 1094fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon continue; 1095fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon } 1096f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 1097c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org desc.fConfig = kSkia8888_GrPixelConfig; 1098f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon desc.fFlags = kRenderTarget_GrSurfaceFlag; 1099c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org desc.fWidth = gWidth; 1100c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org desc.fHeight = gHeight; 110169f6f00fd975823e825c5aa0b1b8f4416e7c812breed SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight); 1102afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context, 1103afe3005be3392e43bc51eb7eb2017eefaed85ad1bsalomon SkSurface::kNo_Budgeted, info)); 1104fdcf2c0863cdd5779bd6203d45b77d2daf21f159bsalomon test_cache(reporter, context, surface->getCanvas()); 110502a44a488605112aa6683c9d919e13b188112ce1bsalomon test_stencil_buffers(reporter, context); 1106820dd6c335411aad889c1d7e8a857642ecd87e30bsalomon } 1107334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 11088b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // The below tests create their own mock contexts. 110971cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_no_key(reporter); 111084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon test_budgeting(reporter); 11115236cf480daf82b2f36e42795abdbbc915533a59bsalomon test_unbudgeted(reporter); 1112c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon test_unbudgeted_to_scratch(reporter); 11138718aafec239c93485e45bbe8fed19d9a8def079bsalomon test_duplicate_unique_key(reporter); 11148b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_duplicate_scratch_key(reporter); 111510e23caea3106be125acea10a637789e5a15c728bsalomon test_remove_scratch_key(reporter); 11161c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon test_scratch_key_consistency(reporter); 11178b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_purge_invalidated(reporter); 111871cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_cache_chained_purge(reporter); 11198b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_resource_size_changed(reporter); 1120ddf30e64fe474847b204d7062fad3341d245062cbsalomon test_timestamp_wrap(reporter); 112110e23caea3106be125acea10a637789e5a15c728bsalomon test_large_resource_count(reporter); 1122c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org} 1123c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 1124c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#endif 1125