ClipCacheTest.cpp revision fec0bc3fc13481f5bcb341ab2d2d695911f39bd4
1/* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9#include "Test.h" 10// This is a GR test 11#if SK_SUPPORT_GPU 12#include "GrContextFactory.h" 13#include "SkGpuDevice.h" 14#include "../../src/gpu/GrClipMaskManager.h" 15 16static const int X_SIZE = 12; 17static const int Y_SIZE = 12; 18 19//////////////////////////////////////////////////////////////////////////////// 20// note: this is unused 21static GrTexture* createTexture(GrContext* context) { 22 unsigned char textureData[X_SIZE][Y_SIZE][4]; 23 24 memset(textureData, 0, 4* X_SIZE * Y_SIZE); 25 26 GrTextureDesc desc; 27 28 // let Skia know we will be using this texture as a render target 29 desc.fFlags = kRenderTarget_GrTextureFlagBit; 30 desc.fConfig = kSkia8888_GrPixelConfig; 31 desc.fWidth = X_SIZE; 32 desc.fHeight = Y_SIZE; 33 34 // We are initializing the texture with zeros here 35 GrTexture* texture = context->createUncachedTexture(desc, textureData, 0); 36 if (!texture) { 37 return NULL; 38 } 39 40 return texture; 41} 42 43// Ensure that the 'getConservativeBounds' calls are returning bounds clamped 44// to the render target 45static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) { 46 47 static const int kXSize = 100; 48 static const int kYSize = 100; 49 50 GrTextureDesc desc; 51 desc.fFlags = kRenderTarget_GrTextureFlagBit; 52 desc.fConfig = kAlpha_8_GrPixelConfig; 53 desc.fWidth = kXSize; 54 desc.fHeight = kYSize; 55 56 GrTexture* texture = context->createUncachedTexture(desc, NULL, 0); 57 if (!texture) { 58 return; 59 } 60 61 GrAutoUnref au(texture); 62 63 SkIRect intScreen = SkIRect::MakeWH(kXSize, kYSize); 64 SkRect screen = SkRect::MakeWH(SkIntToScalar(kXSize), 65 SkIntToScalar(kYSize)); 66 SkRect clipRect(screen); 67 clipRect.outset(10, 10); 68 69 // create a clip stack that will (trivially) reduce to a single rect that 70 // is larger than the screen 71 SkClipStack stack; 72 stack.clipDevRect(clipRect, SkRegion::kReplace_Op, false); 73 74 bool isIntersectionOfRects = true; 75 SkRect devStackBounds; 76 77 stack.getConservativeBounds(0, 0, kXSize, kYSize, 78 &devStackBounds, 79 &isIntersectionOfRects); 80 81 // make sure that the SkClipStack is behaving itself 82 REPORTER_ASSERT(reporter, screen == devStackBounds); 83 REPORTER_ASSERT(reporter, isIntersectionOfRects); 84 85 // wrap the SkClipStack in a GrClipData 86 GrClipData clipData; 87 clipData.fClipStack = &stack; 88 89 SkIRect devGrClipDataBound; 90 clipData.getConservativeBounds(texture, 91 &devGrClipDataBound, 92 &isIntersectionOfRects); 93 94 // make sure that GrClipData is behaving itself 95 REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound); 96 REPORTER_ASSERT(reporter, isIntersectionOfRects); 97} 98 99//////////////////////////////////////////////////////////////////////////////// 100// verify that the top state of the stack matches the passed in state 101static void check_state(skiatest::Reporter* reporter, 102 const GrClipMaskCache& cache, 103 const SkClipStack& clip, 104 GrTexture* mask, 105 const GrIRect& bound) { 106 SkClipStack cacheClip; 107 REPORTER_ASSERT(reporter, clip.getTopmostGenID() == cache.getLastClipGenID()); 108 109 REPORTER_ASSERT(reporter, mask == cache.getLastMask()); 110 111 GrIRect cacheBound; 112 cache.getLastBound(&cacheBound); 113 REPORTER_ASSERT(reporter, bound == cacheBound); 114} 115 116//////////////////////////////////////////////////////////////////////////////// 117// basic test of the cache's base functionality: 118// push, pop, set, canReuse & getters 119static void test_cache(skiatest::Reporter* reporter, GrContext* context) { 120 121 if (false) { // avoid bit rot, suppress warning 122 createTexture(context); 123 } 124 GrClipMaskCache cache; 125 126 cache.setContext(context); 127 128 SkClipStack emptyClip; 129 emptyClip.reset(); 130 131 GrIRect emptyBound; 132 emptyBound.setEmpty(); 133 134 // check initial state 135 check_state(reporter, cache, emptyClip, NULL, emptyBound); 136 137 // set the current state 138 GrIRect bound1; 139 bound1.set(0, 0, 100, 100); 140 141 SkClipStack clip1(bound1); 142 143 GrTextureDesc desc; 144 desc.fFlags = kRenderTarget_GrTextureFlagBit; 145 desc.fWidth = X_SIZE; 146 desc.fHeight = Y_SIZE; 147 desc.fConfig = kSkia8888_GrPixelConfig; 148 149 cache.acquireMask(clip1.getTopmostGenID(), desc, bound1); 150 151 GrTexture* texture1 = cache.getLastMask(); 152 REPORTER_ASSERT(reporter, texture1); 153 if (NULL == texture1) { 154 return; 155 } 156 157 // check that the set took 158 check_state(reporter, cache, clip1, texture1, bound1); 159 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 160 161 // push the state 162 cache.push(); 163 164 // verify that the pushed state is initially empty 165 check_state(reporter, cache, emptyClip, NULL, emptyBound); 166 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 167 168 // modify the new state 169 GrIRect bound2; 170 bound2.set(-10, -10, 10, 10); 171 172 SkClipStack clip2(bound2); 173 174 cache.acquireMask(clip2.getTopmostGenID(), desc, bound2); 175 176 GrTexture* texture2 = cache.getLastMask(); 177 REPORTER_ASSERT(reporter, texture2); 178 if (NULL == texture2) { 179 return; 180 } 181 182 // check that the changes took 183 check_state(reporter, cache, clip2, texture2, bound2); 184 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 185 REPORTER_ASSERT(reporter, texture2->getRefCnt()); 186 187 // check to make sure canReuse works 188 REPORTER_ASSERT(reporter, cache.canReuse(clip2.getTopmostGenID(), bound2)); 189 REPORTER_ASSERT(reporter, !cache.canReuse(clip1.getTopmostGenID(), bound1)); 190 191 // pop the state 192 cache.pop(); 193 194 // verify that the old state is restored 195 check_state(reporter, cache, clip1, texture1, bound1); 196 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 197 REPORTER_ASSERT(reporter, texture2->getRefCnt()); 198 199 // manually clear the state 200 cache.reset(); 201 202 // verify it is now empty 203 check_state(reporter, cache, emptyClip, NULL, emptyBound); 204 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 205 REPORTER_ASSERT(reporter, texture2->getRefCnt()); 206 207 // pop again - so there is no state 208 cache.pop(); 209 210#if !defined(SK_DEBUG) 211 // verify that the getters don't crash 212 // only do in release since it generates asserts in debug 213 check_state(reporter, cache, emptyClip, NULL, emptyBound); 214#endif 215 REPORTER_ASSERT(reporter, texture1->getRefCnt()); 216 REPORTER_ASSERT(reporter, texture2->getRefCnt()); 217} 218 219//////////////////////////////////////////////////////////////////////////////// 220static void TestClipCache(skiatest::Reporter* reporter, GrContextFactory* factory) { 221 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 222 GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type); 223 if (!GrContextFactory::IsRenderingGLContext(glType)) { 224 continue; 225 } 226 GrContext* context = factory->get(glType); 227 if (NULL == context) { 228 continue; 229 } 230 231 test_cache(reporter, context); 232 test_clip_bounds(reporter, context); 233 } 234} 235 236//////////////////////////////////////////////////////////////////////////////// 237#include "TestClassDef.h" 238DEFINE_GPUTESTCLASS("ClipCache", ClipCacheTestClass, TestClipCache) 239 240#endif 241