ResourceCacheTest.cpp revision d21b2a5d5c5dca87b7df02713782e722a2c0ae92
1c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org/* 2c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * Copyright 2013 Google Inc. 3c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * 4c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org * found in the LICENSE file. 6c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org */ 7c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 83f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon// Include here to ensure SK_SUPPORT_GPU is set correctly before it is examined. 93f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon#include "SkTypes.h" 103f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#if SK_SUPPORT_GPU 125e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon#include <thread> 13bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrContext.h" 147ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel#include "GrContextPriv.h" 15c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#include "GrContextFactory.h" 16bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "GrGpu.h" 173582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourceCacheAccess.h" 183582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h" 19c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips#include "GrRenderTargetPriv.h" 200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h" 21473addf17617d441edb44e501786cdd97d3ebdfbbsalomon#include "GrResourceProvider.h" 226dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon#include "GrTest.h" 23646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#include "GrTexture.h" 24646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips 25bcf0a52d4f4221b158e68a06ba0c4cc4db011060bsalomon#include "SkCanvas.h" 2671cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkGr.h" 2771cb0c241e439b6ed746b90294d0b6916644a644bsalomon#include "SkMessageBus.h" 28d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips#include "SkMipMap.h" 2969f6f00fd975823e825c5aa0b1b8f4416e7c812breed#include "SkSurface.h" 304ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.org#include "Test.h" 31c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 32c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gWidth = 640; 33c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.orgstatic const int gHeight = 480; 34c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 35c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 3668d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, ctxInfo) { 378b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 381530283c483cb88aa725bce50a6d193dd00ee570kkinnunen GrSurfaceDesc desc; 39777b5633f599f2a99e2035fdb7ab600779ab95acBrian Osman desc.fConfig = kRGBA_8888_GrPixelConfig; 401530283c483cb88aa725bce50a6d193dd00ee570kkinnunen desc.fFlags = kRenderTarget_GrSurfaceFlag; 411530283c483cb88aa725bce50a6d193dd00ee570kkinnunen desc.fWidth = gWidth; 421530283c483cb88aa725bce50a6d193dd00ee570kkinnunen desc.fHeight = gHeight; 431530283c483cb88aa725bce50a6d193dd00ee570kkinnunen SkImageInfo info = SkImageInfo::MakeN32Premul(gWidth, gHeight); 44e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info)); 451530283c483cb88aa725bce50a6d193dd00ee570kkinnunen SkCanvas* canvas = surface->getCanvas(); 461530283c483cb88aa725bce50a6d193dd00ee570kkinnunen 47c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org const SkIRect size = SkIRect::MakeWH(gWidth, gHeight); 48c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 49c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org SkBitmap src; 50deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org src.allocN32Pixels(size.width(), size.height()); 51c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org src.eraseColor(SK_ColorBLACK); 52f0ffb8943b7be477b769db23660a80013f3332ebMike Reed size_t srcSize = src.computeByteSize(); 53c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 5495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org size_t initialCacheSize; 5596fcdcc219d2a0d3579719b84b28bede76efba64halcanary context->getResourceCacheUsage(nullptr, &initialCacheSize); 56c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 57c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org int oldMaxNum; 58c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t oldMaxBytes; 5995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->getResourceCacheLimits(&oldMaxNum, &oldMaxBytes); 6017f1ae63d57a3f3d3a0ae50e1b25b3f8b18fd328skia.committer@gmail.com 61c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // Set the cache limits so we can fit 10 "src" images and the 62c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // max number of textures doesn't matter 63c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t maxCacheSize = initialCacheSize + 10*srcSize; 6495c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->setResourceCacheLimits(1000, maxCacheSize); 65c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 66c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org SkBitmap readback; 67deee496cd30070e52556dcb538c2e5eb39b66b81mike@reedtribe.org readback.allocN32Pixels(size.width(), size.height()); 68c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 69c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org for (int i = 0; i < 100; ++i) { 70c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org canvas->drawBitmap(src, 0, 0); 71f19421961c59ceabfb88a5c5cdf7c7e31a95b015Mike Reed surface->readPixels(readback, 0, 0); 72c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 73c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // "modify" the src texture 74c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org src.notifyPixelsChanged(); 75c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 7695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org size_t curCacheSize; 7796fcdcc219d2a0d3579719b84b28bede76efba64halcanary context->getResourceCacheUsage(nullptr, &curCacheSize); 78c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 79c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org // we should never go over the size limit 80c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org REPORTER_ASSERT(reporter, curCacheSize <= maxCacheSize); 81c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org } 82c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 8395c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org context->setResourceCacheLimits(oldMaxNum, oldMaxBytes); 84c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org} 85c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 8611abd8d6cb2887bf66711863fb2dfe47da86d979bsalomonstatic bool is_rendering_and_not_angle_es3(sk_gpu_test::GrContextFactory::ContextType type) { 8711abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon if (type == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES3_ContextType || 8811abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType) { 8911abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon return false; 9011abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon } 9111abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon return sk_gpu_test::GrContextFactory::IsRenderingContext(type); 9211abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon} 9311abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon 94c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillipsstatic GrStencilAttachment* get_SB(GrRenderTarget* rt) { 95c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips return rt->renderTargetPriv().getStencilAttachment(); 96c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips} 97c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 98c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillipsstatic sk_sp<GrRenderTarget> create_RT_with_SB(GrResourceProvider* provider, 99c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips int size, int sampleCount, SkBudgeted budgeted) { 100c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips GrSurfaceDesc desc; 101c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fFlags = kRenderTarget_GrSurfaceFlag; 102c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fOrigin = kBottomLeft_GrSurfaceOrigin; 103c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fWidth = size; 104c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fHeight = size; 105c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fConfig = kRGBA_8888_GrPixelConfig; 106c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips desc.fSampleCnt = sampleCount; 107c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 108c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrTexture> tex(provider->createTexture(desc, budgeted)); 109c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips if (!tex || !tex->asRenderTarget()) { 110c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips return nullptr; 111c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips } 112c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 113c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips if (!provider->attachStencilAttachment(tex->asRenderTarget())) { 114c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips return nullptr; 115c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips } 116c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips SkASSERT(get_SB(tex->asRenderTarget())); 117c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 118c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips return sk_ref_sp(tex->asRenderTarget()); 119c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips} 120c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 12111abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon// This currently fails on ES3 ANGLE contexts 12211abd8d6cb2887bf66711863fb2dfe47da86d979bsalomonDEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angle_es3, reporter, 123ec3253472947b0df618261479336a7b50b24f0c8Robert Phillips ctxInfo, nullptr) { 1248b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 1255c77975e4c00e18e644c72b56f369858acd11b15Eric Karl if (context->caps()->avoidStencilBuffers()) { 1265c77975e4c00e18e644c72b56f369858acd11b15Eric Karl return; 1275c77975e4c00e18e644c72b56f369858acd11b15Eric Karl } 1286bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon 129c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips GrResourceProvider* provider = context->resourceProvider(); 130c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 131c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallRT0 = create_RT_with_SB(provider, 4, 0, SkBudgeted::kYes); 132c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallRT0); 133c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 134c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips { 135c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips // Two budgeted RTs with the same desc should share a stencil buffer. 136c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallRT1 = create_RT_with_SB(provider, 4, 0, SkBudgeted::kYes); 137c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallRT1); 138c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 139c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT1.get())); 1406bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 1416bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon 142c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips { 143c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips // An unbudgeted RT with the same desc should also share. 144c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallRT2 = create_RT_with_SB(provider, 4, 0, SkBudgeted::kNo); 145c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallRT2); 14602a44a488605112aa6683c9d919e13b188112ce1bsalomon 147c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) == get_SB(smallRT2.get())); 1486bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 149c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 150c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips { 151c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips // An RT with a much larger size should not share. 152c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> bigRT = create_RT_with_SB(provider, 400, 0, SkBudgeted::kNo); 153c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, bigRT); 154c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 155c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(bigRT.get())); 1566bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 157c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 158c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips int smallSampleCount = context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig); 159c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips if (smallSampleCount > 0) { 1605f939ab658a228dce34a3b14a545638407150b92mtklein // An RT with a different sample count should not share. 161c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallMSAART0 = create_RT_with_SB(provider, 4, smallSampleCount, 162c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips SkBudgeted::kNo); 163b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#ifdef SK_BUILD_FOR_ANDROID 164b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon if (!smallMSAART0) { 165b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon // The nexus player seems to fail to create MSAA textures. 166b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon return; 167b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon } 168c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips#else 169c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallMSAART0); 170b602d4dff8a353f686ce6d7f9d01b7882cc10277bsalomon#endif 171c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 172c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallRT0.get()) != get_SB(smallMSAART0.get())); 173c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 174c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips { 175c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips // A second MSAA RT should share with the first MSAA RT. 176c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallMSAART1 = create_RT_with_SB(provider, 4, smallSampleCount, 177c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips SkBudgeted::kNo); 178c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallMSAART1); 179c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 180c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) == get_SB(smallMSAART1.get())); 1816bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon } 182c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 18302a44a488605112aa6683c9d919e13b188112ce1bsalomon // But not one with a larger sample count should not. (Also check that the request for 4 18402a44a488605112aa6683c9d919e13b188112ce1bsalomon // samples didn't get rounded up to >= 8 or else they could share.). 185c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips int bigSampleCount = context->caps()->getSampleCount(8, kRGBA_8888_GrPixelConfig); 186c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips if (bigSampleCount != smallSampleCount) { 187c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips sk_sp<GrRenderTarget> smallMSAART2 = create_RT_with_SB(provider, 4, bigSampleCount, 188c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips SkBudgeted::kNo); 189c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, smallMSAART2); 190c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips 191c0192e346ccdcacedb4d4f1f53a85caa29b97a6fRobert Phillips REPORTER_ASSERT(reporter, get_SB(smallMSAART0.get()) != get_SB(smallMSAART2.get())); 19202a44a488605112aa6683c9d919e13b188112ce1bsalomon } 19302a44a488605112aa6683c9d919e13b188112ce1bsalomon } 19402a44a488605112aa6683c9d919e13b188112ce1bsalomon} 19502a44a488605112aa6683c9d919e13b188112ce1bsalomon 19668d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxInfo) { 1978b7451aaf6b1c71e9d343a4df107893db277b6aabsalomon GrContext* context = ctxInfo.grContext(); 198e63ffef6248bd103b5f7827f1e4bc75e47ca9e20bsalomon GrGpu* gpu = context->getGpu(); 199eeb8d99b4e58eb95cad3f7cd5438b9c2b3db7141jvanverth // this test is only valid for GL 200eeb8d99b4e58eb95cad3f7cd5438b9c2b3db7141jvanverth if (!gpu || !gpu->glContextForTesting()) { 2016dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon return; 2026dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon } 2036dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 204d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips GrBackendTexture backendTextures[2]; 2056dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon static const int kW = 100; 2066dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon static const int kH = 100; 207672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 208d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips backendTextures[0] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, 209d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips kRGBA_8888_GrPixelConfig, 210d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips false, GrMipMapped::kNo); 211d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips backendTextures[1] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, 212d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips kRGBA_8888_GrPixelConfig, 213d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips false, GrMipMapped::kNo); 214672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 2156dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->resetContext(); 2166dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 21732342f032e1dfd133040324f851f0365f9d4cb51Brian Osman sk_sp<GrTexture> borrowed(context->resourceProvider()->wrapBackendTexture( 218d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips backendTextures[0], kBorrow_GrWrapOwnership)); 219d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips 22032342f032e1dfd133040324f851f0365f9d4cb51Brian Osman sk_sp<GrTexture> adopted(context->resourceProvider()->wrapBackendTexture( 221d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips backendTextures[1], kAdopt_GrWrapOwnership)); 2227ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 22385d34b2e841d99dab914111fe2eaa4db99345e1eBrian Osman REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr); 22485d34b2e841d99dab914111fe2eaa4db99345e1eBrian Osman if (!borrowed || !adopted) { 2256dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon return; 2266dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon } 2276dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 22896fcdcc219d2a0d3579719b84b28bede76efba64halcanary borrowed.reset(nullptr); 22996fcdcc219d2a0d3579719b84b28bede76efba64halcanary adopted.reset(nullptr); 2306dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2316dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->flush(); 2326dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 233d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[0]); 234d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(backendTextures[1]); 2356dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2366dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon REPORTER_ASSERT(reporter, borrowedIsAlive); 2376dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon REPORTER_ASSERT(reporter, !adoptedIsAlive); 2386dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 239d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips gpu->deleteTestingOnlyBackendTexture(&(backendTextures[0]), !borrowedIsAlive); 240d21b2a5d5c5dca87b7df02713782e722a2c0ae92Robert Phillips gpu->deleteTestingOnlyBackendTexture(&(backendTextures[1]), !adoptedIsAlive); 2416dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2426dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->resetContext(); 2436dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon} 2446dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2456d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomonclass TestResource : public GrGpuResource { 2461c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon enum ScratchConstructor { kScratchConstructor }; 247c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgpublic: 2486e83ac778f8f90939abe3aee3ea865428dff592frobertphillips static const size_t kDefaultSize = 100; 2495f939ab658a228dce34a3b14a545638407150b92mtklein 2501c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon /** Property that distinctly categorizes the resource. 2511c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon * For example, textures have width, height, ... */ 25223e619cf462b2a8a500f3ca750e099f79601f508bsalomon enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty }; 2531c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 2542e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, SkBudgeted budgeted = SkBudgeted::kYes, size_t size = kDefaultSize) 2552e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 25696fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fToDelete(nullptr) 2571c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(size) 2582e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(kA_SimulatedProperty) 2592e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(false) { 2605236cf480daf82b2f36e42795abdbbc915533a59bsalomon ++fNumAlive; 2612e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(budgeted); 2625236cf480daf82b2f36e42795abdbbc915533a59bsalomon } 2635236cf480daf82b2f36e42795abdbbc915533a59bsalomon 2642e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen static TestResource* CreateScratch(GrGpu* gpu, SkBudgeted budgeted, 2652e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SimulatedProperty property) { 2662e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen return new TestResource(gpu, budgeted, property, kScratchConstructor); 2678b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 2682e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen static TestResource* CreateWrapped(GrGpu* gpu, size_t size = kDefaultSize) { 2692e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen return new TestResource(gpu, size); 270c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 271c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 272d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~TestResource() override { 273334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon --fNumAlive; 27471cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkSafeUnref(fToDelete); 275c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 276c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 27711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void setSize(size_t size) { 27811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org fSize = size; 27911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org this->didChangeGpuMemorySize(); 28011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 28111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 282334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int NumAlive() { return fNumAlive; } 283c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 28471cb0c241e439b6ed746b90294d0b6916644a644bsalomon void setUnrefWhenDestroyed(TestResource* resource) { 28571cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkRefCnt_SafeAssign(fToDelete, resource); 286c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 287c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 2881c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) { 2891c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType(); 2901c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt); 29124db3b1c35fb935660229da164fc5ad31977387fbsalomon for (int i = 0; i < kScratchKeyFieldCnt; ++i) { 29224db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[i] = static_cast<uint32_t>(i + property); 2931c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 2951c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 2961c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static size_t ExpectedScratchKeySize() { 2971c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt); 2981c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 299c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgprivate: 30024db3b1c35fb935660229da164fc5ad31977387fbsalomon static const int kScratchKeyFieldCnt = 6; 3011c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 3022e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, SkBudgeted budgeted, SimulatedProperty property, ScratchConstructor) 3032e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 30496fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fToDelete(nullptr) 3051c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(kDefaultSize) 3062e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(property) 3072e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(true) { 3081c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon ++fNumAlive; 3092e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(budgeted); 3102e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3112e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 3122e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen // Constructor for simulating resources that wrap backend objects. 3132e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, size_t size) 3142e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 3152e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fToDelete(nullptr) 3162e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fSize(size) 3172e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(kA_SimulatedProperty) 3182e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(false) { 3192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen ++fNumAlive; 3202e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCacheWrapped(); 3212e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3222e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 3232e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen void computeScratchKey(GrScratchKey* key) const override { 3242e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen if (fIsScratch) { 3252e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen ComputeScratchKey(fProperty, key); 3262e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3271c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 3281c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 32936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein size_t onGpuMemorySize() const override { return fSize; } 33069ed47f42d4877c178fdc0031cb01af2966ae235bsalomon 331c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org TestResource* fToDelete; 33211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org size_t fSize; 333334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int fNumAlive; 3341c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon SimulatedProperty fProperty; 3352e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen bool fIsScratch; 3366d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon typedef GrGpuResource INHERITED; 337c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org}; 338334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonint TestResource::fNumAlive = 0; 339c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 340c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonclass Mock { 341c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonpublic: 342c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock(int maxCnt, size_t maxBytes) { 34302611d9afdd887ee443825ac88377f2eea093380Greg Daniel fContext = GrContext::MakeMock(nullptr); 344c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon SkASSERT(fContext); 345c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon fContext->setResourceCacheLimits(maxCnt, maxBytes); 3460ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = fContext->getResourceCache(); 3470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 3480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes()); 34971cb0c241e439b6ed746b90294d0b6916644a644bsalomon } 350c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 3510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache() { return fContext->getResourceCache(); } 352c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 353342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary GrContext* context() { return fContext.get(); } 354c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 355c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonprivate: 356342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrContext> fContext; 357c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon}; 358c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 359c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_no_key(skiatest::Reporter* reporter) { 360c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 361c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 3620ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 36371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 36471cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Create a bunch of resources with no keys 365385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 366385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 367385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* c = new TestResource(context->getGpu()); 368385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* d = new TestResource(context->getGpu()); 36971cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->setSize(11); 37071cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->setSize(12); 37171cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->setSize(13); 37271cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->setSize(14); 37371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 37471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 3750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 37671cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() + 3770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon d->gpuMemorySize() == cache->getResourceBytes()); 37871cb0c241e439b6ed746b90294d0b6916644a644bsalomon 37971cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Should be safe to purge without deleting the resources since we still have refs. 3800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 38171cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 38271cb0c241e439b6ed746b90294d0b6916644a644bsalomon 3838718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Since the resources have neither unique nor scratch keys, delete immediately upon unref. 38471cb0c241e439b6ed746b90294d0b6916644a644bsalomon 38571cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->unref(); 38671cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 3870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 38871cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() == 3890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 39071cb0c241e439b6ed746b90294d0b6916644a644bsalomon 39171cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->unref(); 39271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 3930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 39471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() == 3950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 39671cb0c241e439b6ed746b90294d0b6916644a644bsalomon 39771cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->unref(); 39871cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 3990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 4000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 40171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 40271cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->unref(); 40371cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 4040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 4050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 40671cb0c241e439b6ed746b90294d0b6916644a644bsalomon} 40771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 40824db3b1c35fb935660229da164fc5ad31977387fbsalomon// Each integer passed as a template param creates a new domain. 4091090da6433db575d59b93aec99f6bda49b808b84Brian Salomontemplate <int> 4101090da6433db575d59b93aec99f6bda49b808b84Brian Salomonstatic void make_unique_key(GrUniqueKey* key, int data, const char* tag = nullptr) { 4118718aafec239c93485e45bbe8fed19d9a8def079bsalomon static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain(); 4121090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrUniqueKey::Builder builder(key, d, 1, tag); 41324db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[0] = data; 41424db3b1c35fb935660229da164fc5ad31977387fbsalomon} 41524db3b1c35fb935660229da164fc5ad31977387fbsalomon 41684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomonstatic void test_budgeting(skiatest::Reporter* reporter) { 417c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 418c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 4190ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 420dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4218718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 4228718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 423dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4248718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create a scratch, a unique, and a wrapped resource 4251c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon TestResource* scratch = 4262e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, TestResource::kB_SimulatedProperty); 427dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(10); 428385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* unique = new TestResource(context->getGpu()); 4298718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 430f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 4312e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* wrapped = TestResource::CreateWrapped(context->getGpu()); 4325236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->setSize(12); 433385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* unbudgeted = 4342e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen new TestResource(context->getGpu(), SkBudgeted::kNo); 43584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->setSize(13); 436dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4370562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman // Make sure we can add a unique key to the wrapped resource 4388718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey2; 4398718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey2, 1); 440f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon wrapped->resourcePriv().setUniqueKey(uniqueKey2); 4410562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman GrGpuResource* wrappedViaKey = cache->findAndRefUniqueResource(uniqueKey2); 4420562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman REPORTER_ASSERT(reporter, wrappedViaKey != nullptr); 4430562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman 4440562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman // Remove the extra ref we just added. 4450562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman wrappedViaKey->unref(); 446dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 447dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Make sure sizes are as we expect 4480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 4498718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 45084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 4510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4538718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 4540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 455ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 456dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 45763c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 4580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 4608718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 46184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 4620ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4630ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4648718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 4650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 466ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 467dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 468dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Unreffing the wrapped resource should free it right away. 469dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 4700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 4718718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 4720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 473ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 474dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 47584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon // Now try freeing the budgeted resources first 4762e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen wrapped = TestResource::CreateWrapped(context->getGpu()); 477dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(12); 4788718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 479ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 11 == cache->getPurgeableBytes()); 4800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 48284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() + 4830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 4840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 4850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes()); 486ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 487dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 488dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->unref(); 489ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 12 == cache->getPurgeableBytes()); 4900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4910ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 49284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() == 4930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4940ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 4950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 496ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 497dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 498dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 4990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 5010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5020ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 503ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 50484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon 50584c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->unref(); 5060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 5070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 5080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5090ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 510ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 511dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon} 512dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 5135236cf480daf82b2f36e42795abdbbc915533a59bsalomonstatic void test_unbudgeted(skiatest::Reporter* reporter) { 514c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 515c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 5175236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5188718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 5198718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 5205236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5215236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* scratch; 5228718aafec239c93485e45bbe8fed19d9a8def079bsalomon TestResource* unique; 5235236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* wrapped; 5245236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* unbudgeted; 5255236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5265236cf480daf82b2f36e42795abdbbc915533a59bsalomon // A large uncached or wrapped resource shouldn't evict anything. 5272e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen scratch = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 5282e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::kB_SimulatedProperty); 5292e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 5305236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->setSize(10); 5315236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->unref(); 5320ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes()); 5340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 5350ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes()); 536ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 10 == cache->getPurgeableBytes()); 5375236cf480daf82b2f36e42795abdbbc915533a59bsalomon 538385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary unique = new TestResource(context->getGpu()); 5398718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 540f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 5418718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 5420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5430ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 546ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5475236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon size_t large = 2 * cache->getResourceBytes(); 5492e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen unbudgeted = new TestResource(context->getGpu(), SkBudgeted::kNo, large); 5500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 5510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 5520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 554ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5555236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5565236cf480daf82b2f36e42795abdbbc915533a59bsalomon unbudgeted->unref(); 5570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 561ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5625236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5632e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen wrapped = TestResource::CreateWrapped(context->getGpu(), large); 5640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 5650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 5660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5670ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 568ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5695236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5705236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->unref(); 5710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 575ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon 5770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 5780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 5790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 5800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 582ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 5835236cf480daf82b2f36e42795abdbbc915533a59bsalomon} 5845236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5853582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon// This method can't be static because it needs to friended in GrGpuResource::CacheAccess. 5863582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomonvoid test_unbudgeted_to_scratch(skiatest::Reporter* reporter); 5873582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) { 588c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 589c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 591c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 592c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource* resource = 5932e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::CreateScratch(context->getGpu(), SkBudgeted::kNo, 5942e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::kA_SimulatedProperty); 595c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrScratchKey key; 59623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key); 597c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 598c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon size_t size = resource->gpuMemorySize(); 599c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon for (int i = 0; i < 2; ++i) { 600c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Since this resource is unbudgeted, it should not be reachable as scratch. 6013582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 602c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 6035ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kNo == resource->resourcePriv().isBudgeted()); 60496fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0)); 6050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 6080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 609ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 610c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 611c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Once it is unrefed, it should become available as scratch. 612c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 6130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 6160ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 617ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, size == cache->getPurgeableBytes()); 6186e83ac778f8f90939abe3aee3ea865428dff592frobertphillips resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0)); 619c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource); 6203582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 621c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch()); 6225ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); 623c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 624c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon if (0 == i) { 6255f939ab658a228dce34a3b14a545638407150b92mtklein // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try 626c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // the above tests again. 6273582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().makeUnbudgeted(); 628c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } else { 629c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // After the second time around, try removing the scratch key 6303582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().removeScratchKey(); 6310ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6320ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6330ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 6340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 635ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 6363582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid()); 637c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 6385ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); 639c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 640c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // now when it is unrefed it should die since it has no key. 641c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 6420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 6430ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 6440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 6450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 646ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 647c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } 6488b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 649c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon} 650c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 651c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_duplicate_scratch_key(skiatest::Reporter* reporter) { 652c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 653c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 6540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 6558b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 6568b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Create two resources that have the same scratch key. 65723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* a = TestResource::CreateScratch(context->getGpu(), 6582e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted::kYes, 65923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 66023e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* b = TestResource::CreateScratch(context->getGpu(), 6612e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted::kYes, 66223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 6638b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 6648b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(12); 6651c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 66623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 6671c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Check for negative case consistency. (leaks upon test failure.) 66896fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(scratchKey1, TestResource::kDefaultSize, 0)); 6691c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6701c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 67123e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 6721c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 674ac49acda520292b059bc37fd368dff912626c3d9bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 6760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 67771cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == 6780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 6798b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 68063c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 6810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 6828b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 6848b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 6858b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Unref but don't purge 6868b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->unref(); 6878b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 6888b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 6908b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 69163c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Purge again. This time resources should be purgeable. 6920ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 6938b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 6940ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 6950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 6968b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 6978b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 69810e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_remove_scratch_key(skiatest::Reporter* reporter) { 699c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 700c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 70210e23caea3106be125acea10a637789e5a15c728bsalomon 70310e23caea3106be125acea10a637789e5a15c728bsalomon // Create two resources that have the same scratch key. 7042e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 70523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7062e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 70723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 70810e23caea3106be125acea10a637789e5a15c728bsalomon a->unref(); 70910e23caea3106be125acea10a637789e5a15c728bsalomon b->unref(); 71010e23caea3106be125acea10a637789e5a15c728bsalomon 7111c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 7121c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 71323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 7141c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 71596fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr); 7161c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7170ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 71823e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 71910e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 7200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 7210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 72210e23caea3106be125acea10a637789e5a15c728bsalomon 72310e23caea3106be125acea10a637789e5a15c728bsalomon // Find the first resource and remove its scratch key 72410e23caea3106be125acea10a637789e5a15c728bsalomon GrGpuResource* find; 7256e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 7263582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 72710e23caea3106be125acea10a637789e5a15c728bsalomon // It's still alive, but not cached by scratch key anymore 72810e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 7290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 7300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 73110e23caea3106be125acea10a637789e5a15c728bsalomon 73210e23caea3106be125acea10a637789e5a15c728bsalomon // The cache should immediately delete it when it's unrefed since it isn't accessible. 73310e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 73410e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7350ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 7360ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 73710e23caea3106be125acea10a637789e5a15c728bsalomon 73810e23caea3106be125acea10a637789e5a15c728bsalomon // Repeat for the second resource. 7396e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 7403582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 74110e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7430ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 74410e23caea3106be125acea10a637789e5a15c728bsalomon 74510e23caea3106be125acea10a637789e5a15c728bsalomon // Should be able to call this multiple times with no problem. 7463582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 74710e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7490ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 75010e23caea3106be125acea10a637789e5a15c728bsalomon 75110e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 75210e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 7530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 75510e23caea3106be125acea10a637789e5a15c728bsalomon} 75610e23caea3106be125acea10a637789e5a15c728bsalomon 7571c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomonstatic void test_scratch_key_consistency(skiatest::Reporter* reporter) { 758c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 759c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 7611c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7621c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Create two resources that have the same scratch key. 7632e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 76423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7652e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 76623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7671c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon a->unref(); 7681c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon b->unref(); 7691c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7701c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 7711c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key comparison and assignment is consistent. 7721c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 77323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 7741c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey2; 77523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2); 7761c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize()); 7771c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2); 7781c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1); 7791c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey = scratchKey1; 7801c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize()); 7811c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 == scratchKey); 7821c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey == scratchKey1); 7831c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 != scratchKey); 7841c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey != scratchKey2); 7851c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey = scratchKey2; 7861c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize()); 7871c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey); 7881c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey != scratchKey1); 7891c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 == scratchKey); 7901c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey == scratchKey2); 7911c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7921c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 79323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 7941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 79596fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr); 7961c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7971c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Find the first resource with a scratch key and a copy of a scratch key. 79823e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 7996e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 80096fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find != nullptr); 8011c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 8021c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8031c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey2 = scratchKey; 8046e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0); 80596fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find != nullptr); 8061c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find == a || find == b); 8071c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8086e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0); 80996fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find2 != nullptr); 8101c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 == a || find2 == b); 8111c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 != find); 8121c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find2->unref(); 8131c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 8141c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon} 8151c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8168718aafec239c93485e45bbe8fed19d9a8def079bsalomonstatic void test_duplicate_unique_key(skiatest::Reporter* reporter) { 817c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 818c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 8190ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 8208b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 8218718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key; 8228718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key, 0); 8235f939ab658a228dce34a3b14a545638407150b92mtklein 8248718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create two resources that we will attempt to register with the same unique key. 825385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 8268b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 8275f939ab658a228dce34a3b14a545638407150b92mtklein 828f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Set key on resource a. 829f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 830f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 831f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 832f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 833f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Make sure that redundantly setting a's key works. 834f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 835f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 836f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 837f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 838f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes()); 839f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 840f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 841f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Create resource b and set the same key. It should replace a's unique key cache entry. 842385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 843f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->setSize(12); 844f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->resourcePriv().setUniqueKey(key); 845f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key)); 846f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->unref(); 84771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 848f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Still have two resources because a is still reffed. 8490ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 850f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes()); 8518b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 8528b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 853f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 854f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now a should be gone. 855f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 856f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 857f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 858f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 859f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now replace b with c, but make sure c can start with one unique key and change it to b's key. 860f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Also make b be unreffed when replacement occurs. 8618b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 862385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* c = new TestResource(context->getGpu()); 863f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon GrUniqueKey differentKey; 864f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon make_unique_key<0>(&differentKey, 1); 865f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->setSize(13); 866f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(differentKey); 867f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 868f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes()); 869f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 870f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c replaces b and b should be immediately purged. 871f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(key); 8720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 873f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 87471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 87571cb0c241e439b6ed746b90294d0b6916644a644bsalomon 876f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c shouldn't be purged because it is ref'ed. 8770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 8780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 879f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 8808b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 8818b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 882f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Drop the ref on c, it should be kept alive because it has a unique key. 883f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 8840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 885f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 88671cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 88771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 888f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Verify that we can find c, then remove its unique key. It should get purged immediately. 889f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key)); 890f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().removeUniqueKey(); 891f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 8920ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 8930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 8948b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 89584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 89684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco { 89784cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key2; 89884cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key2, 0); 899342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> d(new TestResource(context->getGpu())); 90084cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco int foo = 4132; 90138d909ec2875f79952de08f36adfaac5680d2c53bungeman key2.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo))); 90284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco d->resourcePriv().setUniqueKey(key2); 90384cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco } 90484cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 90584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key3; 90684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key3, 0); 907342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrGpuResource> d2(cache->findAndRefUniqueResource(key3)); 90884cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) d2->getUniqueKey().getCustomData()->data() == 4132); 9098b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 9108b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9118b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_purge_invalidated(skiatest::Reporter* reporter) { 912c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 913c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 9158b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9168718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2, key3; 9178718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 9188718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 9198718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key3, 3); 9205f939ab658a228dce34a3b14a545638407150b92mtklein 92123e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Add three resources to the cache. Only c is usable as scratch. 922385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 923385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 9242e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* c = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 92523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kA_SimulatedProperty); 9268718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 9278718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 9288718aafec239c93485e45bbe8fed19d9a8def079bsalomon c->resourcePriv().setUniqueKey(key3); 929c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org a->unref(); 93023e619cf462b2a8a500f3ca750e099f79601f508bsalomon // hold b until *after* the message is sent. 9318b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon c->unref(); 932c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 9338718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 9348718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 9358718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 936334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 93723e619cf462b2a8a500f3ca750e099f79601f508bsalomon 9388718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef GrUniqueKeyInvalidatedMessage Msg; 9398718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus; 94023e619cf462b2a8a500f3ca750e099f79601f508bsalomon 94123e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Invalidate two of the three, they should be purged and no longer accessible via their keys. 94223e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key1)); 94323e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key2)); 9440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 94523e619cf462b2a8a500f3ca750e099f79601f508bsalomon // a should be deleted now, but we still have a ref on b. 9468718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 9478718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 94823e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 9498718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 9508b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9518b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Invalidate the third. 95223e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key3)); 9530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 95423e619cf462b2a8a500f3ca750e099f79601f508bsalomon // we still have a ref on b, c should be recycled as scratch. 95523e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 9568718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3)); 95771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 95823e619cf462b2a8a500f3ca750e099f79601f508bsalomon // make b purgeable. It should be immediately deleted since it has no key. 95923e619cf462b2a8a500f3ca750e099f79601f508bsalomon b->unref(); 96023e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 96123e619cf462b2a8a500f3ca750e099f79601f508bsalomon 96223e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Make sure we actually get to c via it's scratch key, before we say goodbye. 96323e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrScratchKey scratchKey; 96423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 9656e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 96623e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, scratch == c); 96723e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 96823e619cf462b2a8a500f3ca750e099f79601f508bsalomon 96923e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Get rid of c. 9700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 9716e83ac778f8f90939abe3aee3ea865428dff592frobertphillips scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 97271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 9730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 9740ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 97523e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, !scratch); 97623e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 977c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org} 978c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 97971cb0c241e439b6ed746b90294d0b6916644a644bsalomonstatic void test_cache_chained_purge(skiatest::Reporter* reporter) { 980c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 981c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 9838b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9848718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 9858718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 9868718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 987bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 988385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 989385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 9908718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 9918718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 99271cb0c241e439b6ed746b90294d0b6916644a644bsalomon 993c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Make a cycle 994c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->setUnrefWhenDestroyed(b); 995c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->setUnrefWhenDestroyed(a); 996334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 997c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 998334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 999c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->unref(); 1000c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->unref(); 10018b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 1002c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 10038b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 10040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 1005c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 1006f21dab95405979a4aff9f6a741c818304a67f220bsalomon 1007c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Break the cycle 100896fcdcc219d2a0d3579719b84b28bede76efba64halcanary a->setUnrefWhenDestroyed(nullptr); 1009c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 1010ac49acda520292b059bc37fd368dff912626c3d9bsalomon 10110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 1012c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 1013bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org} 1014bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 10158b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_resource_size_changed(skiatest::Reporter* reporter) { 10168718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 10178718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 10188718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 101911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 102011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test changing resources sizes (both increase & decrease). 102111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 1022c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 1023c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 10240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 102511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1026385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 10278718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 102811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 102911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1030385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 10318718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 103211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 103311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10340ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 10350ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 10368b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 1037342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find2( 10388718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key2))); 10398b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(200); 1040342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find1( 10418718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key1))); 10428b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find1->setSize(50); 10438b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 104411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10450ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes()); 10460ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 104711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 104811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 104911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test increasing a resources size beyond the cache budget. 105011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 1051c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2, 300); 1052c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 10530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 105411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1055385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 10568b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(100); 10578718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 105811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 105911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1060385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 10618b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(100); 10628718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 106311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 106411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 10660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 106711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10688b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 1069342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find2(static_cast<TestResource*>( 10708718aafec239c93485e45bbe8fed19d9a8def079bsalomon cache->findAndRefUniqueResource(key2))); 10718b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(201); 10728b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 10738718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 107411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10750ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes()); 10760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 107711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 107811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org} 107911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1080ddf30e64fe474847b204d7062fad3341d245062cbsalomonstatic void test_timestamp_wrap(skiatest::Reporter* reporter) { 1081ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kCount = 50; 1082ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetCnt = kCount / 2; 1083ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kLockedFreq = 8; 1084ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetSize = 0x80000000; 1085ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1086ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkRandom random; 1087ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1088ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Run the test 2*kCount times; 1089ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int i = 0; i < 2 * kCount; ++i ) { 1090ddf30e64fe474847b204d7062fad3341d245062cbsalomon Mock mock(kBudgetCnt, kBudgetSize); 1091ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrContext* context = mock.context(); 1092ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrResourceCache* cache = mock.cache(); 1093ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1094ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Pick a random number of resources to add before the timestamp will wrap. 1095ddf30e64fe474847b204d7062fad3341d245062cbsalomon cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1)); 1096ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1097ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kNumToPurge = kCount - kBudgetCnt; 1098ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1099ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<int> shouldPurgeIdxs; 1100ddf30e64fe474847b204d7062fad3341d245062cbsalomon int purgeableCnt = 0; 1101ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<GrGpuResource*> resourcesToUnref; 1102ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1103ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Add kCount resources, holding onto resources at random so we have a mix of purgeable and 1104ddf30e64fe474847b204d7062fad3341d245062cbsalomon // unpurgeable resources. 1105ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 1106ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 1107ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 1108ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1109385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 1110ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->resourcePriv().setUniqueKey(key); 1111ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (random.nextU() % kLockedFreq) { 1112ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Make this is purgeable. 1113ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->unref(); 1114ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++purgeableCnt; 1115ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (purgeableCnt <= kNumToPurge) { 1116ddf30e64fe474847b204d7062fad3341d245062cbsalomon *shouldPurgeIdxs.append() = j; 1117ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1118ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 1119ddf30e64fe474847b204d7062fad3341d245062cbsalomon *resourcesToUnref.append() = r; 1120ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1121ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1122ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1123ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Verify that the correct resources were purged. 1124ddf30e64fe474847b204d7062fad3341d245062cbsalomon int currShouldPurgeIdx = 0; 1125ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 1126ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 1127ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 1128ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrGpuResource* res = cache->findAndRefUniqueResource(key); 1129ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (currShouldPurgeIdx < shouldPurgeIdxs.count() && 1130ddf30e64fe474847b204d7062fad3341d245062cbsalomon shouldPurgeIdxs[currShouldPurgeIdx] == j) { 1131ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++currShouldPurgeIdx; 113296fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == res); 1133ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 113496fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr != res); 1135ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1136ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkSafeUnref(res); 1137ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1138ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1139ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < resourcesToUnref.count(); ++j) { 1140ddf30e64fe474847b204d7062fad3341d245062cbsalomon resourcesToUnref[j]->unref(); 1141ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1142ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1143ddf30e64fe474847b204d7062fad3341d245062cbsalomon} 1144ddf30e64fe474847b204d7062fad3341d245062cbsalomon 11453f324321cdd8fde7976d958e2888a1ec4e657e35bsalomonstatic void test_flush(skiatest::Reporter* reporter) { 11463f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon Mock mock(1000000, 1000000); 11473f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrContext* context = mock.context(); 11483f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrResourceCache* cache = mock.cache(); 11493f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11503f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // The current cache impl will round the max flush count to the next power of 2. So we choose a 11513f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // power of two here to keep things simpler. 11523f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon static const int kFlushCount = 16; 11533f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->setLimits(1000000, 1000000, kFlushCount); 11543f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11553f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon { 11563f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Insert a resource and send a flush notification kFlushCount times. 11573f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 1158385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 11593f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11603f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, i); 11613f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->resourcePriv().setUniqueKey(k); 11623f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->unref(); 1163b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 11643f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11653f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11663f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Send flush notifications to the cache. Each flush should purge the oldest resource. 1167e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon for (int i = 0; i < kFlushCount; ++i) { 1168e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 11693f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount()); 11703f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int j = 0; j < i; ++j) { 11713f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11723f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, j); 11733f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrGpuResource* r = cache->findAndRefUniqueResource(k); 11743f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, !SkToBool(r)); 11753f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon SkSafeUnref(r); 11763f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11773f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11783f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11793f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 11803f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->purgeAllUnlocked(); 11813f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11823f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11833f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Do a similar test but where we leave refs on some resources to prevent them from being 11843f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // purged. 11853f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon { 11863f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrGpuResource* refedResources[kFlushCount >> 1]; 11873f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 1188385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 11893f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11903f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, i); 11913f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->resourcePriv().setUniqueKey(k); 11923f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Leave a ref on every other resource, beginning with the first. 11933f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon if (SkToBool(i & 0x1)) { 11943f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon refedResources[i/2] = r; 11953f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } else { 11963f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->unref(); 11973f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 1198b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 11993f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12003f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12013f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 12023f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Should get a resource purged every other flush. 1203b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 1204e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount()); 12053f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12063f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12073f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Unref all the resources that we kept refs on in the first loop. 12083f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount >> 1; ++i) { 12093f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon refedResources[i]->unref(); 12103f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12113f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 1212e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon // After kFlushCount + 1 flushes they all will have sat in the purgeable queue for 1213e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon // kFlushCount full flushes. 1214e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon for (int i = 0; i < kFlushCount + 1; ++i) { 12153f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount()); 1216b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 12173f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12183f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 12193f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12203f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->purgeAllUnlocked(); 12213f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12223f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12233f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 1224dc43898bbbd06202562514ae785116e0cc40f825bsalomon 1225dc43898bbbd06202562514ae785116e0cc40f825bsalomon // Verify that calling flush() on a GrContext with nothing to do will not trigger resource 1226dc43898bbbd06202562514ae785116e0cc40f825bsalomon // eviction. 1227dc43898bbbd06202562514ae785116e0cc40f825bsalomon context->flush(); 1228dc43898bbbd06202562514ae785116e0cc40f825bsalomon for (int i = 0; i < 10; ++i) { 1229dc43898bbbd06202562514ae785116e0cc40f825bsalomon TestResource* r = new TestResource(context->getGpu()); 1230dc43898bbbd06202562514ae785116e0cc40f825bsalomon GrUniqueKey k; 1231dc43898bbbd06202562514ae785116e0cc40f825bsalomon make_unique_key<1>(&k, i); 1232dc43898bbbd06202562514ae785116e0cc40f825bsalomon r->resourcePriv().setUniqueKey(k); 1233dc43898bbbd06202562514ae785116e0cc40f825bsalomon r->unref(); 1234dc43898bbbd06202562514ae785116e0cc40f825bsalomon } 1235dc43898bbbd06202562514ae785116e0cc40f825bsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 1236dc43898bbbd06202562514ae785116e0cc40f825bsalomon for (int i = 0; i < 10 * kFlushCount; ++i) { 1237dc43898bbbd06202562514ae785116e0cc40f825bsalomon context->flush(); 1238dc43898bbbd06202562514ae785116e0cc40f825bsalomon } 1239dc43898bbbd06202562514ae785116e0cc40f825bsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 12403f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon} 12413f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12425e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomonstatic void test_time_purge(skiatest::Reporter* reporter) { 12435e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon Mock mock(1000000, 1000000); 12445e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrContext* context = mock.context(); 12455e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrResourceCache* cache = mock.cache(); 12465e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12475e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon static constexpr int kCnts[] = {1, 10, 1024}; 12485e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon auto nowish = []() { 12495e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // We sleep so that we ensure we get a value that is greater than the last call to 12505e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // GrStdSteadyClock::now(). 12515e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::this_thread::sleep_for(GrStdSteadyClock::duration(5)); 12525e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon auto result = GrStdSteadyClock::now(); 12535e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Also sleep afterwards so we don't get this value again. 12545e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::this_thread::sleep_for(GrStdSteadyClock::duration(5)); 12555e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon return result; 12565e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon }; 12575e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12585e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int cnt : kCnts) { 12595e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::unique_ptr<GrStdSteadyClock::time_point[]> timeStamps( 12605e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon new GrStdSteadyClock::time_point[cnt]); 12615e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon { 12625e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Insert resources and get time points between each addition. 12635e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 12645e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 12655e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 12665e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 12675e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 12685e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 12695e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon timeStamps.get()[i] = nowish(); 12705e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12715e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12725e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Purge based on the time points between resource additions. Each purge should remove 12735e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // the oldest resource. 12745e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 12755e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(timeStamps[i]); 12765e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt - i - 1 == cache->getResourceCount()); 12775e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int j = 0; j < i; ++j) { 12785e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 12795e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, j); 12805e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrGpuResource* r = cache->findAndRefUniqueResource(k); 12815e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, !SkToBool(r)); 12825e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon SkSafeUnref(r); 12835e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12845e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12855e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12865e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 12875e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeAllUnlocked(); 12885e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12895e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12905e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Do a similar test but where we leave refs on some resources to prevent them from being 12915e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // purged. 12925e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon { 12935e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::unique_ptr<GrGpuResource* []> refedResources(new GrGpuResource*[cnt / 2]); 12945e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 12955e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 12965e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 12975e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 12985e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 12995e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Leave a ref on every other resource, beginning with the first. 13005e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon if (SkToBool(i & 0x1)) { 13015e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon refedResources.get()[i / 2] = r; 13025e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } else { 13035e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 13045e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13055e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon timeStamps.get()[i] = nowish(); 13065e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13075e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13085e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 13095e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Should get a resource purged every other frame. 13105e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(timeStamps[i]); 13115e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt - i / 2 - 1 == cache->getResourceCount()); 13125e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13135e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13145e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Unref all the resources that we kept refs on in the first loop. 13155e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < (cnt / 2); ++i) { 13165e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon refedResources.get()[i]->unref(); 13175e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(nowish()); 13185e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt / 2 - i - 1 == cache->getResourceCount()); 13195e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13205e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13215e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeAllUnlocked(); 13225e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13235e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13245e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 13255e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13265e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Verify that calling flush() on a GrContext with nothing to do will not trigger resource 13275e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // eviction 13285e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon context->flush(); 13295e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < 10; ++i) { 13305e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 13315e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 13325e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 13335e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 13345e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 13355e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13365e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 13375e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon context->flush(); 13385e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 13395e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(nowish()); 13405e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 13415e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13425e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon} 13435e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13445480a18d8799511034d0da219c72932cd8f25274Derek Sollenbergerstatic void test_partial_purge(skiatest::Reporter* reporter) { 13455480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger Mock mock(6, 100); 13465480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrContext* context = mock.context(); 13475480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrResourceCache* cache = mock.cache(); 13485480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13495480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger enum TestsCase { 13505480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kOnlyScratch_TestCase = 0, 13515480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kPartialScratch_TestCase = 1, 13525480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kAllScratch_TestCase = 2, 13535480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kPartial_TestCase = 3, 13545480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kAll_TestCase = 4, 13555480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kNone_TestCase = 5, 13565480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kEndTests_TestCase = kNone_TestCase + 1 13575480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger }; 13585480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13595480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger for (int testCase = 0; testCase < kEndTests_TestCase; testCase++) { 13605480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13615480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrUniqueKey key1, key2, key3; 13625480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key1, 1); 13635480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key2, 2); 13645480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key3, 3); 13655480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13665480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add three unique resources to the cache. 13675480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique1 = new TestResource(context->getGpu()); 13685480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique2 = new TestResource(context->getGpu()); 13695480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique3 = new TestResource(context->getGpu()); 13705480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13715480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->resourcePriv().setUniqueKey(key1); 13725480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->resourcePriv().setUniqueKey(key2); 13735480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->resourcePriv().setUniqueKey(key3); 13745480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13755480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->setSize(10); 13765480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->setSize(11); 13775480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->setSize(12); 13785480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13795480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add two scratch resources to the cache. 13805480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *scratch1 = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 13815480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource::kA_SimulatedProperty); 13825480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *scratch2 = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 13835480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource::kB_SimulatedProperty); 13845480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch1->setSize(13); 13855480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch2->setSize(14); 13865480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13875480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13885480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 13895480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 13905480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 13915480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13925480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add resources to the purgeable queue 13935480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->unref(); 13945480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch1->unref(); 13955480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->unref(); 13965480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch2->unref(); 13975480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->unref(); 13985480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13995480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 14005480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 14015480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes()); 14025480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14035480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger switch(testCase) { 14045480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kOnlyScratch_TestCase: { 14055480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(14, true); 14065480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount()); 14075480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 33 == cache->getBudgetedResourceBytes()); 14085480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14095480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14105480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kPartialScratch_TestCase: { 14115480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(3, true); 14125480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 4 == cache->getBudgetedResourceCount()); 14135480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 47 == cache->getBudgetedResourceBytes()); 14145480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14155480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14165480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kAllScratch_TestCase: { 14175480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(50, true); 14185480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14195480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 14205480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14215480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14225480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kPartial_TestCase: { 14235480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(13, false); 14245480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount()); 14255480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 37 == cache->getBudgetedResourceBytes()); 14265480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14275480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14285480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kAll_TestCase: { 14295480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(50, false); 14305480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14315480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 14325480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14335480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14345480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kNone_TestCase: { 14355480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(0, true); 14365480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(0, false); 14375480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 14385480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 14395480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes()); 14405480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14415480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14425480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger }; 14435480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14445480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // ensure all are purged before the next 14455480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeAllUnlockedResources(); 14465480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14475480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 14485480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14495480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14505480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger} 14515480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 145210e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_large_resource_count(skiatest::Reporter* reporter) { 145310e23caea3106be125acea10a637789e5a15c728bsalomon // Set the cache size to double the resource count because we're going to create 2x that number 145410e23caea3106be125acea10a637789e5a15c728bsalomon // resources, using two different key domains. Add a little slop to the bytes because we resize 145510e23caea3106be125acea10a637789e5a15c728bsalomon // down to 1 byte after creating the resource. 1456c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon static const int kResourceCnt = 2000; 145710e23caea3106be125acea10a637789e5a15c728bsalomon 1458c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000); 1459c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 14600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 146110e23caea3106be125acea10a637789e5a15c728bsalomon 146210e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 14638718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 14648718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 14658718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 146624db3b1c35fb935660229da164fc5ad31977387fbsalomon 146710e23caea3106be125acea10a637789e5a15c728bsalomon TestResource* resource; 146810e23caea3106be125acea10a637789e5a15c728bsalomon 1469385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary resource = new TestResource(context->getGpu()); 14708718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key1); 147110e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 147210e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 147310e23caea3106be125acea10a637789e5a15c728bsalomon 1474385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary resource = new TestResource(context->getGpu()); 14758718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key2); 147610e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 147710e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 147810e23caea3106be125acea10a637789e5a15c728bsalomon } 147910e23caea3106be125acea10a637789e5a15c728bsalomon 148010e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt); 1481ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 2 * kResourceCnt); 14820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt); 14830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt); 14840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt); 14850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt); 148610e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 14878718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 14888718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 14898718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 149024db3b1c35fb935660229da164fc5ad31977387fbsalomon 14918718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 14928718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 149310e23caea3106be125acea10a637789e5a15c728bsalomon } 149410e23caea3106be125acea10a637789e5a15c728bsalomon 14950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 149610e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0); 1497ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 0); 14980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0); 14990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0); 15000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0); 15010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 0); 150210e23caea3106be125acea10a637789e5a15c728bsalomon 150310e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 15048718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 15058718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 15068718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 150724db3b1c35fb935660229da164fc5ad31977387fbsalomon 15088718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 15098718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 151010e23caea3106be125acea10a637789e5a15c728bsalomon } 151110e23caea3106be125acea10a637789e5a15c728bsalomon} 151210e23caea3106be125acea10a637789e5a15c728bsalomon 151384cd621670a357484e1674e06d3d8d6f929a4ab2senorblancostatic void test_custom_data(skiatest::Reporter* reporter) { 151484cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key1, key2; 151584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key1, 1); 151684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key2, 2); 151784cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco int foo = 4132; 151838d909ec2875f79952de08f36adfaac5680d2c53bungeman key1.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo))); 151984cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) key1.getCustomData()->data() == 4132); 152084cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, key2.getCustomData() == nullptr); 152184cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 152284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco // Test that copying a key also takes a ref on its custom data. 152384cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key3 = key1; 152484cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) key3.getCustomData()->data() == 4132); 152584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco} 152684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 1527c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomonstatic void test_abandoned(skiatest::Reporter* reporter) { 1528c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon Mock mock(10, 300); 1529c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon GrContext* context = mock.context(); 1530342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrGpuResource> resource(new TestResource(context->getGpu())); 1531c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon context->abandonContext(); 1532c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1533c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon REPORTER_ASSERT(reporter, resource->wasDestroyed()); 1534c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1535c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon // Call all the public methods on resource in the abandoned state. They shouldn't crash. 1536c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 15378abb370aca280516f4861c6c942ec453aad018farobertphillips resource->uniqueID(); 1538c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->getUniqueKey(); 1539c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->wasDestroyed(); 1540c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->gpuMemorySize(); 1541c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->getContext(); 1542c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1543c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->abandon(); 1544c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().getScratchKey(); 1545c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().isBudgeted(); 1546c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().makeBudgeted(); 1547c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().makeUnbudgeted(); 1548c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().removeScratchKey(); 1549c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon GrUniqueKey key; 1550c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon make_unique_key<0>(&key, 1); 1551c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().setUniqueKey(key); 1552c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().removeUniqueKey(); 1553c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon} 1554c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 15551090da6433db575d59b93aec99f6bda49b808b84Brian Salomonstatic void test_tags(skiatest::Reporter* reporter) { 15561090da6433db575d59b93aec99f6bda49b808b84Brian Salomon#ifdef SK_DEBUG 15571090da6433db575d59b93aec99f6bda49b808b84Brian Salomon // We will insert 1 resource with tag "tag1", 2 with "tag2", and so on, up through kLastTagIdx. 15581090da6433db575d59b93aec99f6bda49b808b84Brian Salomon static constexpr int kLastTagIdx = 10; 15591090da6433db575d59b93aec99f6bda49b808b84Brian Salomon static constexpr int kNumResources = kLastTagIdx * (kLastTagIdx + 1) / 2; 15601090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15611090da6433db575d59b93aec99f6bda49b808b84Brian Salomon Mock mock(kNumResources, kNumResources * TestResource::kDefaultSize); 15621090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrContext* context = mock.context(); 15631090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrResourceCache* cache = mock.cache(); 15641090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15651090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkString tagStr; 15661090da6433db575d59b93aec99f6bda49b808b84Brian Salomon int tagIdx = 0; 15671090da6433db575d59b93aec99f6bda49b808b84Brian Salomon int currTagCnt = 0; 15681090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15691090da6433db575d59b93aec99f6bda49b808b84Brian Salomon for (int i = 0; i < kNumResources; ++i, ++currTagCnt) { 15701090da6433db575d59b93aec99f6bda49b808b84Brian Salomon sk_sp<GrGpuResource> resource(new TestResource(context->getGpu())); 15711090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrUniqueKey key; 15721090da6433db575d59b93aec99f6bda49b808b84Brian Salomon if (currTagCnt == tagIdx) { 15731090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagIdx += 1; 15741090da6433db575d59b93aec99f6bda49b808b84Brian Salomon currTagCnt = 0; 15751090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagStr.printf("tag%d", tagIdx); 15761090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15771090da6433db575d59b93aec99f6bda49b808b84Brian Salomon make_unique_key<1>(&key, i, tagStr.c_str()); 15781090da6433db575d59b93aec99f6bda49b808b84Brian Salomon resource->resourcePriv().setUniqueKey(key); 15791090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15801090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkASSERT(kLastTagIdx == tagIdx); 15811090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkASSERT(currTagCnt == kLastTagIdx); 15821090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15831090da6433db575d59b93aec99f6bda49b808b84Brian Salomon // Test i = 0 to exercise unused tag string. 15841090da6433db575d59b93aec99f6bda49b808b84Brian Salomon for (int i = 0; i <= kLastTagIdx; ++i) { 15851090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagStr.printf("tag%d", i); 15861090da6433db575d59b93aec99f6bda49b808b84Brian Salomon REPORTER_ASSERT(reporter, cache->countUniqueKeysWithTag(tagStr.c_str()) == i); 15871090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15881090da6433db575d59b93aec99f6bda49b808b84Brian Salomon#endif 15891090da6433db575d59b93aec99f6bda49b808b84Brian Salomon} 15901090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 1591dcfca431e3c350e17eedb3402cc63577cea8d4eaBrian SalomonDEF_GPUTEST(ResourceCacheMisc, reporter, /* options */) { 15928b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // The below tests create their own mock contexts. 159371cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_no_key(reporter); 159484c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon test_budgeting(reporter); 15955236cf480daf82b2f36e42795abdbbc915533a59bsalomon test_unbudgeted(reporter); 1596c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon test_unbudgeted_to_scratch(reporter); 15978718aafec239c93485e45bbe8fed19d9a8def079bsalomon test_duplicate_unique_key(reporter); 15988b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_duplicate_scratch_key(reporter); 159910e23caea3106be125acea10a637789e5a15c728bsalomon test_remove_scratch_key(reporter); 16001c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon test_scratch_key_consistency(reporter); 16018b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_purge_invalidated(reporter); 160271cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_cache_chained_purge(reporter); 16038b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_resource_size_changed(reporter); 1604ddf30e64fe474847b204d7062fad3341d245062cbsalomon test_timestamp_wrap(reporter); 16053f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon test_flush(reporter); 16065e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon test_time_purge(reporter); 16075480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger test_partial_purge(reporter); 160810e23caea3106be125acea10a637789e5a15c728bsalomon test_large_resource_count(reporter); 160984cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco test_custom_data(reporter); 1610c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon test_abandoned(reporter); 16111090da6433db575d59b93aec99f6bda49b808b84Brian Salomon test_tags(reporter); 1612c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org} 1613c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 1614d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips//////////////////////////////////////////////////////////////////////////////// 161532342f032e1dfd133040324f851f0365f9d4cb51Brian Osmanstatic sk_sp<GrTexture> make_normal_texture(GrResourceProvider* provider, 1616d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceFlags flags, 1617d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int width, int height, 1618d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int sampleCnt) { 1619d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceDesc desc; 1620d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fFlags = flags; 1621b0e93a22bbfad05bb834e33387880ece56e0f6d2Robert Phillips desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1622d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fWidth = width; 1623d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fHeight = height; 1624d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fConfig = kRGBA_8888_GrPixelConfig; 1625d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fSampleCnt = sampleCnt; 1626d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1627e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips return provider->createTexture(desc, SkBudgeted::kYes); 1628d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1629d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1630e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillipsstatic sk_sp<GrTextureProxy> make_mipmap_proxy(GrResourceProvider* provider, 1631e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips GrSurfaceFlags flags, 1632e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips int width, int height, 1633e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips int sampleCnt) { 1634d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkBitmap bm; 1635d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1636d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips bm.allocN32Pixels(width, height, true); 1637d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips bm.eraseColor(SK_ColorBLUE); 1638d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 16397b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman sk_sp<SkMipMap> mipmaps(SkMipMap::Build(bm, SkDestinationSurfaceColorMode::kLegacy, nullptr)); 1640d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkASSERT(mipmaps); 1641d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkASSERT(mipmaps->countLevels() > 1); 1642d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1643d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int mipLevelCount = mipmaps->countLevels() + 1; 1644d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1645d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); 1646d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1647d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[0].fPixels = bm.getPixels(); 1648d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[0].fRowBytes = bm.rowBytes(); 1649d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1650d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips for (int i = 1; i < mipLevelCount; ++i) { 1651d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkMipMap::Level generatedMipLevel; 1652d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips mipmaps->getLevel(i - 1, &generatedMipLevel); 1653d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[i].fPixels = generatedMipLevel.fPixmap.addr(); 1654d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); 1655d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips } 1656d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1657d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceDesc desc; 1658d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fFlags = flags; 1659e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips desc.fOrigin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin 1660e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips : kTopLeft_GrSurfaceOrigin; 1661d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fWidth = width; 1662d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fHeight = height; 1663d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fConfig = kRGBA_8888_GrPixelConfig; 1664d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fSampleCnt = sampleCnt; 1665d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 16668e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips return GrSurfaceProxy::MakeDeferredMipMap(provider, desc, SkBudgeted::kYes, 16678e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips texels.get(), mipLevelCount); 1668d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1669d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1670d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips// Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only, 1671d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips// Texture-only, both-RT-and-Texture and MIPmapped 1672d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert PhillipsDEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) { 1673d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrContext* context = ctxInfo.grContext(); 167432342f032e1dfd133040324f851f0365f9d4cb51Brian Osman GrResourceProvider* provider = context->resourceProvider(); 1675d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1676d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips static const int kSize = 64; 1677d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1678d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips // Normal versions 1679e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips { 1680e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips sk_sp<GrTexture> tex; 1681e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 1682e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0); 1683e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size_t size = tex->gpuMemorySize(); 1684e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4 == size); 1685e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 168681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig); 168781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel if (sampleCount >= 4) { 168881e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 168981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel sampleCount); 1690e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = tex->gpuMemorySize(); 169181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel REPORTER_ASSERT(reporter, 169281e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4 == size || // msaa4 failed 169381e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*sampleCount == size || // auto-resolving 169481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*(sampleCount+1) == size); // explicit resolve buffer 1695e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 1696d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1697e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips tex = make_normal_texture(provider, kNone_GrSurfaceFlags, kSize, kSize, 0); 1698d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips size = tex->gpuMemorySize(); 1699e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4 == size); 1700d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips } 1701d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1702d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1703d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips // Mipmapped versions 170448c9919335c7da6188c08a78552186760bd434eaBrian Osman if (context->caps()->mipMapSupport()) { 1705e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips sk_sp<GrTextureProxy> proxy; 1706d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1707e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0); 1708e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size_t size = proxy->gpuMemorySize(); 1709e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size); 1710e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 171181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig); 171281e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel if (sampleCount >= 4) { 171381e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 171481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel sampleCount); 1715e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = proxy->gpuMemorySize(); 1716e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, 171781e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4+(kSize*kSize*4)/3 == size || // msaa4 failed 171881e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*sampleCount+(kSize*kSize*4)/3 == size || // auto-resolving 171981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size); // explicit resolve buffer 1720e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 17211b35256f1166358056b2aad8ce09caa6f07912d5Robert Phillips 1722e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips proxy = make_mipmap_proxy(provider, kNone_GrSurfaceFlags, kSize, kSize, 0); 1723e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = proxy->gpuMemorySize(); 1724e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size); 1725e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 1726d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1727d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1728c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#endif 1729