• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
create(SkBitmap * bm,SkBitmap::Config config,SkColor color)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 
TestDeferredCanvasBitmapAccess(skiatest::Reporter * reporter)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 
TestDeferredCanvasFlush(skiatest::Reporter * reporter)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 
TestDeferredCanvasFreshFrame(skiatest::Reporter * reporter)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 
TestDeferredCanvas(skiatest::Reporter * reporter)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