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 14static const int gWidth = 2; 15static const int gHeight = 2; 16 17static void create(SkBitmap* bm, SkBitmap::Config config, SkColor color) { 18 bm->setConfig(config, gWidth, gHeight); 19 bm->allocPixels(); 20 bm->eraseColor(color); 21} 22 23static 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 39static 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 54static 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 180static void TestDeferredCanvas(skiatest::Reporter* reporter) { 181 TestDeferredCanvasBitmapAccess(reporter); 182 TestDeferredCanvasFlush(reporter); 183 TestDeferredCanvasFreshFrame(reporter); 184} 185 186#include "TestClassDef.h" 187DEFINE_TESTCLASS("DeferredCanvas", TestDeferredCanvasClass, TestDeferredCanvas) 188