1952841bf41a81228c23d16c7204b458abe0d7136robertphillips/* 2952841bf41a81228c23d16c7204b458abe0d7136robertphillips* Copyright 2014 Google Inc. 3952841bf41a81228c23d16c7204b458abe0d7136robertphillips* 4952841bf41a81228c23d16c7204b458abe0d7136robertphillips* Use of this source code is governed by a BSD-style license that can be 5952841bf41a81228c23d16c7204b458abe0d7136robertphillips* found in the LICENSE file. 6952841bf41a81228c23d16c7204b458abe0d7136robertphillips*/ 7952841bf41a81228c23d16c7204b458abe0d7136robertphillips 8952841bf41a81228c23d16c7204b458abe0d7136robertphillips#if SK_SUPPORT_GPU 9952841bf41a81228c23d16c7204b458abe0d7136robertphillips 10952841bf41a81228c23d16c7204b458abe0d7136robertphillips#include "GrContext.h" 11952841bf41a81228c23d16c7204b458abe0d7136robertphillips#include "GrContextFactory.h" 12952841bf41a81228c23d16c7204b458abe0d7136robertphillips#include "GrLayerCache.h" 13cfaeec446d06058cacef068b09f58ae2c78338faRobert Phillips#include "SkPictureRecorder.h" 14952841bf41a81228c23d16c7204b458abe0d7136robertphillips#include "Test.h" 15952841bf41a81228c23d16c7204b458abe0d7136robertphillips 16d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillipsclass TestingAccess { 17952841bf41a81228c23d16c7204b458abe0d7136robertphillipspublic: 18952841bf41a81228c23d16c7204b458abe0d7136robertphillips static int NumLayers(GrLayerCache* cache) { 19952841bf41a81228c23d16c7204b458abe0d7136robertphillips return cache->numLayers(); 20952841bf41a81228c23d16c7204b458abe0d7136robertphillips } 21d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips static void Purge(GrLayerCache* cache, uint32_t pictureID) { 22d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips cache->purge(pictureID); 23d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips } 24952841bf41a81228c23d16c7204b458abe0d7136robertphillips}; 25952841bf41a81228c23d16c7204b458abe0d7136robertphillips 26952841bf41a81228c23d16c7204b458abe0d7136robertphillips// Add several layers to the cache 27952841bf41a81228c23d16c7204b458abe0d7136robertphillipsstatic void create_layers(skiatest::Reporter* reporter, 28952841bf41a81228c23d16c7204b458abe0d7136robertphillips GrLayerCache* cache, 29320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips const SkPicture& picture, 30320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips int numToAdd, 31320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips int idOffset) { 32320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 33320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips for (int i = 0; i < numToAdd; ++i) { 346f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 350c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips idOffset+i+1, idOffset+i+2, 364815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), 374aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips SkMatrix::I(), 384aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips NULL); 3949f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 404815fe5a0a497b676677fb4e4a0f05c511855490robertphillips GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset+i+1, idOffset+i+2, 414815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 42320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, temp == layer); 43320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 44320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1); 45320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 46320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID()); 470c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1); 480c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2); 490c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips REPORTER_ASSERT(reporter, layer->ctm() == SkMatrix::I()); 50320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, NULL == layer->texture()); 514aa6dfc0b77af9ac298bb9d48991b72a2fec00b2robertphillips REPORTER_ASSERT(reporter, NULL == layer->paint()); 52320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, !layer->isAtlased()); 53320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } 54320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 55320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips cache->trackPicture(&picture); 56320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips} 57952841bf41a81228c23d16c7204b458abe0d7136robertphillips 58320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillipsstatic void lock_layer(skiatest::Reporter* reporter, 59320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips GrLayerCache* cache, 60320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips GrCachedLayer* layer) { 61320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // Make the layer 512x512 (so it can be atlased) 62320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips GrTextureDesc desc; 63320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips desc.fWidth = 512; 64320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips desc.fHeight = 512; 65320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips desc.fConfig = kSkia8888_GrPixelConfig; 66952841bf41a81228c23d16c7204b458abe0d7136robertphillips 676f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips bool needsRerendering = cache->lock(layer, desc, false); 686f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips REPORTER_ASSERT(reporter, needsRerendering); 69952841bf41a81228c23d16c7204b458abe0d7136robertphillips 706f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips needsRerendering = cache->lock(layer, desc, false); 716f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips REPORTER_ASSERT(reporter, !needsRerendering); 72952841bf41a81228c23d16c7204b458abe0d7136robertphillips 7349f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer->texture()); 74320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, layer->locked()); 75952841bf41a81228c23d16c7204b458abe0d7136robertphillips} 76952841bf41a81228c23d16c7204b458abe0d7136robertphillips 77952841bf41a81228c23d16c7204b458abe0d7136robertphillips// This test case exercises the public API of the GrLayerCache class. 78952841bf41a81228c23d16c7204b458abe0d7136robertphillips// In particular it checks its interaction with the resource cache (w.r.t. 79952841bf41a81228c23d16c7204b458abe0d7136robertphillips// locking & unlocking textures). 80952841bf41a81228c23d16c7204b458abe0d7136robertphillips// TODO: need to add checks on VRAM usage! 81952841bf41a81228c23d16c7204b458abe0d7136robertphillipsDEF_GPUTEST(GpuLayerCache, reporter, factory) { 82320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips static const int kInitialNumLayers = 5; 83320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 84e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) { 85e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i; 86952841bf41a81228c23d16c7204b458abe0d7136robertphillips 87e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon if (!GrContextFactory::IsRenderingGLContext(glCtxType)) { 88e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon continue; 89e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 90952841bf41a81228c23d16c7204b458abe0d7136robertphillips 91e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon GrContext* context = factory->get(glCtxType); 92952841bf41a81228c23d16c7204b458abe0d7136robertphillips 93e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon if (NULL == context) { 94e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon continue; 95e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 96952841bf41a81228c23d16c7204b458abe0d7136robertphillips 97e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon SkPictureRecorder recorder; 98e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon recorder.beginRecording(1, 1); 99e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon SkAutoTUnref<const SkPicture> picture(recorder.endRecording()); 100952841bf41a81228c23d16c7204b458abe0d7136robertphillips 101e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon GrLayerCache cache(context); 102952841bf41a81228c23d16c7204b458abe0d7136robertphillips 103320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips create_layers(reporter, &cache, *picture, kInitialNumLayers, 0); 104e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon 105320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips for (int i = 0; i < kInitialNumLayers; ++i) { 1064815fe5a0a497b676677fb4e4a0f05c511855490robertphillips GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 1074815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 10849f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 109952841bf41a81228c23d16c7204b458abe0d7136robertphillips 110320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips lock_layer(reporter, &cache, layer); 111e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon 112e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // The first 4 layers should be in the atlas (and thus have non-empty 113e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // rects) 114e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon if (i < 4) { 115e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon REPORTER_ASSERT(reporter, layer->isAtlased()); 116e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } else { 117320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // The 5th layer couldn't fit in the atlas 118320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, !layer->isAtlased()); 119e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 120e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 121952841bf41a81228c23d16c7204b458abe0d7136robertphillips 122e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // Unlock the textures 123320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips for (int i = 0; i < kInitialNumLayers; ++i) { 1244815fe5a0a497b676677fb4e4a0f05c511855490robertphillips GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 1254815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 12649f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 127e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon cache.unlock(layer); 128e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 129952841bf41a81228c23d16c7204b458abe0d7136robertphillips 130320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips for (int i = 0; i < kInitialNumLayers; ++i) { 1314815fe5a0a497b676677fb4e4a0f05c511855490robertphillips GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 1324815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 13349f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 134952841bf41a81228c23d16c7204b458abe0d7136robertphillips 135320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, !layer->locked()); 136320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // The first 4 layers should still be in the atlas. 137e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon if (i < 4) { 13849f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer->texture()); 139e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon REPORTER_ASSERT(reporter, layer->isAtlased()); 140e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } else { 141320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // The final layer should be unlocked. 142e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon REPORTER_ASSERT(reporter, NULL == layer->texture()); 143e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon REPORTER_ASSERT(reporter, !layer->isAtlased()); 144e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 145e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 146952841bf41a81228c23d16c7204b458abe0d7136robertphillips 147320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips { 148320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // Add an additional layer. Since all the layers are unlocked this 149320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // will force out the first atlased layer 150320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips create_layers(reporter, &cache, *picture, 1, kInitialNumLayers); 1516f294af43bcd94ed9616a7e4f5892589813d0a01robertphillips GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), 1520c4233285919c10df63c6cb207e580a7d1ff66b4robertphillips kInitialNumLayers+1, kInitialNumLayers+2, 1534815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 15449f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 155320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 156320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips lock_layer(reporter, &cache, layer); 157320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips cache.unlock(layer); 158320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } 159320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 160320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips for (int i = 0; i < kInitialNumLayers+1; ++i) { 1614815fe5a0a497b676677fb4e4a0f05c511855490robertphillips GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, i+2, 1624815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkIPoint::Make(0, 0), SkMatrix::I()); 163320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // 3 old layers plus the new one should be in the atlas. 164320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips if (1 == i || 2 == i || 3 == i || 5 == i) { 16549f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 166320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, !layer->locked()); 16749f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer->texture()); 168320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, layer->isAtlased()); 169320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } else if (4 == i) { 170320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // The one that was never atlased should still be around 17149f085dddff10473b6ebf832a974288300224e60bsalomon REPORTER_ASSERT(reporter, layer); 172320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 173320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, NULL == layer->texture()); 174320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, !layer->isAtlased()); 175320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } else { 176320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips // The one bumped out of the atlas (i.e., 0) should be gone 177320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips REPORTER_ASSERT(reporter, NULL == layer); 178320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } 179320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips } 180320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips 181d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips //-------------------------------------------------------------------- 182e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // Free them all SkGpuDevice-style. This will not free up the 183e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // atlas' texture but will eliminate all the layers. 184d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips TestingAccess::Purge(&cache, picture->uniqueID()); 185952841bf41a81228c23d16c7204b458abe0d7136robertphillips 186d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0); 187e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // TODO: add VRAM/resource cache check here 188d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips 189d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips //-------------------------------------------------------------------- 190d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips // Test out the GrContext-style purge. This should remove all the layers 191d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips // and the atlas. 192e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // Re-create the layers 193320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips create_layers(reporter, &cache, *picture, kInitialNumLayers, 0); 194952841bf41a81228c23d16c7204b458abe0d7136robertphillips 195e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // Free them again GrContext-style. This should free up everything. 196e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon cache.freeAll(); 197952841bf41a81228c23d16c7204b458abe0d7136robertphillips 198d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0); 199d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips // TODO: add VRAM/resource cache check here 200d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips 201d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips //-------------------------------------------------------------------- 202d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips // Test out the MessageBus-style purge. This will not free the atlas 203d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips // but should eliminate the free-floating layers. 204320c92380fe6a43dffbcd3f9e7c99897da44298drobertphillips create_layers(reporter, &cache, *picture, kInitialNumLayers, 0); 205d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips 206d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips picture.reset(NULL); 207d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips cache.processDeletedPictures(); 208d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips 209d771f6bc273457bc7aa95938ac326dfbbf876e1arobertphillips REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0); 210e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon // TODO: add VRAM/resource cache check here 211e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 212952841bf41a81228c23d16c7204b458abe0d7136robertphillips} 213952841bf41a81228c23d16c7204b458abe0d7136robertphillips 214952841bf41a81228c23d16c7204b458abe0d7136robertphillips#endif 215