Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "Test.h"
      9 #include "SkBitmap.h"
     10 #include "SkDeferredCanvas.h"
     11 #include "SkShader.h"
     12 
     13 
     14 static const int gWidth = 2;
     15 static const int gHeight = 2;
     16 
     17 static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
     18     bm->setConfig(config, gWidth, gHeight);
     19     bm->allocPixels();
     20     bm->eraseColor(color);
     21 }
     22 
     23 static void TestDeferredCanvasBitmapAccess(skiatest::Reporter* reporter) {
     24     SkBitmap store;
     25 
     26     create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
     27     SkDevice device(store);
     28     SkDeferredCanvas canvas(&device);
     29 
     30     canvas.clear(0x00000000);
     31 
     32     SkAutoLockPixels alp(store);
     33     REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred
     34     SkBitmap accessed = canvas.getDevice()->accessBitmap(false);
     35     REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed
     36     REPORTER_ASSERT(reporter, accessed.pixelRef() == store.pixelRef());
     37 }
     38 
     39 static void TestDeferredCanvasFlush(skiatest::Reporter* reporter) {
     40     SkBitmap store;
     41 
     42     create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
     43     SkDevice device(store);
     44     SkDeferredCanvas canvas(&device);
     45 
     46     canvas.clear(0x00000000);
     47 
     48     SkAutoLockPixels alp(store);
     49     REPORTER_ASSERT(reporter, store.getColor(0,0) == 0xFFFFFFFF); //verify that clear was deferred
     50     canvas.flush();
     51     REPORTER_ASSERT(reporter, store.getColor(0,0) == 0x00000000); //verify that clear was executed
     52 }
     53 
     54 static void TestDeferredCanvasFreshFrame(skiatest::Reporter* reporter) {
     55     SkBitmap store;
     56     SkRect fullRect;
     57     fullRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(gWidth),
     58         SkIntToScalar(gHeight));
     59     SkRect partialRect;
     60     partialRect.setXYWH(SkIntToScalar(0), SkIntToScalar(0),
     61         SkIntToScalar(1), SkIntToScalar(1));
     62     create(&store, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
     63     SkDevice device(store);
     64     SkDeferredCanvas canvas(&device);
     65 
     66     // verify that frame is intially fresh
     67     REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
     68     // no clearing op since last call to isFreshFrame -> not fresh
     69     REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
     70 
     71     // Verify that clear triggers a fresh frame
     72     canvas.clear(0x00000000);
     73     REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
     74 
     75     // Verify that clear with saved state triggers a fresh frame
     76     canvas.save(SkCanvas::kMatrixClip_SaveFlag);
     77     canvas.clear(0x00000000);
     78     canvas.restore();
     79     REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
     80 
     81     // Verify that clear within a layer does NOT trigger a fresh frame
     82     canvas.saveLayer(NULL, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
     83     canvas.clear(0x00000000);
     84     canvas.restore();
     85     REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
     86 
     87     // Verify that a clear with clipping triggers a fresh frame
     88     // (clear is not affected by clipping)
     89     canvas.save(SkCanvas::kMatrixClip_SaveFlag);
     90     canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false);
     91     canvas.clear(0x00000000);
     92     canvas.restore();
     93     REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
     94 
     95     // Verify that full frame rects with different forms of opaque paint
     96     // trigger frames to be marked as fresh
     97     {
     98         SkPaint paint;
     99         paint.setStyle( SkPaint::kFill_Style );
    100         paint.setAlpha( 255 );
    101         canvas.drawRect(fullRect, paint);
    102         REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
    103     }
    104     {
    105         SkPaint paint;
    106         paint.setStyle( SkPaint::kFill_Style );
    107         SkBitmap bmp;
    108         create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    109         bmp.setIsOpaque(true);
    110         SkShader* shader = SkShader::CreateBitmapShader(bmp,
    111             SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    112         paint.setShader(shader)->unref();
    113         canvas.drawRect(fullRect, paint);
    114         REPORTER_ASSERT(reporter, canvas.getDeferredDevice()->isFreshFrame());
    115     }
    116 
    117     // Verify that full frame rects with different forms of non-opaque paint
    118     // do not trigger frames to be marked as fresh
    119     {
    120         SkPaint paint;
    121         paint.setStyle( SkPaint::kFill_Style );
    122         paint.setAlpha( 254 );
    123         canvas.drawRect(fullRect, paint);
    124         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    125     }
    126     {
    127         SkPaint paint;
    128         paint.setStyle( SkPaint::kFill_Style );
    129         SkBitmap bmp;
    130         create(&bmp, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
    131         bmp.setIsOpaque(false);
    132         SkShader* shader = SkShader::CreateBitmapShader(bmp,
    133             SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
    134         paint.setShader(shader)->unref();
    135         canvas.drawRect(fullRect, paint);
    136         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    137     }
    138 
    139     // Verify that incomplete coverage does not trigger a fresh frame
    140     {
    141         SkPaint paint;
    142         paint.setStyle(SkPaint::kFill_Style);
    143         paint.setAlpha(255);
    144         canvas.drawRect(partialRect, paint);
    145         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    146     }
    147 
    148     // Verify that incomplete coverage due to clipping does not trigger a fresh
    149     // frame
    150     {
    151         canvas.save(SkCanvas::kMatrixClip_SaveFlag);
    152         canvas.clipRect(partialRect, SkRegion::kIntersect_Op, false);
    153         SkPaint paint;
    154         paint.setStyle(SkPaint::kFill_Style);
    155         paint.setAlpha(255);
    156         canvas.drawRect(fullRect, paint);
    157         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    158     }
    159 
    160     // Verify that stroked rect does not trigger a fresh frame
    161     {
    162         SkPaint paint;
    163         paint.setStyle( SkPaint::kStroke_Style );
    164         paint.setAlpha( 255 );
    165         canvas.drawRect(fullRect, paint);
    166         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    167     }
    168 
    169     // Verify kSrcMode triggers a fresh frame even with transparent color
    170     {
    171         SkPaint paint;
    172         paint.setStyle( SkPaint::kFill_Style );
    173         paint.setAlpha( 100 );
    174         paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    175         canvas.drawRect(fullRect, paint);
    176         REPORTER_ASSERT(reporter, !canvas.getDeferredDevice()->isFreshFrame());
    177     }
    178 }
    179 
    180 static void TestDeferredCanvas(skiatest::Reporter* reporter) {
    181     TestDeferredCanvasBitmapAccess(reporter);
    182     TestDeferredCanvasFlush(reporter);
    183     TestDeferredCanvasFreshFrame(reporter);
    184 }
    185 
    186 #include "TestClassDef.h"
    187 DEFINE_TESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanvas)
    188