Home | History | Annotate | Download | only in tests
      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 
     16 static const int X_SIZE = 12;
     17 static const int Y_SIZE = 12;
     18 
     19 ////////////////////////////////////////////////////////////////////////////////
     20 // note: this is unused
     21 static 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
     45 static 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;
     65 
     66     screen = SkRect::MakeWH(SkIntToScalar(kXSize),
     67                             SkIntToScalar(kYSize));
     68 
     69     SkRect clipRect(screen);
     70     clipRect.outset(10, 10);
     71 
     72     // create a clip stack that will (trivially) reduce to a single rect that
     73     // is larger than the screen
     74     SkClipStack stack;
     75     stack.clipDevRect(clipRect, SkRegion::kReplace_Op, false);
     76 
     77     bool isIntersectionOfRects = true;
     78     SkRect devStackBounds;
     79 
     80     stack.getConservativeBounds(0, 0, kXSize, kYSize,
     81                                 &devStackBounds,
     82                                 &isIntersectionOfRects);
     83 
     84     // make sure that the SkClipStack is behaving itself
     85     REPORTER_ASSERT(reporter, screen == devStackBounds);
     86     REPORTER_ASSERT(reporter, isIntersectionOfRects);
     87 
     88     // wrap the SkClipStack in a GrClipData
     89     GrClipData clipData;
     90     clipData.fClipStack = &stack;
     91 
     92     SkIRect devGrClipDataBound;
     93     clipData.getConservativeBounds(texture,
     94                                    &devGrClipDataBound,
     95                                    &isIntersectionOfRects);
     96 
     97     // make sure that GrClipData is behaving itself
     98     REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound);
     99     REPORTER_ASSERT(reporter, isIntersectionOfRects);
    100 }
    101 
    102 ////////////////////////////////////////////////////////////////////////////////
    103 // verify that the top state of the stack matches the passed in state
    104 static void check_state(skiatest::Reporter* reporter,
    105                         const GrClipMaskCache& cache,
    106                         const SkClipStack& clip,
    107                         GrTexture* mask,
    108                         const SkIRect& bound) {
    109     SkClipStack cacheClip;
    110     REPORTER_ASSERT(reporter, clip.getTopmostGenID() == cache.getLastClipGenID());
    111 
    112     REPORTER_ASSERT(reporter, mask == cache.getLastMask());
    113 
    114     SkIRect cacheBound;
    115     cache.getLastBound(&cacheBound);
    116     REPORTER_ASSERT(reporter, bound == cacheBound);
    117 }
    118 
    119 ////////////////////////////////////////////////////////////////////////////////
    120 // basic test of the cache's base functionality:
    121 //  push, pop, set, canReuse & getters
    122 static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
    123 
    124     if (false) { // avoid bit rot, suppress warning
    125         createTexture(context);
    126     }
    127     GrClipMaskCache cache;
    128 
    129     cache.setContext(context);
    130 
    131     SkClipStack emptyClip;
    132     emptyClip.reset();
    133 
    134     SkIRect emptyBound;
    135     emptyBound.setEmpty();
    136 
    137     // check initial state
    138     check_state(reporter, cache, emptyClip, NULL, emptyBound);
    139 
    140     // set the current state
    141     SkIRect bound1;
    142     bound1.set(0, 0, 100, 100);
    143 
    144     SkClipStack clip1(bound1);
    145 
    146     GrTextureDesc desc;
    147     desc.fFlags = kRenderTarget_GrTextureFlagBit;
    148     desc.fWidth = X_SIZE;
    149     desc.fHeight = Y_SIZE;
    150     desc.fConfig = kSkia8888_GrPixelConfig;
    151 
    152     cache.acquireMask(clip1.getTopmostGenID(), desc, bound1);
    153 
    154     GrTexture* texture1 = cache.getLastMask();
    155     REPORTER_ASSERT(reporter, texture1);
    156     if (NULL == texture1) {
    157         return;
    158     }
    159 
    160     // check that the set took
    161     check_state(reporter, cache, clip1, texture1, bound1);
    162     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    163 
    164     // push the state
    165     cache.push();
    166 
    167     // verify that the pushed state is initially empty
    168     check_state(reporter, cache, emptyClip, NULL, emptyBound);
    169     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    170 
    171     // modify the new state
    172     SkIRect bound2;
    173     bound2.set(-10, -10, 10, 10);
    174 
    175     SkClipStack clip2(bound2);
    176 
    177     cache.acquireMask(clip2.getTopmostGenID(), desc, bound2);
    178 
    179     GrTexture* texture2 = cache.getLastMask();
    180     REPORTER_ASSERT(reporter, texture2);
    181     if (NULL == texture2) {
    182         return;
    183     }
    184 
    185     // check that the changes took
    186     check_state(reporter, cache, clip2, texture2, bound2);
    187     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    188     REPORTER_ASSERT(reporter, texture2->getRefCnt());
    189 
    190     // check to make sure canReuse works
    191     REPORTER_ASSERT(reporter, cache.canReuse(clip2.getTopmostGenID(), bound2));
    192     REPORTER_ASSERT(reporter, !cache.canReuse(clip1.getTopmostGenID(), bound1));
    193 
    194     // pop the state
    195     cache.pop();
    196 
    197     // verify that the old state is restored
    198     check_state(reporter, cache, clip1, texture1, bound1);
    199     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    200     REPORTER_ASSERT(reporter, texture2->getRefCnt());
    201 
    202     // manually clear the state
    203     cache.reset();
    204 
    205     // verify it is now empty
    206     check_state(reporter, cache, emptyClip, NULL, emptyBound);
    207     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    208     REPORTER_ASSERT(reporter, texture2->getRefCnt());
    209 
    210     // pop again - so there is no state
    211     cache.pop();
    212 
    213 #if !defined(SK_DEBUG)
    214     // verify that the getters don't crash
    215     // only do in release since it generates asserts in debug
    216     check_state(reporter, cache, emptyClip, NULL, emptyBound);
    217 #endif
    218     REPORTER_ASSERT(reporter, texture1->getRefCnt());
    219     REPORTER_ASSERT(reporter, texture2->getRefCnt());
    220 }
    221 
    222 ////////////////////////////////////////////////////////////////////////////////
    223 static void TestClipCache(skiatest::Reporter* reporter, GrContextFactory* factory) {
    224     for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
    225         GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
    226         if (!GrContextFactory::IsRenderingGLContext(glType)) {
    227             continue;
    228         }
    229         GrContext* context = factory->get(glType);
    230         if (NULL == context) {
    231             continue;
    232         }
    233 
    234         test_cache(reporter, context);
    235         test_clip_bounds(reporter, context);
    236     }
    237 }
    238 
    239 ////////////////////////////////////////////////////////////////////////////////
    240 #include "TestClassDef.h"
    241 DEFINE_GPUTESTCLASS("ClipCache", ClipCacheTestClass, TestClipCache)
    242 
    243 #endif
    244