ResourceCacheTest.cpp revision c0192e346ccdcacedb4d4f1f53a85caa29b97a6f
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); 52c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org size_t srcSize = src.getSize(); 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, 12311abd8d6cb2887bf66711863fb2dfe47da86d979bsalomon ctxInfo) { 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 20485d34b2e841d99dab914111fe2eaa4db99345e1eBrian Osman GrBackendObject texHandles[2]; 2056dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon static const int kW = 100; 2066dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon static const int kH = 100; 207672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 208091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texHandles[0] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kRGBA_8888_GrPixelConfig); 209091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon texHandles[1] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kRGBA_8888_GrPixelConfig); 210672bb7fc6640e3fc68107354ed4ae45a2a1e2d29jvanverth 2116dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->resetContext(); 2126dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2137ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTexture backendTex1 = GrTest::CreateBackendTexture(context->contextPriv().getBackend(), 2147ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kW, 2157ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kH, 2167ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kRGBA_8888_GrPixelConfig, 2177ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel texHandles[0]); 21832342f032e1dfd133040324f851f0365f9d4cb51Brian Osman sk_sp<GrTexture> borrowed(context->resourceProvider()->wrapBackendTexture( 219b0e93a22bbfad05bb834e33387880ece56e0f6d2Robert Phillips backendTex1, kBorrow_GrWrapOwnership)); 2207ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 2217ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel GrBackendTexture backendTex2 = GrTest::CreateBackendTexture(context->contextPriv().getBackend(), 2227ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kW, 2237ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kH, 2247ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel kRGBA_8888_GrPixelConfig, 2257ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel texHandles[1]); 22632342f032e1dfd133040324f851f0365f9d4cb51Brian Osman sk_sp<GrTexture> adopted(context->resourceProvider()->wrapBackendTexture( 227b0e93a22bbfad05bb834e33387880ece56e0f6d2Robert Phillips backendTex2, kAdopt_GrWrapOwnership)); 2287ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Daniel 22985d34b2e841d99dab914111fe2eaa4db99345e1eBrian Osman REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr); 23085d34b2e841d99dab914111fe2eaa4db99345e1eBrian Osman if (!borrowed || !adopted) { 2316dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon return; 2326dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon } 2336dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 23496fcdcc219d2a0d3579719b84b28bede76efba64halcanary borrowed.reset(nullptr); 23596fcdcc219d2a0d3579719b84b28bede76efba64halcanary adopted.reset(nullptr); 2366dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2376dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->flush(); 2386dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 239091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[0]); 240091f60c2a0e4504c017b8a67ff96a0e829519b14bsalomon bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[1]); 2416dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2426dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon REPORTER_ASSERT(reporter, borrowedIsAlive); 2436dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon REPORTER_ASSERT(reporter, !adoptedIsAlive); 2446dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 24567d7620285cdfa60158add6615db03bd48e6d8b0bsalomon gpu->deleteTestingOnlyBackendTexture(texHandles[0], !borrowedIsAlive); 24667d7620285cdfa60158add6615db03bd48e6d8b0bsalomon gpu->deleteTestingOnlyBackendTexture(texHandles[1], !adoptedIsAlive); 2476dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2486dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon context->resetContext(); 2496dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon} 2506dc6f5f4a153d33ed91565cb3cd397a310a937d0bsalomon 2516d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomonclass TestResource : public GrGpuResource { 2521c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon enum ScratchConstructor { kScratchConstructor }; 253c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgpublic: 2546e83ac778f8f90939abe3aee3ea865428dff592frobertphillips static const size_t kDefaultSize = 100; 2555f939ab658a228dce34a3b14a545638407150b92mtklein 2561c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon /** Property that distinctly categorizes the resource. 2571c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon * For example, textures have width, height, ... */ 25823e619cf462b2a8a500f3ca750e099f79601f508bsalomon enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty }; 2591c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 2602e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, SkBudgeted budgeted = SkBudgeted::kYes, size_t size = kDefaultSize) 2612e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 26296fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fToDelete(nullptr) 2631c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(size) 2642e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(kA_SimulatedProperty) 2652e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(false) { 2665236cf480daf82b2f36e42795abdbbc915533a59bsalomon ++fNumAlive; 2672e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(budgeted); 2685236cf480daf82b2f36e42795abdbbc915533a59bsalomon } 2695236cf480daf82b2f36e42795abdbbc915533a59bsalomon 2702e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen static TestResource* CreateScratch(GrGpu* gpu, SkBudgeted budgeted, 2712e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SimulatedProperty property) { 2722e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen return new TestResource(gpu, budgeted, property, kScratchConstructor); 2738b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 2742e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen static TestResource* CreateWrapped(GrGpu* gpu, size_t size = kDefaultSize) { 2752e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen return new TestResource(gpu, size); 276c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 277c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 278d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon ~TestResource() override { 279334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon --fNumAlive; 28071cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkSafeUnref(fToDelete); 281c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 282c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 28311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void setSize(size_t size) { 28411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org fSize = size; 28511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org this->didChangeGpuMemorySize(); 28611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 28711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 288334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int NumAlive() { return fNumAlive; } 289c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 29071cb0c241e439b6ed746b90294d0b6916644a644bsalomon void setUnrefWhenDestroyed(TestResource* resource) { 29171cb0c241e439b6ed746b90294d0b6916644a644bsalomon SkRefCnt_SafeAssign(fToDelete, resource); 292c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org } 293c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 2941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static void ComputeScratchKey(SimulatedProperty property, GrScratchKey* key) { 2951c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static GrScratchKey::ResourceType t = GrScratchKey::GenerateResourceType(); 2961c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey::Builder builder(key, t, kScratchKeyFieldCnt); 29724db3b1c35fb935660229da164fc5ad31977387fbsalomon for (int i = 0; i < kScratchKeyFieldCnt; ++i) { 29824db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[i] = static_cast<uint32_t>(i + property); 2991c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 3001c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 3011c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 3021c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon static size_t ExpectedScratchKeySize() { 3031c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt); 3041c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 305c665804300096c2e7617379835bb83d715538788commit-bot@chromium.orgprivate: 30624db3b1c35fb935660229da164fc5ad31977387fbsalomon static const int kScratchKeyFieldCnt = 6; 3071c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 3082e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, SkBudgeted budgeted, SimulatedProperty property, ScratchConstructor) 3092e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 31096fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fToDelete(nullptr) 3111c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon , fSize(kDefaultSize) 3122e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(property) 3132e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(true) { 3141c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon ++fNumAlive; 3152e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(budgeted); 3162e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3172e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 3182e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen // Constructor for simulating resources that wrap backend objects. 3192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource(GrGpu* gpu, size_t size) 3202e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen : INHERITED(gpu) 3212e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fToDelete(nullptr) 3222e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fSize(size) 3232e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fProperty(kA_SimulatedProperty) 3242e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen , fIsScratch(false) { 3252e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen ++fNumAlive; 3262e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCacheWrapped(); 3272e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3282e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 3292e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen void computeScratchKey(GrScratchKey* key) const override { 3302e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen if (fIsScratch) { 3312e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen ComputeScratchKey(fProperty, key); 3322e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen } 3331c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon } 3341c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 33536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein size_t onGpuMemorySize() const override { return fSize; } 33669ed47f42d4877c178fdc0031cb01af2966ae235bsalomon 337c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org TestResource* fToDelete; 33811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org size_t fSize; 339334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon static int fNumAlive; 3401c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon SimulatedProperty fProperty; 3412e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen bool fIsScratch; 3426d3fe022d68fd6dd32c0fab30e24fa5a4f048946bsalomon typedef GrGpuResource INHERITED; 343c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org}; 344334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonint TestResource::fNumAlive = 0; 345c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 346c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonclass Mock { 347c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonpublic: 348c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock(int maxCnt, size_t maxBytes) { 34902611d9afdd887ee443825ac88377f2eea093380Greg Daniel fContext = GrContext::MakeMock(nullptr); 350c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon SkASSERT(fContext); 351c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon fContext->setResourceCacheLimits(maxCnt, maxBytes); 3520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = fContext->getResourceCache(); 3530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 3540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkASSERT(0 == cache->getResourceCount() && 0 == cache->getResourceBytes()); 35571cb0c241e439b6ed746b90294d0b6916644a644bsalomon } 356c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 3570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache() { return fContext->getResourceCache(); } 358c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 359342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary GrContext* context() { return fContext.get(); } 360c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 361c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonprivate: 362342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrContext> fContext; 363c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon}; 364c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 365c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_no_key(skiatest::Reporter* reporter) { 366c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 367c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 3680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 36971cb0c241e439b6ed746b90294d0b6916644a644bsalomon 37071cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Create a bunch of resources with no keys 371385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 372385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 373385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* c = new TestResource(context->getGpu()); 374385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* d = new TestResource(context->getGpu()); 37571cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->setSize(11); 37671cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->setSize(12); 37771cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->setSize(13); 37871cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->setSize(14); 37971cb0c241e439b6ed746b90294d0b6916644a644bsalomon 38071cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 3810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 38271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() + c->gpuMemorySize() + 3830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon d->gpuMemorySize() == cache->getResourceBytes()); 38471cb0c241e439b6ed746b90294d0b6916644a644bsalomon 38571cb0c241e439b6ed746b90294d0b6916644a644bsalomon // Should be safe to purge without deleting the resources since we still have refs. 3860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 38771cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 4 == TestResource::NumAlive()); 38871cb0c241e439b6ed746b90294d0b6916644a644bsalomon 3898718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Since the resources have neither unique nor scratch keys, delete immediately upon unref. 39071cb0c241e439b6ed746b90294d0b6916644a644bsalomon 39171cb0c241e439b6ed746b90294d0b6916644a644bsalomon a->unref(); 39271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 3930ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 39471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() + d->gpuMemorySize() == 3950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 39671cb0c241e439b6ed746b90294d0b6916644a644bsalomon 39771cb0c241e439b6ed746b90294d0b6916644a644bsalomon c->unref(); 39871cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 3990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 40071cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + d->gpuMemorySize() == 4010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 40271cb0c241e439b6ed746b90294d0b6916644a644bsalomon 40371cb0c241e439b6ed746b90294d0b6916644a644bsalomon d->unref(); 40471cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 4050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 4060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 40771cb0c241e439b6ed746b90294d0b6916644a644bsalomon 40871cb0c241e439b6ed746b90294d0b6916644a644bsalomon b->unref(); 40971cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 4100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 4110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 41271cb0c241e439b6ed746b90294d0b6916644a644bsalomon} 41371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 41424db3b1c35fb935660229da164fc5ad31977387fbsalomon// Each integer passed as a template param creates a new domain. 4151090da6433db575d59b93aec99f6bda49b808b84Brian Salomontemplate <int> 4161090da6433db575d59b93aec99f6bda49b808b84Brian Salomonstatic void make_unique_key(GrUniqueKey* key, int data, const char* tag = nullptr) { 4178718aafec239c93485e45bbe8fed19d9a8def079bsalomon static GrUniqueKey::Domain d = GrUniqueKey::GenerateDomain(); 4181090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrUniqueKey::Builder builder(key, d, 1, tag); 41924db3b1c35fb935660229da164fc5ad31977387fbsalomon builder[0] = data; 42024db3b1c35fb935660229da164fc5ad31977387fbsalomon} 42124db3b1c35fb935660229da164fc5ad31977387fbsalomon 42284c8e62fad59f0e19b40ac718467f5b7884b431dbsalomonstatic void test_budgeting(skiatest::Reporter* reporter) { 423c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 424c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 4250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 426dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4278718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 4288718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 429dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4308718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create a scratch, a unique, and a wrapped resource 4311c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon TestResource* scratch = 4322e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, TestResource::kB_SimulatedProperty); 433dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(10); 434385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* unique = new TestResource(context->getGpu()); 4358718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 436f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 4372e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* wrapped = TestResource::CreateWrapped(context->getGpu()); 4385236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->setSize(12); 439385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* unbudgeted = 4402e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen new TestResource(context->getGpu(), SkBudgeted::kNo); 44184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->setSize(13); 442dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 4430562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman // Make sure we can add a unique key to the wrapped resource 4448718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey2; 4458718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey2, 1); 446f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon wrapped->resourcePriv().setUniqueKey(uniqueKey2); 4470562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman GrGpuResource* wrappedViaKey = cache->findAndRefUniqueResource(uniqueKey2); 4480562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman REPORTER_ASSERT(reporter, wrappedViaKey != nullptr); 4490562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman 4500562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman // Remove the extra ref we just added. 4510562eb9c6c98f07732ca96a1dd4e986f1ca089b8Brian Osman wrappedViaKey->unref(); 452dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 453dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Make sure sizes are as we expect 4540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 4558718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 45684c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 4570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4598718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 4600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 461ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 462dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 46363c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 4640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 4 == cache->getResourceCount()); 4668718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 46784c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon wrapped->gpuMemorySize() + unbudgeted->gpuMemorySize() == 4680ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 4690ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 4708718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() == 4710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getBudgetedResourceBytes()); 472ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 473dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 474dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon // Unreffing the wrapped resource should free it right away. 475dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 4760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 4778718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + unique->gpuMemorySize() + 4780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 479ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 480dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 48184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon // Now try freeing the budgeted resources first 4822e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen wrapped = TestResource::CreateWrapped(context->getGpu()); 483dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->setSize(12); 4848718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 485ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 11 == cache->getPurgeableBytes()); 4860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 48884c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() + wrapped->gpuMemorySize() + 4890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 4900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 4910ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, scratch->gpuMemorySize() == cache->getBudgetedResourceBytes()); 492ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 493dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 494dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon scratch->unref(); 495ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 12 == cache->getPurgeableBytes()); 4960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 4970ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 49884c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() + wrapped->gpuMemorySize() == 4990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 5000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 502ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 503dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 504dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon wrapped->unref(); 5050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, unbudgeted->gpuMemorySize() == cache->getResourceBytes()); 5070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 509ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 51084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon 51184c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon unbudgeted->unref(); 5120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 5130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 5140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 516ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 517dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon} 518dace19ec17e85872df3fb35212e1b8bce72018b6bsalomon 5195236cf480daf82b2f36e42795abdbbc915533a59bsalomonstatic void test_unbudgeted(skiatest::Reporter* reporter) { 520c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 30000); 521c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5220ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 5235236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5248718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey uniqueKey; 5258718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&uniqueKey, 0); 5265236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5275236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* scratch; 5288718aafec239c93485e45bbe8fed19d9a8def079bsalomon TestResource* unique; 5295236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* wrapped; 5305236cf480daf82b2f36e42795abdbbc915533a59bsalomon TestResource* unbudgeted; 5315236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5325236cf480daf82b2f36e42795abdbbc915533a59bsalomon // A large uncached or wrapped resource shouldn't evict anything. 5332e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen scratch = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 5342e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::kB_SimulatedProperty); 5352e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen 5365236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->setSize(10); 5375236cf480daf82b2f36e42795abdbbc915533a59bsalomon scratch->unref(); 5380ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 5390ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceBytes()); 5400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 5410ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 10 == cache->getBudgetedResourceBytes()); 542ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 10 == cache->getPurgeableBytes()); 5435236cf480daf82b2f36e42795abdbbc915533a59bsalomon 544385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary unique = new TestResource(context->getGpu()); 5458718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->setSize(11); 546f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon unique->resourcePriv().setUniqueKey(uniqueKey); 5478718aafec239c93485e45bbe8fed19d9a8def079bsalomon unique->unref(); 5480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5490ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 552ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5535236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon size_t large = 2 * cache->getResourceBytes(); 5552e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen unbudgeted = new TestResource(context->getGpu(), SkBudgeted::kNo, large); 5560ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 5570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 5580ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 560ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5615236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5625236cf480daf82b2f36e42795abdbbc915533a59bsalomon unbudgeted->unref(); 5630ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5640ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 567ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5685236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5692e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen wrapped = TestResource::CreateWrapped(context->getGpu(), large); 5700ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 3 == cache->getResourceCount()); 5710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes()); 5720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5730ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 574ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5755236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5765236cf480daf82b2f36e42795abdbbc915533a59bsalomon wrapped->unref(); 5770ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 5780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getResourceBytes()); 5790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount()); 5800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes()); 581ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 21 == cache->getPurgeableBytes()); 5820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon 5830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 5840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 5850ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 5860ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 5870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 588ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 5895236cf480daf82b2f36e42795abdbbc915533a59bsalomon} 5905236cf480daf82b2f36e42795abdbbc915533a59bsalomon 5913582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon// This method can't be static because it needs to friended in GrGpuResource::CacheAccess. 5923582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomonvoid test_unbudgeted_to_scratch(skiatest::Reporter* reporter); 5933582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon/*static*/ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter) { 594c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(10, 300); 595c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 5960ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 597c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 598c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon TestResource* resource = 5992e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::CreateScratch(context->getGpu(), SkBudgeted::kNo, 6002e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource::kA_SimulatedProperty); 601c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrScratchKey key; 60223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key); 603c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 604c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon size_t size = resource->gpuMemorySize(); 605c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon for (int i = 0; i < 2; ++i) { 606c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Since this resource is unbudgeted, it should not be reachable as scratch. 6073582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 608c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 6095ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kNo == resource->resourcePriv().isBudgeted()); 61096fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0)); 6110ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6120ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 6140ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 615ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 616c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 617c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Once it is unrefed, it should become available as scratch. 618c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 6190ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6210ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 6220ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 623ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, size == cache->getPurgeableBytes()); 6246e83ac778f8f90939abe3aee3ea865428dff592frobertphillips resource = static_cast<TestResource*>(cache->findAndRefScratchResource(key, TestResource::kDefaultSize, 0)); 625c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource); 6263582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, resource->resourcePriv().getScratchKey() == key); 627c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, resource->cacheAccess().isScratch()); 6285ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); 629c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 630c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon if (0 == i) { 6315f939ab658a228dce34a3b14a545638407150b92mtklein // If made unbudgeted, it should return to original state: ref'ed and unbudgeted. Try 632c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // the above tests again. 6333582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().makeUnbudgeted(); 634c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } else { 635c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // After the second time around, try removing the scratch key 6363582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon resource->resourcePriv().removeScratchKey(); 6370ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 6380ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getResourceBytes()); 6390ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getBudgetedResourceCount()); 6400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, size == cache->getBudgetedResourceBytes()); 641ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 6423582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon REPORTER_ASSERT(reporter, !resource->resourcePriv().getScratchKey().isValid()); 643c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, !resource->cacheAccess().isScratch()); 6445ec26ae9bfca635ccc98283aad5deda11519d826bsalomon REPORTER_ASSERT(reporter, SkBudgeted::kYes == resource->resourcePriv().isBudgeted()); 645c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 646c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // now when it is unrefed it should die since it has no key. 647c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon resource->unref(); 6480ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 6490ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 6500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 6510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 652ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 653c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon } 6548b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 655c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon} 656c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon 657c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomonstatic void test_duplicate_scratch_key(skiatest::Reporter* reporter) { 658c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 659c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 6600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 6618b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 6628b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Create two resources that have the same scratch key. 66323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* a = TestResource::CreateScratch(context->getGpu(), 6642e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted::kYes, 66523e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 66623e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource* b = TestResource::CreateScratch(context->getGpu(), 6672e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen SkBudgeted::kYes, 66823e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 6698b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 6708b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(12); 6711c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 67223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 6731c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Check for negative case consistency. (leaks upon test failure.) 67496fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == cache->findAndRefScratchResource(scratchKey1, TestResource::kDefaultSize, 0)); 6751c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6761c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 67723e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 6781c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 6790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 680ac49acda520292b059bc37fd368dff912626c3d9bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 6820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 68371cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == 6840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->getResourceBytes()); 6858b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 68663c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Our refs mean that the resources are non purgeable. 6870ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 6888b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 6908b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 6918b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Unref but don't purge 6928b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->unref(); 6938b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 6948b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 6950ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 6968b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 69763c992f6c05ea728b5386de61d279f10eb7e08d9bsalomon // Purge again. This time resources should be purgeable. 6980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 6998b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 7000ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 7010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7028b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 7038b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 70410e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_remove_scratch_key(skiatest::Reporter* reporter) { 705c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 706c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 70810e23caea3106be125acea10a637789e5a15c728bsalomon 70910e23caea3106be125acea10a637789e5a15c728bsalomon // Create two resources that have the same scratch key. 7102e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 71123e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7122e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 71323e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 71410e23caea3106be125acea10a637789e5a15c728bsalomon a->unref(); 71510e23caea3106be125acea10a637789e5a15c728bsalomon b->unref(); 71610e23caea3106be125acea10a637789e5a15c728bsalomon 7171c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 7181c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 71923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 7201c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 72196fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr); 7221c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7230ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon // Scratch resources are registered with GrResourceCache just by existing. There are 2. 72423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 72510e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 7260ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 2 == cache->countScratchEntriesForKey(scratchKey));) 7270ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 72810e23caea3106be125acea10a637789e5a15c728bsalomon 72910e23caea3106be125acea10a637789e5a15c728bsalomon // Find the first resource and remove its scratch key 73010e23caea3106be125acea10a637789e5a15c728bsalomon GrGpuResource* find; 7316e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 7323582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 73310e23caea3106be125acea10a637789e5a15c728bsalomon // It's still alive, but not cached by scratch key anymore 73410e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 7350ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 7360ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 73710e23caea3106be125acea10a637789e5a15c728bsalomon 73810e23caea3106be125acea10a637789e5a15c728bsalomon // The cache should immediately delete it when it's unrefed since it isn't accessible. 73910e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 74010e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7410ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 1 == cache->countScratchEntriesForKey(scratchKey));) 7420ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 74310e23caea3106be125acea10a637789e5a15c728bsalomon 74410e23caea3106be125acea10a637789e5a15c728bsalomon // Repeat for the second resource. 7456e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 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 // Should be able to call this multiple times with no problem. 7523582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon find->resourcePriv().removeScratchKey(); 75310e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 7540ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 75610e23caea3106be125acea10a637789e5a15c728bsalomon 75710e23caea3106be125acea10a637789e5a15c728bsalomon find->unref(); 75810e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 7590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon SkDEBUGCODE(REPORTER_ASSERT(reporter, 0 == cache->countScratchEntriesForKey(scratchKey));) 7600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 76110e23caea3106be125acea10a637789e5a15c728bsalomon} 76210e23caea3106be125acea10a637789e5a15c728bsalomon 7631c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomonstatic void test_scratch_key_consistency(skiatest::Reporter* reporter) { 764c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 765c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 7660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 7671c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7681c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Create two resources that have the same scratch key. 7692e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 77023e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7712e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 77223e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kB_SimulatedProperty); 7731c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon a->unref(); 7741c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon b->unref(); 7751c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7761c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey; 7771c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key comparison and assignment is consistent. 7781c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey1; 77923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey1); 7801c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon GrScratchKey scratchKey2; 78123e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey2); 7821c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1.size() == TestResource::ExpectedScratchKeySize()); 7831c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey2); 7841c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 != scratchKey1); 7851c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey = scratchKey1; 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 scratchKey = scratchKey2; 7921c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey.size() == TestResource::ExpectedScratchKeySize()); 7931c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey1 != scratchKey); 7941c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey != scratchKey1); 7951c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey2 == scratchKey); 7961c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, scratchKey == scratchKey2); 7971c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 7981c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Ensure that scratch key lookup is correct for negative case. 79923e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 8001c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // (following leaks upon test failure). 80196fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0) == nullptr); 8021c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8031c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon // Find the first resource with a scratch key and a copy of a scratch key. 80423e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kB_SimulatedProperty, &scratchKey); 8056e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* find = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 80696fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find != nullptr); 8071c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 8081c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8091c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon scratchKey2 = scratchKey; 8106e83ac778f8f90939abe3aee3ea865428dff592frobertphillips find = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0); 81196fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find != nullptr); 8121c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find == a || find == b); 8131c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8146e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* find2 = cache->findAndRefScratchResource(scratchKey2, TestResource::kDefaultSize, 0); 81596fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, find2 != nullptr); 8161c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 == a || find2 == b); 8171c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon REPORTER_ASSERT(reporter, find2 != find); 8181c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find2->unref(); 8191c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon find->unref(); 8201c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon} 8211c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon 8228718aafec239c93485e45bbe8fed19d9a8def079bsalomonstatic void test_duplicate_unique_key(skiatest::Reporter* reporter) { 823c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 824c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 8250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 8268b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 8278718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key; 8288718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key, 0); 8295f939ab658a228dce34a3b14a545638407150b92mtklein 8308718aafec239c93485e45bbe8fed19d9a8def079bsalomon // Create two resources that we will attempt to register with the same unique key. 831385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 8328b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(11); 8335f939ab658a228dce34a3b14a545638407150b92mtklein 834f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Set key on resource a. 835f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 836f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 837f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 838f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 839f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Make sure that redundantly setting a's key works. 840f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->resourcePriv().setUniqueKey(key); 841f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a == cache->findAndRefUniqueResource(key)); 842f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 843f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 844f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() == cache->getResourceBytes()); 845f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 846f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 847f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Create resource b and set the same key. It should replace a's unique key cache entry. 848385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 849f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->setSize(12); 850f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->resourcePriv().setUniqueKey(key); 851f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b == cache->findAndRefUniqueResource(key)); 852f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon b->unref(); 85371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 854f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Still have two resources because a is still reffed. 8550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 856f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, a->gpuMemorySize() + b->gpuMemorySize() == cache->getResourceBytes()); 8578b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 8588b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 859f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon a->unref(); 860f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now a should be gone. 861f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 862f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() == cache->getResourceBytes()); 863f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 864f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon 865f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Now replace b with c, but make sure c can start with one unique key and change it to b's key. 866f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Also make b be unreffed when replacement occurs. 8678b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->unref(); 868385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* c = new TestResource(context->getGpu()); 869f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon GrUniqueKey differentKey; 870f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon make_unique_key<0>(&differentKey, 1); 871f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->setSize(13); 872f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(differentKey); 873f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 874f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, b->gpuMemorySize() + c->gpuMemorySize() == cache->getResourceBytes()); 875f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 876f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c replaces b and b should be immediately purged. 877f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().setUniqueKey(key); 8780ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 879f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 88071cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 88171cb0c241e439b6ed746b90294d0b6916644a644bsalomon 882f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // c shouldn't be purged because it is ref'ed. 8830ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 8840ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 885f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 8868b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 8878b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 888f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Drop the ref on c, it should be kept alive because it has a unique key. 889f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 8900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 891f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c->gpuMemorySize() == cache->getResourceBytes()); 89271cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 89371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 894f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon // Verify that we can find c, then remove its unique key. It should get purged immediately. 895f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon REPORTER_ASSERT(reporter, c == cache->findAndRefUniqueResource(key)); 896f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->resourcePriv().removeUniqueKey(); 897f99e961f55bb603d099c8cb57d05a2ae52a4e9cabsalomon c->unref(); 8980ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 8990ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 9008b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 90184cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 90284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco { 90384cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key2; 90484cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key2, 0); 905342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> d(new TestResource(context->getGpu())); 90684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco int foo = 4132; 90738d909ec2875f79952de08f36adfaac5680d2c53bungeman key2.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo))); 90884cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco d->resourcePriv().setUniqueKey(key2); 90984cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco } 91084cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 91184cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key3; 91284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key3, 0); 913342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrGpuResource> d2(cache->findAndRefUniqueResource(key3)); 91484cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) d2->getUniqueKey().getCustomData()->data() == 4132); 9158b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon} 9168b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9178b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_purge_invalidated(skiatest::Reporter* reporter) { 918c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(5, 30000); 919c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9200ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 9218b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9228718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2, key3; 9238718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 9248718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 9258718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key3, 3); 9265f939ab658a228dce34a3b14a545638407150b92mtklein 92723e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Add three resources to the cache. Only c is usable as scratch. 928385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 929385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 9302e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen TestResource* c = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 93123e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::kA_SimulatedProperty); 9328718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 9338718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 9348718aafec239c93485e45bbe8fed19d9a8def079bsalomon c->resourcePriv().setUniqueKey(key3); 935c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org a->unref(); 93623e619cf462b2a8a500f3ca750e099f79601f508bsalomon // hold b until *after* the message is sent. 9378b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon c->unref(); 938c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 9398718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 9408718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 9418718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 942334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon REPORTER_ASSERT(reporter, 3 == TestResource::NumAlive()); 94323e619cf462b2a8a500f3ca750e099f79601f508bsalomon 9448718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef GrUniqueKeyInvalidatedMessage Msg; 9458718aafec239c93485e45bbe8fed19d9a8def079bsalomon typedef SkMessageBus<GrUniqueKeyInvalidatedMessage> Bus; 94623e619cf462b2a8a500f3ca750e099f79601f508bsalomon 94723e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Invalidate two of the three, they should be purged and no longer accessible via their keys. 94823e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key1)); 94923e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key2)); 9500ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 95123e619cf462b2a8a500f3ca750e099f79601f508bsalomon // a should be deleted now, but we still have a ref on b. 9528718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 9538718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 95423e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 9558718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key3)); 9568b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9578b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // Invalidate the third. 95823e619cf462b2a8a500f3ca750e099f79601f508bsalomon Bus::Post(Msg(key3)); 9590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAsNeeded(); 96023e619cf462b2a8a500f3ca750e099f79601f508bsalomon // we still have a ref on b, c should be recycled as scratch. 96123e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 9628718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key3)); 96371cb0c241e439b6ed746b90294d0b6916644a644bsalomon 96423e619cf462b2a8a500f3ca750e099f79601f508bsalomon // make b purgeable. It should be immediately deleted since it has no key. 96523e619cf462b2a8a500f3ca750e099f79601f508bsalomon b->unref(); 96623e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, 1 == TestResource::NumAlive()); 96723e619cf462b2a8a500f3ca750e099f79601f508bsalomon 96823e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Make sure we actually get to c via it's scratch key, before we say goodbye. 96923e619cf462b2a8a500f3ca750e099f79601f508bsalomon GrScratchKey scratchKey; 97023e619cf462b2a8a500f3ca750e099f79601f508bsalomon TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &scratchKey); 9716e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 97223e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, scratch == c); 97323e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 97423e619cf462b2a8a500f3ca750e099f79601f508bsalomon 97523e619cf462b2a8a500f3ca750e099f79601f508bsalomon // Get rid of c. 9760ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 9776e83ac778f8f90939abe3aee3ea865428dff592frobertphillips scratch = cache->findAndRefScratchResource(scratchKey, TestResource::kDefaultSize, 0); 97871cb0c241e439b6ed746b90294d0b6916644a644bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 9790ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 9800ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceBytes()); 98123e619cf462b2a8a500f3ca750e099f79601f508bsalomon REPORTER_ASSERT(reporter, !scratch); 98223e619cf462b2a8a500f3ca750e099f79601f508bsalomon SkSafeUnref(scratch); 983c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org} 984c665804300096c2e7617379835bb83d715538788commit-bot@chromium.org 98571cb0c241e439b6ed746b90294d0b6916644a644bsalomonstatic void test_cache_chained_purge(skiatest::Reporter* reporter) { 986c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 987c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 9880ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 9898b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 9908718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 9918718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 9928718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 993bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 994385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 995385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 9968718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 9978718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 99871cb0c241e439b6ed746b90294d0b6916644a644bsalomon 999c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Make a cycle 1000c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->setUnrefWhenDestroyed(b); 1001c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->setUnrefWhenDestroyed(a); 1002334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 1003c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 1004334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon 1005c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon a->unref(); 1006c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon b->unref(); 10078b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 1008c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 10098b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon 10100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 1011c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 1012f21dab95405979a4aff9f6a741c818304a67f220bsalomon 1013c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon // Break the cycle 101496fcdcc219d2a0d3579719b84b28bede76efba64halcanary a->setUnrefWhenDestroyed(nullptr); 1015c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 2 == TestResource::NumAlive()); 1016ac49acda520292b059bc37fd368dff912626c3d9bsalomon 10170ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 1018c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon REPORTER_ASSERT(reporter, 0 == TestResource::NumAlive()); 1019bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org} 1020bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org 10218b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomonstatic void test_resource_size_changed(skiatest::Reporter* reporter) { 10228718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 10238718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key1, 1); 10248718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<0>(&key2, 2); 102511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 102611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test changing resources sizes (both increase & decrease). 102711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 1028c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(3, 30000); 1029c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 10300ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 103111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1032385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 10338718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 103411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 103511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1036385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 10378718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 103811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 103911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10400ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 10410ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 10428b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 1043342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find2( 10448718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key2))); 10458b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(200); 1046342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find1( 10478718aafec239c93485e45bbe8fed19d9a8def079bsalomon static_cast<TestResource*>(cache->findAndRefUniqueResource(key1))); 10488b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find1->setSize(50); 10498b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 105011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10510ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 250 == cache->getResourceBytes()); 10520ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 105311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 105411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 105511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org // Test increasing a resources size beyond the cache budget. 105611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org { 1057c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2, 300); 1058c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 10590ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 106011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1061385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* a = new TestResource(context->getGpu()); 10628b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon a->setSize(100); 10638718aafec239c93485e45bbe8fed19d9a8def079bsalomon a->resourcePriv().setUniqueKey(key1); 106411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org a->unref(); 106511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1066385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* b = new TestResource(context->getGpu()); 10678b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon b->setSize(100); 10688718aafec239c93485e45bbe8fed19d9a8def079bsalomon b->resourcePriv().setUniqueKey(key2); 106911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org b->unref(); 107011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 200 == cache->getResourceBytes()); 10720ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 2 == cache->getResourceCount()); 107311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10748b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon { 1075342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<TestResource> find2(static_cast<TestResource*>( 10768718aafec239c93485e45bbe8fed19d9a8def079bsalomon cache->findAndRefUniqueResource(key2))); 10778b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon find2->setSize(201); 10788b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon } 10798718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 108011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 10810ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 201 == cache->getResourceBytes()); 10820ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, 1 == cache->getResourceCount()); 108311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org } 108411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org} 108511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 1086ddf30e64fe474847b204d7062fad3341d245062cbsalomonstatic void test_timestamp_wrap(skiatest::Reporter* reporter) { 1087ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kCount = 50; 1088ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetCnt = kCount / 2; 1089ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kLockedFreq = 8; 1090ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kBudgetSize = 0x80000000; 1091ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1092ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkRandom random; 1093ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1094ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Run the test 2*kCount times; 1095ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int i = 0; i < 2 * kCount; ++i ) { 1096ddf30e64fe474847b204d7062fad3341d245062cbsalomon Mock mock(kBudgetCnt, kBudgetSize); 1097ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrContext* context = mock.context(); 1098ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrResourceCache* cache = mock.cache(); 1099ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1100ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Pick a random number of resources to add before the timestamp will wrap. 1101ddf30e64fe474847b204d7062fad3341d245062cbsalomon cache->changeTimestamp(SK_MaxU32 - random.nextULessThan(kCount + 1)); 1102ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1103ddf30e64fe474847b204d7062fad3341d245062cbsalomon static const int kNumToPurge = kCount - kBudgetCnt; 1104ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1105ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<int> shouldPurgeIdxs; 1106ddf30e64fe474847b204d7062fad3341d245062cbsalomon int purgeableCnt = 0; 1107ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkTDArray<GrGpuResource*> resourcesToUnref; 1108ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1109ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Add kCount resources, holding onto resources at random so we have a mix of purgeable and 1110ddf30e64fe474847b204d7062fad3341d245062cbsalomon // unpurgeable resources. 1111ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 1112ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 1113ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 1114ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1115385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 1116ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->resourcePriv().setUniqueKey(key); 1117ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (random.nextU() % kLockedFreq) { 1118ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Make this is purgeable. 1119ddf30e64fe474847b204d7062fad3341d245062cbsalomon r->unref(); 1120ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++purgeableCnt; 1121ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (purgeableCnt <= kNumToPurge) { 1122ddf30e64fe474847b204d7062fad3341d245062cbsalomon *shouldPurgeIdxs.append() = j; 1123ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1124ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 1125ddf30e64fe474847b204d7062fad3341d245062cbsalomon *resourcesToUnref.append() = r; 1126ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1127ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1128ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1129ddf30e64fe474847b204d7062fad3341d245062cbsalomon // Verify that the correct resources were purged. 1130ddf30e64fe474847b204d7062fad3341d245062cbsalomon int currShouldPurgeIdx = 0; 1131ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < kCount; ++j) { 1132ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrUniqueKey key; 1133ddf30e64fe474847b204d7062fad3341d245062cbsalomon make_unique_key<0>(&key, j); 1134ddf30e64fe474847b204d7062fad3341d245062cbsalomon GrGpuResource* res = cache->findAndRefUniqueResource(key); 1135ddf30e64fe474847b204d7062fad3341d245062cbsalomon if (currShouldPurgeIdx < shouldPurgeIdxs.count() && 1136ddf30e64fe474847b204d7062fad3341d245062cbsalomon shouldPurgeIdxs[currShouldPurgeIdx] == j) { 1137ddf30e64fe474847b204d7062fad3341d245062cbsalomon ++currShouldPurgeIdx; 113896fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr == res); 1139ddf30e64fe474847b204d7062fad3341d245062cbsalomon } else { 114096fcdcc219d2a0d3579719b84b28bede76efba64halcanary REPORTER_ASSERT(reporter, nullptr != res); 1141ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1142ddf30e64fe474847b204d7062fad3341d245062cbsalomon SkSafeUnref(res); 1143ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1144ddf30e64fe474847b204d7062fad3341d245062cbsalomon 1145ddf30e64fe474847b204d7062fad3341d245062cbsalomon for (int j = 0; j < resourcesToUnref.count(); ++j) { 1146ddf30e64fe474847b204d7062fad3341d245062cbsalomon resourcesToUnref[j]->unref(); 1147ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1148ddf30e64fe474847b204d7062fad3341d245062cbsalomon } 1149ddf30e64fe474847b204d7062fad3341d245062cbsalomon} 1150ddf30e64fe474847b204d7062fad3341d245062cbsalomon 11513f324321cdd8fde7976d958e2888a1ec4e657e35bsalomonstatic void test_flush(skiatest::Reporter* reporter) { 11523f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon Mock mock(1000000, 1000000); 11533f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrContext* context = mock.context(); 11543f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrResourceCache* cache = mock.cache(); 11553f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11563f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // The current cache impl will round the max flush count to the next power of 2. So we choose a 11573f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // power of two here to keep things simpler. 11583f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon static const int kFlushCount = 16; 11593f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->setLimits(1000000, 1000000, kFlushCount); 11603f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11613f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon { 11623f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Insert a resource and send a flush notification kFlushCount times. 11633f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 1164385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 11653f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11663f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, i); 11673f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->resourcePriv().setUniqueKey(k); 11683f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->unref(); 1169b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 11703f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11713f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11723f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Send flush notifications to the cache. Each flush should purge the oldest resource. 1173e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon for (int i = 0; i < kFlushCount; ++i) { 1174e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 11753f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, kFlushCount - i - 1 == cache->getResourceCount()); 11763f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int j = 0; j < i; ++j) { 11773f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11783f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, j); 11793f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrGpuResource* r = cache->findAndRefUniqueResource(k); 11803f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, !SkToBool(r)); 11813f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon SkSafeUnref(r); 11823f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11833f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11843f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11853f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 11863f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->purgeAllUnlocked(); 11873f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 11883f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 11893f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Do a similar test but where we leave refs on some resources to prevent them from being 11903f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // purged. 11913f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon { 11923f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrGpuResource* refedResources[kFlushCount >> 1]; 11933f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 1194385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary TestResource* r = new TestResource(context->getGpu()); 11953f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon GrUniqueKey k; 11963f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon make_unique_key<1>(&k, i); 11973f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->resourcePriv().setUniqueKey(k); 11983f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Leave a ref on every other resource, beginning with the first. 11993f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon if (SkToBool(i & 0x1)) { 12003f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon refedResources[i/2] = r; 12013f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } else { 12023f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon r->unref(); 12033f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 1204b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 12053f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12063f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12073f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount; ++i) { 12083f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Should get a resource purged every other flush. 1209b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 1210e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon REPORTER_ASSERT(reporter, kFlushCount - i/2 - 1 == cache->getResourceCount()); 12113f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12123f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12133f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon // Unref all the resources that we kept refs on in the first loop. 12143f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon for (int i = 0; i < kFlushCount >> 1; ++i) { 12153f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon refedResources[i]->unref(); 12163f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12173f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 1218e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon // After kFlushCount + 1 flushes they all will have sat in the purgeable queue for 1219e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon // kFlushCount full flushes. 1220e2e87f3484e5524dbfd6c01f402136738d1d434bbsalomon for (int i = 0; i < kFlushCount + 1; ++i) { 12213f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, kFlushCount >> 1 == cache->getResourceCount()); 1222b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon cache->notifyFlushOccurred(GrResourceCache::kExternal); 12233f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12243f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 12253f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12263f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon cache->purgeAllUnlocked(); 12273f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon } 12283f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12293f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 1230dc43898bbbd06202562514ae785116e0cc40f825bsalomon 1231dc43898bbbd06202562514ae785116e0cc40f825bsalomon // Verify that calling flush() on a GrContext with nothing to do will not trigger resource 1232dc43898bbbd06202562514ae785116e0cc40f825bsalomon // eviction. 1233dc43898bbbd06202562514ae785116e0cc40f825bsalomon context->flush(); 1234dc43898bbbd06202562514ae785116e0cc40f825bsalomon for (int i = 0; i < 10; ++i) { 1235dc43898bbbd06202562514ae785116e0cc40f825bsalomon TestResource* r = new TestResource(context->getGpu()); 1236dc43898bbbd06202562514ae785116e0cc40f825bsalomon GrUniqueKey k; 1237dc43898bbbd06202562514ae785116e0cc40f825bsalomon make_unique_key<1>(&k, i); 1238dc43898bbbd06202562514ae785116e0cc40f825bsalomon r->resourcePriv().setUniqueKey(k); 1239dc43898bbbd06202562514ae785116e0cc40f825bsalomon r->unref(); 1240dc43898bbbd06202562514ae785116e0cc40f825bsalomon } 1241dc43898bbbd06202562514ae785116e0cc40f825bsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 1242dc43898bbbd06202562514ae785116e0cc40f825bsalomon for (int i = 0; i < 10 * kFlushCount; ++i) { 1243dc43898bbbd06202562514ae785116e0cc40f825bsalomon context->flush(); 1244dc43898bbbd06202562514ae785116e0cc40f825bsalomon } 1245dc43898bbbd06202562514ae785116e0cc40f825bsalomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 12463f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon} 12473f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon 12485e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomonstatic void test_time_purge(skiatest::Reporter* reporter) { 12495e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon Mock mock(1000000, 1000000); 12505e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrContext* context = mock.context(); 12515e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrResourceCache* cache = mock.cache(); 12525e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12535e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon static constexpr int kCnts[] = {1, 10, 1024}; 12545e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon auto nowish = []() { 12555e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // We sleep so that we ensure we get a value that is greater than the last call to 12565e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // GrStdSteadyClock::now(). 12575e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::this_thread::sleep_for(GrStdSteadyClock::duration(5)); 12585e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon auto result = GrStdSteadyClock::now(); 12595e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Also sleep afterwards so we don't get this value again. 12605e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::this_thread::sleep_for(GrStdSteadyClock::duration(5)); 12615e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon return result; 12625e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon }; 12635e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12645e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int cnt : kCnts) { 12655e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::unique_ptr<GrStdSteadyClock::time_point[]> timeStamps( 12665e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon new GrStdSteadyClock::time_point[cnt]); 12675e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon { 12685e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Insert resources and get time points between each addition. 12695e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 12705e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 12715e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 12725e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 12735e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 12745e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 12755e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon timeStamps.get()[i] = nowish(); 12765e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12775e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12785e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Purge based on the time points between resource additions. Each purge should remove 12795e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // the oldest resource. 12805e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 12815e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(timeStamps[i]); 12825e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt - i - 1 == cache->getResourceCount()); 12835e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int j = 0; j < i; ++j) { 12845e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 12855e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, j); 12865e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrGpuResource* r = cache->findAndRefUniqueResource(k); 12875e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, !SkToBool(r)); 12885e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon SkSafeUnref(r); 12895e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12905e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12915e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12925e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 12935e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeAllUnlocked(); 12945e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 12955e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 12965e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Do a similar test but where we leave refs on some resources to prevent them from being 12975e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // purged. 12985e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon { 12995e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon std::unique_ptr<GrGpuResource* []> refedResources(new GrGpuResource*[cnt / 2]); 13005e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 13015e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 13025e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 13035e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 13045e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 13055e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Leave a ref on every other resource, beginning with the first. 13065e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon if (SkToBool(i & 0x1)) { 13075e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon refedResources.get()[i / 2] = r; 13085e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } else { 13095e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 13105e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13115e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon timeStamps.get()[i] = nowish(); 13125e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13135e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13145e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < cnt; ++i) { 13155e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Should get a resource purged every other frame. 13165e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(timeStamps[i]); 13175e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt - i / 2 - 1 == cache->getResourceCount()); 13185e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13195e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13205e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Unref all the resources that we kept refs on in the first loop. 13215e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < (cnt / 2); ++i) { 13225e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon refedResources.get()[i]->unref(); 13235e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(nowish()); 13245e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, cnt / 2 - i - 1 == cache->getResourceCount()); 13255e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13265e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13275e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeAllUnlocked(); 13285e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13295e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13305e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 13315e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13325e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // Verify that calling flush() on a GrContext with nothing to do will not trigger resource 13335e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon // eviction 13345e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon context->flush(); 13355e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon for (int i = 0; i < 10; ++i) { 13365e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon TestResource* r = new TestResource(context->getGpu()); 13375e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon GrUniqueKey k; 13385e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon make_unique_key<1>(&k, i); 13395e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->resourcePriv().setUniqueKey(k); 13405e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon r->unref(); 13415e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13425e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 13435e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon context->flush(); 13445e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 10 == cache->getResourceCount()); 13455e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon cache->purgeResourcesNotUsedSince(nowish()); 13465e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon REPORTER_ASSERT(reporter, 0 == cache->getResourceCount()); 13475e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon } 13485e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon} 13495e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon 13505480a18d8799511034d0da219c72932cd8f25274Derek Sollenbergerstatic void test_partial_purge(skiatest::Reporter* reporter) { 13515480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger Mock mock(6, 100); 13525480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrContext* context = mock.context(); 13535480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrResourceCache* cache = mock.cache(); 13545480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13555480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger enum TestsCase { 13565480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kOnlyScratch_TestCase = 0, 13575480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kPartialScratch_TestCase = 1, 13585480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kAllScratch_TestCase = 2, 13595480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kPartial_TestCase = 3, 13605480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kAll_TestCase = 4, 13615480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kNone_TestCase = 5, 13625480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger kEndTests_TestCase = kNone_TestCase + 1 13635480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger }; 13645480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13655480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger for (int testCase = 0; testCase < kEndTests_TestCase; testCase++) { 13665480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13675480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger GrUniqueKey key1, key2, key3; 13685480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key1, 1); 13695480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key2, 2); 13705480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger make_unique_key<0>(&key3, 3); 13715480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13725480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add three unique resources to the cache. 13735480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique1 = new TestResource(context->getGpu()); 13745480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique2 = new TestResource(context->getGpu()); 13755480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *unique3 = new TestResource(context->getGpu()); 13765480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13775480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->resourcePriv().setUniqueKey(key1); 13785480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->resourcePriv().setUniqueKey(key2); 13795480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->resourcePriv().setUniqueKey(key3); 13805480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13815480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->setSize(10); 13825480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->setSize(11); 13835480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->setSize(12); 13845480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13855480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add two scratch resources to the cache. 13865480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *scratch1 = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 13875480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource::kA_SimulatedProperty); 13885480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource *scratch2 = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, 13895480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger TestResource::kB_SimulatedProperty); 13905480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch1->setSize(13); 13915480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch2->setSize(14); 13925480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13935480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13945480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 13955480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 13965480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 13975480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 13985480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // Add resources to the purgeable queue 13995480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique1->unref(); 14005480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch1->unref(); 14015480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique2->unref(); 14025480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger scratch2->unref(); 14035480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger unique3->unref(); 14045480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14055480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 14065480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 14075480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes()); 14085480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14095480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger switch(testCase) { 14105480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kOnlyScratch_TestCase: { 14115480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(14, true); 14125480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount()); 14135480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 33 == cache->getBudgetedResourceBytes()); 14145480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14155480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14165480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kPartialScratch_TestCase: { 14175480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(3, true); 14185480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 4 == cache->getBudgetedResourceCount()); 14195480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 47 == cache->getBudgetedResourceBytes()); 14205480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14215480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14225480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kAllScratch_TestCase: { 14235480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(50, true); 14245480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14255480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 14265480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14275480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14285480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kPartial_TestCase: { 14295480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(13, false); 14305480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 3 == cache->getBudgetedResourceCount()); 14315480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 37 == cache->getBudgetedResourceBytes()); 14325480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14335480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14345480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kAll_TestCase: { 14355480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(50, false); 14365480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14375480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceBytes()); 14385480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14395480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14405480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger case kNone_TestCase: { 14415480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(0, true); 14425480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeUnlockedResources(0, false); 14435480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 5 == cache->getBudgetedResourceCount()); 14445480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getBudgetedResourceBytes()); 14455480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 60 == cache->getPurgeableBytes()); 14465480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger break; 14475480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14485480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger }; 14495480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14505480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger // ensure all are purged before the next 14515480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger context->purgeAllUnlockedResources(); 14525480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getBudgetedResourceCount()); 14535480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger REPORTER_ASSERT(reporter, 0 == cache->getPurgeableBytes()); 14545480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 14555480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger } 14565480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger} 14575480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger 145810e23caea3106be125acea10a637789e5a15c728bsalomonstatic void test_large_resource_count(skiatest::Reporter* reporter) { 145910e23caea3106be125acea10a637789e5a15c728bsalomon // Set the cache size to double the resource count because we're going to create 2x that number 146010e23caea3106be125acea10a637789e5a15c728bsalomon // resources, using two different key domains. Add a little slop to the bytes because we resize 146110e23caea3106be125acea10a637789e5a15c728bsalomon // down to 1 byte after creating the resource. 1462c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon static const int kResourceCnt = 2000; 146310e23caea3106be125acea10a637789e5a15c728bsalomon 1464c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon Mock mock(2 * kResourceCnt, 2 * kResourceCnt + 1000); 1465c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon GrContext* context = mock.context(); 14660ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon GrResourceCache* cache = mock.cache(); 146710e23caea3106be125acea10a637789e5a15c728bsalomon 146810e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 14698718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 14708718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 14718718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 147224db3b1c35fb935660229da164fc5ad31977387fbsalomon 147310e23caea3106be125acea10a637789e5a15c728bsalomon TestResource* resource; 147410e23caea3106be125acea10a637789e5a15c728bsalomon 1475385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary resource = new TestResource(context->getGpu()); 14768718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key1); 147710e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 147810e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 147910e23caea3106be125acea10a637789e5a15c728bsalomon 1480385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary resource = new TestResource(context->getGpu()); 14818718aafec239c93485e45bbe8fed19d9a8def079bsalomon resource->resourcePriv().setUniqueKey(key2); 148210e23caea3106be125acea10a637789e5a15c728bsalomon resource->setSize(1); 148310e23caea3106be125acea10a637789e5a15c728bsalomon resource->unref(); 148410e23caea3106be125acea10a637789e5a15c728bsalomon } 148510e23caea3106be125acea10a637789e5a15c728bsalomon 148610e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 2 * kResourceCnt); 1487ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 2 * kResourceCnt); 14880ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 2 * kResourceCnt); 14890ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 2 * kResourceCnt); 14900ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 2 * kResourceCnt); 14910ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 2 * kResourceCnt); 149210e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 14938718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 14948718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 14958718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 149624db3b1c35fb935660229da164fc5ad31977387fbsalomon 14978718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key1)); 14988718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, cache->hasUniqueKey(key2)); 149910e23caea3106be125acea10a637789e5a15c728bsalomon } 150010e23caea3106be125acea10a637789e5a15c728bsalomon 15010ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon cache->purgeAllUnlocked(); 150210e23caea3106be125acea10a637789e5a15c728bsalomon REPORTER_ASSERT(reporter, TestResource::NumAlive() == 0); 1503ee47914ae5661043c20754f46523665a6d31bc73Derek Sollenberger REPORTER_ASSERT(reporter, cache->getPurgeableBytes() == 0); 15040ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceBytes() == 0); 15050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getBudgetedResourceCount() == 0); 15060ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceBytes() == 0); 15070ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon REPORTER_ASSERT(reporter, cache->getResourceCount() == 0); 150810e23caea3106be125acea10a637789e5a15c728bsalomon 150910e23caea3106be125acea10a637789e5a15c728bsalomon for (int i = 0; i < kResourceCnt; ++i) { 15108718aafec239c93485e45bbe8fed19d9a8def079bsalomon GrUniqueKey key1, key2; 15118718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<1>(&key1, i); 15128718aafec239c93485e45bbe8fed19d9a8def079bsalomon make_unique_key<2>(&key2, i); 151324db3b1c35fb935660229da164fc5ad31977387fbsalomon 15148718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key1)); 15158718aafec239c93485e45bbe8fed19d9a8def079bsalomon REPORTER_ASSERT(reporter, !cache->hasUniqueKey(key2)); 151610e23caea3106be125acea10a637789e5a15c728bsalomon } 151710e23caea3106be125acea10a637789e5a15c728bsalomon} 151810e23caea3106be125acea10a637789e5a15c728bsalomon 151984cd621670a357484e1674e06d3d8d6f929a4ab2senorblancostatic void test_custom_data(skiatest::Reporter* reporter) { 152084cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key1, key2; 152184cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key1, 1); 152284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco make_unique_key<0>(&key2, 2); 152384cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco int foo = 4132; 152438d909ec2875f79952de08f36adfaac5680d2c53bungeman key1.setCustomData(SkData::MakeWithCopy(&foo, sizeof(foo))); 152584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) key1.getCustomData()->data() == 4132); 152684cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, key2.getCustomData() == nullptr); 152784cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 152884cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco // Test that copying a key also takes a ref on its custom data. 152984cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco GrUniqueKey key3 = key1; 153084cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco REPORTER_ASSERT(reporter, *(int*) key3.getCustomData()->data() == 4132); 153184cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco} 153284cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco 1533c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomonstatic void test_abandoned(skiatest::Reporter* reporter) { 1534c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon Mock mock(10, 300); 1535c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon GrContext* context = mock.context(); 1536342b7acc46550af5fbefc6f9313231ede11ed692Hal Canary sk_sp<GrGpuResource> resource(new TestResource(context->getGpu())); 1537c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon context->abandonContext(); 1538c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1539c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon REPORTER_ASSERT(reporter, resource->wasDestroyed()); 1540c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1541c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon // Call all the public methods on resource in the abandoned state. They shouldn't crash. 1542c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 15438abb370aca280516f4861c6c942ec453aad018farobertphillips resource->uniqueID(); 1544c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->getUniqueKey(); 1545c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->wasDestroyed(); 1546c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->gpuMemorySize(); 1547c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->getContext(); 1548c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 1549c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->abandon(); 1550c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().getScratchKey(); 1551c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().isBudgeted(); 1552c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().makeBudgeted(); 1553c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().makeUnbudgeted(); 1554c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().removeScratchKey(); 1555c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon GrUniqueKey key; 1556c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon make_unique_key<0>(&key, 1); 1557c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().setUniqueKey(key); 1558c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon resource->resourcePriv().removeUniqueKey(); 1559c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon} 1560c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon 15611090da6433db575d59b93aec99f6bda49b808b84Brian Salomonstatic void test_tags(skiatest::Reporter* reporter) { 15621090da6433db575d59b93aec99f6bda49b808b84Brian Salomon#ifdef SK_DEBUG 15631090da6433db575d59b93aec99f6bda49b808b84Brian Salomon // We will insert 1 resource with tag "tag1", 2 with "tag2", and so on, up through kLastTagIdx. 15641090da6433db575d59b93aec99f6bda49b808b84Brian Salomon static constexpr int kLastTagIdx = 10; 15651090da6433db575d59b93aec99f6bda49b808b84Brian Salomon static constexpr int kNumResources = kLastTagIdx * (kLastTagIdx + 1) / 2; 15661090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15671090da6433db575d59b93aec99f6bda49b808b84Brian Salomon Mock mock(kNumResources, kNumResources * TestResource::kDefaultSize); 15681090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrContext* context = mock.context(); 15691090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrResourceCache* cache = mock.cache(); 15701090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15711090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkString tagStr; 15721090da6433db575d59b93aec99f6bda49b808b84Brian Salomon int tagIdx = 0; 15731090da6433db575d59b93aec99f6bda49b808b84Brian Salomon int currTagCnt = 0; 15741090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15751090da6433db575d59b93aec99f6bda49b808b84Brian Salomon for (int i = 0; i < kNumResources; ++i, ++currTagCnt) { 15761090da6433db575d59b93aec99f6bda49b808b84Brian Salomon sk_sp<GrGpuResource> resource(new TestResource(context->getGpu())); 15771090da6433db575d59b93aec99f6bda49b808b84Brian Salomon GrUniqueKey key; 15781090da6433db575d59b93aec99f6bda49b808b84Brian Salomon if (currTagCnt == tagIdx) { 15791090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagIdx += 1; 15801090da6433db575d59b93aec99f6bda49b808b84Brian Salomon currTagCnt = 0; 15811090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagStr.printf("tag%d", tagIdx); 15821090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15831090da6433db575d59b93aec99f6bda49b808b84Brian Salomon make_unique_key<1>(&key, i, tagStr.c_str()); 15841090da6433db575d59b93aec99f6bda49b808b84Brian Salomon resource->resourcePriv().setUniqueKey(key); 15851090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15861090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkASSERT(kLastTagIdx == tagIdx); 15871090da6433db575d59b93aec99f6bda49b808b84Brian Salomon SkASSERT(currTagCnt == kLastTagIdx); 15881090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15891090da6433db575d59b93aec99f6bda49b808b84Brian Salomon // Test i = 0 to exercise unused tag string. 15901090da6433db575d59b93aec99f6bda49b808b84Brian Salomon for (int i = 0; i <= kLastTagIdx; ++i) { 15911090da6433db575d59b93aec99f6bda49b808b84Brian Salomon tagStr.printf("tag%d", i); 15921090da6433db575d59b93aec99f6bda49b808b84Brian Salomon REPORTER_ASSERT(reporter, cache->countUniqueKeysWithTag(tagStr.c_str()) == i); 15931090da6433db575d59b93aec99f6bda49b808b84Brian Salomon } 15941090da6433db575d59b93aec99f6bda49b808b84Brian Salomon#endif 15951090da6433db575d59b93aec99f6bda49b808b84Brian Salomon} 15961090da6433db575d59b93aec99f6bda49b808b84Brian Salomon 15971530283c483cb88aa725bce50a6d193dd00ee570kkinnunenDEF_GPUTEST(ResourceCacheMisc, reporter, factory) { 15988b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon // The below tests create their own mock contexts. 159971cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_no_key(reporter); 160084c8e62fad59f0e19b40ac718467f5b7884b431dbsalomon test_budgeting(reporter); 16015236cf480daf82b2f36e42795abdbbc915533a59bsalomon test_unbudgeted(reporter); 1602c2f35b750a57d7dc0b8053a98279631d1ccb9b56bsalomon test_unbudgeted_to_scratch(reporter); 16038718aafec239c93485e45bbe8fed19d9a8def079bsalomon test_duplicate_unique_key(reporter); 16048b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_duplicate_scratch_key(reporter); 160510e23caea3106be125acea10a637789e5a15c728bsalomon test_remove_scratch_key(reporter); 16061c60dfe7ca0db010fa3118a1a2c7ff4c09136ab0bsalomon test_scratch_key_consistency(reporter); 16078b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_purge_invalidated(reporter); 160871cb0c241e439b6ed746b90294d0b6916644a644bsalomon test_cache_chained_purge(reporter); 16098b79d23f825cd9e0f9e3bf8aaa9e209940b17ef6bsalomon test_resource_size_changed(reporter); 1610ddf30e64fe474847b204d7062fad3341d245062cbsalomon test_timestamp_wrap(reporter); 16113f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon test_flush(reporter); 16125e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon test_time_purge(reporter); 16135480a18d8799511034d0da219c72932cd8f25274Derek Sollenberger test_partial_purge(reporter); 161410e23caea3106be125acea10a637789e5a15c728bsalomon test_large_resource_count(reporter); 161584cd621670a357484e1674e06d3d8d6f929a4ab2senorblanco test_custom_data(reporter); 1616c6363ef7b4763b36a9a0d255bc775a973d2fc7a5bsalomon test_abandoned(reporter); 16171090da6433db575d59b93aec99f6bda49b808b84Brian Salomon test_tags(reporter); 1618c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org} 1619c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org 1620d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips//////////////////////////////////////////////////////////////////////////////// 162132342f032e1dfd133040324f851f0365f9d4cb51Brian Osmanstatic sk_sp<GrTexture> make_normal_texture(GrResourceProvider* provider, 1622d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceFlags flags, 1623d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int width, int height, 1624d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int sampleCnt) { 1625d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceDesc desc; 1626d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fFlags = flags; 1627b0e93a22bbfad05bb834e33387880ece56e0f6d2Robert Phillips desc.fOrigin = kTopLeft_GrSurfaceOrigin; 1628d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fWidth = width; 1629d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fHeight = height; 1630d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fConfig = kRGBA_8888_GrPixelConfig; 1631d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fSampleCnt = sampleCnt; 1632d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1633e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips return provider->createTexture(desc, SkBudgeted::kYes); 1634d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1635d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1636e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillipsstatic sk_sp<GrTextureProxy> make_mipmap_proxy(GrResourceProvider* provider, 1637e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips GrSurfaceFlags flags, 1638e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips int width, int height, 1639e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips int sampleCnt) { 1640d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkBitmap bm; 1641d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1642d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips bm.allocN32Pixels(width, height, true); 1643d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips bm.eraseColor(SK_ColorBLUE); 1644d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 16457b8400dad2f82dcc6ed3c7cc1707ebaf85f04840Brian Osman sk_sp<SkMipMap> mipmaps(SkMipMap::Build(bm, SkDestinationSurfaceColorMode::kLegacy, nullptr)); 1646d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkASSERT(mipmaps); 1647d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkASSERT(mipmaps->countLevels() > 1); 1648d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1649d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips int mipLevelCount = mipmaps->countLevels() + 1; 1650d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1651d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); 1652d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1653d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[0].fPixels = bm.getPixels(); 1654d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[0].fRowBytes = bm.rowBytes(); 1655d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1656d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips for (int i = 1; i < mipLevelCount; ++i) { 1657d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips SkMipMap::Level generatedMipLevel; 1658d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips mipmaps->getLevel(i - 1, &generatedMipLevel); 1659d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[i].fPixels = generatedMipLevel.fPixmap.addr(); 1660d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); 1661d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips } 1662d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1663d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrSurfaceDesc desc; 1664d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fFlags = flags; 1665e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips desc.fOrigin = (flags & kRenderTarget_GrSurfaceFlag) ? kBottomLeft_GrSurfaceOrigin 1666e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips : kTopLeft_GrSurfaceOrigin; 1667d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fWidth = width; 1668d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fHeight = height; 1669d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fConfig = kRGBA_8888_GrPixelConfig; 1670d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips desc.fSampleCnt = sampleCnt; 167121918231b25037f6ae98a9a431d9e107e8b29f08Greg Daniel desc.fIsMipMapped = true; 1672d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 16738e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips return GrSurfaceProxy::MakeDeferredMipMap(provider, desc, SkBudgeted::kYes, 16748e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips texels.get(), mipLevelCount); 1675d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1676d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1677d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips// Exercise GrSurface::gpuMemorySize for different combos of MSAA, RT-only, 1678d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips// Texture-only, both-RT-and-Texture and MIPmapped 1679d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert PhillipsDEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) { 1680d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips GrContext* context = ctxInfo.grContext(); 168132342f032e1dfd133040324f851f0365f9d4cb51Brian Osman GrResourceProvider* provider = context->resourceProvider(); 1682d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1683d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips static const int kSize = 64; 1684d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1685d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips // Normal versions 1686e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips { 1687e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips sk_sp<GrTexture> tex; 1688e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 1689e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0); 1690e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size_t size = tex->gpuMemorySize(); 1691e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4 == size); 1692e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 169381e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig); 169481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel if (sampleCount >= 4) { 169581e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 169681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel sampleCount); 1697e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = tex->gpuMemorySize(); 169881e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel REPORTER_ASSERT(reporter, 169981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4 == size || // msaa4 failed 170081e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*sampleCount == size || // auto-resolving 170181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*(sampleCount+1) == size); // explicit resolve buffer 1702e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 1703d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1704e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips tex = make_normal_texture(provider, kNone_GrSurfaceFlags, kSize, kSize, 0); 1705d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips size = tex->gpuMemorySize(); 1706e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4 == size); 1707d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips } 1708d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1709d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1710d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips // Mipmapped versions 171148c9919335c7da6188c08a78552186760bd434eaBrian Osman if (context->caps()->mipMapSupport()) { 1712e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips sk_sp<GrTextureProxy> proxy; 1713d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1714e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 0); 1715e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size_t size = proxy->gpuMemorySize(); 1716e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size); 1717e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips 171881e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig); 171981e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel if (sampleCount >= 4) { 172081e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 172181e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel sampleCount); 1722e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = proxy->gpuMemorySize(); 1723e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, 172481e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4+(kSize*kSize*4)/3 == size || // msaa4 failed 172581e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*sampleCount+(kSize*kSize*4)/3 == size || // auto-resolving 172681e7bf8d6d338d944f3c5075b14c21580398aeb6Greg Daniel kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size); // explicit resolve buffer 1727e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 17281b35256f1166358056b2aad8ce09caa6f07912d5Robert Phillips 1729e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips proxy = make_mipmap_proxy(provider, kNone_GrSurfaceFlags, kSize, kSize, 0); 1730e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips size = proxy->gpuMemorySize(); 1731e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size); 1732e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips } 1733d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips} 1734d6214d4f4664ce47861dc690b0ddbea3b7a07855Robert Phillips 1735c28f555f7f4259216a4a524cae6676ab2c56871acommit-bot@chromium.org#endif 1736