Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: gm/bleed.cpp

Issue 1424473006: Rewrite bleed GM bmp/img generators and change oversized texture case (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "gm.h" 8 #include "gm.h"
9 #include "SkBlurMask.h" 9 #include "SkBlurMask.h"
10 #include "SkBlurMaskFilter.h" 10 #include "SkBlurMaskFilter.h"
11 #include "SkCanvas.h" 11 #include "SkCanvas.h"
12 #include "SkGradientShader.h" 12 #include "SkGradientShader.h"
13 #include "SkImage.h" 13 #include "SkImage.h"
14 #include "SkUtils.h" 14 #include "SkUtils.h"
15 15
16 #if SK_SUPPORT_GPU 16 #if SK_SUPPORT_GPU
17 #include "GrContext.h" 17 #include "GrContext.h"
18 #include "GrContextOptions.h" 18 #include "GrContextOptions.h"
19 #include "SkGr.h" 19 #include "SkGr.h"
20 #endif 20 #endif
21 21
22 static void draw_bitmap_rect(SkCanvas* canvas, const SkBitmap& bitmap, const SkI mage*, 22 /** Holds either a bitmap or image to be rendered and a rect that indicates what part of the bitmap
23 const SkRect& src, const SkRect& dst, 23 or image should be tested by the GM. The area outside of the rect is present to check
24 const SkPaint* paint, SkCanvas::SrcRectConstraint c onstraint) { 24 for bleed due to filtering/blurring. */
25 canvas->drawBitmapRect(bitmap, src, dst, paint, constraint); 25 struct TestPixels {
26 } 26 enum Type {
27 27 kBitmap,
28 static void draw_image_rect(SkCanvas* canvas, const SkBitmap&, const SkImage* im age, 28 kImage
29 const SkRect& src, const SkRect& dst, 29 };
30 const SkPaint* paint, SkCanvas::SrcRectConstraint co nstraint) { 30 Type fType;
31 canvas->drawImageRect(image, src, dst, paint, constraint); 31 SkBitmap fBitmap;
32 } 32 SkAutoTUnref<SkImage> fImage;
33 33 SkIRect fRect; // The region of the bitmap/image that should be rendered.
34 // Upload the tight-fitting sw-backed bitmap to a loose-fitting gpu-backed textu re before drawing 34 };
35 static void draw_texture_bitmap_rect(SkCanvas* canvas, const SkBitmap& bitmap, c onst SkImage*, 35
36 const SkRect& src, const SkRect& dst, 36 /** Creates a bitmap with two one-pixel rings around a checkerboard. The checker board is 2x2
37 const SkPaint* paint, 37 logically where each check has as many pixels as is necessary to fill the in terior. The rect
38 SkCanvas::SrcRectConstraint constraint) { 38 to draw is set to the checkerboard portion. */
39 GrContext* context = canvas->getGrContext(); 39 template<typename PIXEL_TYPE>
40 if (!context) { 40 bool make_ringed_bitmap(GrContext*, TestPixels* result, int width, int height,
41 // For non-GPU canvases fallback to drawing the bitmap directly. 41 SkColorType ct, SkAlphaType at,
42 canvas->drawBitmapRect(bitmap, src, dst, paint, constraint); 42 PIXEL_TYPE outerRingColor, PIXEL_TYPE innerRingColor,
43 return; 43 PIXEL_TYPE checkColor1, PIXEL_TYPE checkColor2) {
44 }
45 #if SK_SUPPORT_GPU
46 GrSurfaceDesc desc;
47 desc.fConfig = kAlpha_8_SkColorType == bitmap.colorType() ? kAlpha_8_GrPixel Config :
48 kSkia8888_GrPixe lConfig;
49 // Add some padding to the right and beneath the bitmap contents to exercise the case where
50 // the texture is larger than the bitmap. Outsets chosen to be small and dif ferent.
51 desc.fWidth = bitmap.width() + 16;
52 desc.fHeight = bitmap.height() + 23;
53 SkAutoTUnref<GrTexture> texture(context->textureProvider()->createTexture(de sc, true));
54 if (!texture) {
55 return;
56 }
57 // Init the whole texture to 0 in the alpha case or solid green in the 32bit rgba case.
58 SkAutoLockPixels al(bitmap);
59 if (kAlpha_8_GrPixelConfig == texture->config()) {
60 SkAutoMalloc pixels(texture->width() * texture->height());
61 memset(pixels.get(), 0, texture->width() * texture->height());
62 texture->writePixels(0, 0, texture->width(), texture->height(), desc.fCo nfig, pixels.get(),
63 0);
64 } else {
65 SkAutoMalloc pixels(texture->width() * texture->height() * sizeof(uint32 _t));
66 SkOpts::memset32((uint32_t*)pixels.get(), 0xFF00FF00, texture->width()*t exture->height());
67 texture->writePixels(0, 0, texture->width(), texture->height(), desc.fCo nfig, pixels.get(),
68 0);
69 }
70
71 // Upload the bitmap contents to the upper left.
72 texture->writePixels(0, 0, bitmap.width(), bitmap.height(), desc.fConfig, bi tmap.getPixels(),
73 bitmap.rowBytes());
74
75 // Wrap the texture in a bitmap and draw it.
76 SkBitmap textureBmp;
77 GrWrapTextureInBitmap(texture, bitmap.width(), bitmap.height(), true, &textu reBmp);
78 canvas->drawBitmapRect(textureBmp, src, dst, paint, constraint);
79 #endif
80 }
81
82 // Create a black&white checked texture with 2 1-pixel rings
83 // around the outside edge. The inner ring is red and the outer ring is blue.
84 static void make_ringed_color_bitmap(SkBitmap* result, int width, int height) {
85 SkASSERT(0 == width % 2 && 0 == height % 2); 44 SkASSERT(0 == width % 2 && 0 == height % 2);
86 45 SkASSERT(width >= 6 && height >= 6);
87 static const SkPMColor kRed = SkPreMultiplyColor(SK_ColorRED); 46
88 static const SkPMColor kBlue = SkPreMultiplyColor(SK_ColorBLUE); 47 result->fType = TestPixels::kBitmap;
48 SkImageInfo info = SkImageInfo::Make(width, height, ct, at);
49 size_t rowBytes = SkAlign4(info.minRowBytes());
50 result->fBitmap.allocPixels(info, rowBytes);
51
52 PIXEL_TYPE* scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, 0);
53 for (int x = 0; x < width; ++x) {
54 scanline[x] = outerRingColor;
55 }
56 scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, 1);
57 scanline[0] = outerRingColor;
58 for (int x = 1; x < width - 1; ++x) {
59 scanline[x] = innerRingColor;
60 }
61 scanline[width - 1] = outerRingColor;
62
63 for (int y = 2; y < height / 2; ++y) {
64 scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, y);
65 scanline[0] = outerRingColor;
66 scanline[1] = innerRingColor;
67 for (int x = 2; x < width / 2; ++x) {
68 scanline[x] = checkColor1;
69 }
70 for (int x = width / 2; x < width - 2; ++x) {
71 scanline[x] = checkColor2;
72 }
73 scanline[width - 2] = innerRingColor;
74 scanline[width - 1] = outerRingColor;
75 }
76
77 for (int y = height / 2; y < height - 2; ++y) {
78 scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, y);
79 scanline[0] = outerRingColor;
80 scanline[1] = innerRingColor;
81 for (int x = 2; x < width / 2; ++x) {
82 scanline[x] = checkColor2;
83 }
84 for (int x = width / 2; x < width - 2; ++x) {
85 scanline[x] = checkColor1;
86 }
87 scanline[width - 2] = innerRingColor;
88 scanline[width - 1] = outerRingColor;
89 }
90
91 scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, height - 2);
92 scanline[0] = outerRingColor;
93 for (int x = 1; x < width - 1; ++x) {
94 scanline[x] = innerRingColor;
95 }
96 scanline[width - 1] = outerRingColor;
97
98 scanline = (PIXEL_TYPE*)result->fBitmap.getAddr(0, height - 1);
99 for (int x = 0; x < width; ++x) {
100 scanline[x] = outerRingColor;
101 }
102 result->fBitmap.setImmutable();
103 result->fRect.set(2, 2, width - 2, height - 2);
104 return true;
105 }
106
107 /** Create a black and white checked texture with 2 1-pixel rings around the out side edge.
108 The inner ring is red and the outer ring is blue. */
109 static bool make_ringed_color_bitmap(GrContext* ctx, TestPixels* result, int wid th, int height) {
110 static const SkPMColor kBlue = SkPreMultiplyColor(SK_ColorBLUE);
111 static const SkPMColor kRed = SkPreMultiplyColor(SK_ColorRED);
89 static const SkPMColor kBlack = SkPreMultiplyColor(SK_ColorBLACK); 112 static const SkPMColor kBlack = SkPreMultiplyColor(SK_ColorBLACK);
90 static const SkPMColor kWhite = SkPreMultiplyColor(SK_ColorWHITE); 113 static const SkPMColor kWhite = SkPreMultiplyColor(SK_ColorWHITE);
91 114 return make_ringed_bitmap<SkPMColor>(ctx, result, width, height, kBGRA_8888_ SkColorType,
92 result->allocN32Pixels(width, height, true); 115 kPremul_SkAlphaType, kBlue, kRed, kBlac k, kWhite);
93
94 SkPMColor* scanline = result->getAddr32(0, 0);
95 for (int x = 0; x < width; ++x) {
96 scanline[x] = kBlue;
97 }
98 scanline = result->getAddr32(0, 1);
99 scanline[0] = kBlue;
100 for (int x = 1; x < width - 1; ++x) {
101 scanline[x] = kRed;
102 }
103 scanline[width-1] = kBlue;
104
105 for (int y = 2; y < height/2; ++y) {
106 scanline = result->getAddr32(0, y);
107 scanline[0] = kBlue;
108 scanline[1] = kRed;
109 for (int x = 2; x < width/2; ++x) {
110 scanline[x] = kBlack;
111 }
112 for (int x = width/2; x < width-2; ++x) {
113 scanline[x] = kWhite;
114 }
115 scanline[width-2] = kRed;
116 scanline[width-1] = kBlue;
117 }
118
119 for (int y = height/2; y < height-2; ++y) {
120 scanline = result->getAddr32(0, y);
121 scanline[0] = kBlue;
122 scanline[1] = kRed;
123 for (int x = 2; x < width/2; ++x) {
124 scanline[x] = kWhite;
125 }
126 for (int x = width/2; x < width-2; ++x) {
127 scanline[x] = kBlack;
128 }
129 scanline[width-2] = kRed;
130 scanline[width-1] = kBlue;
131 }
132
133 scanline = result->getAddr32(0, height-2);
134 scanline[0] = kBlue;
135 for (int x = 1; x < width - 1; ++x) {
136 scanline[x] = kRed;
137 }
138 scanline[width-1] = kBlue;
139
140 scanline = result->getAddr32(0, height-1);
141 for (int x = 0; x < width; ++x) {
142 scanline[x] = kBlue;
143 }
144 result->setImmutable();
145 } 116 }
146 117
147 /** Makes a alpha bitmap with 1 wide rect/ring of 0s, an inset of 1s, and the in terior is a 2x2 118 /** Makes a alpha bitmap with 1 wide rect/ring of 0s, an inset of 1s, and the in terior is a 2x2
148 checker board of 3/4 and 1/2. The inner checkers are large enough to fill th e interior with 119 checker board of 3/4 and 1/2. The inner checkers are large enough to fill th e interior with
149 the 2x2 checker grid. */ 120 the 2x2 checker grid. */
150 static void make_ringed_alpha_bitmap(SkBitmap* result, int width, int height) { 121 static bool make_ringed_alpha_bitmap(GrContext* ctx, TestPixels* result, int wid th, int height) {
122 static const uint8_t kZero = 0x00;
123 static const uint8_t kHalf = 0x80;
124 static const uint8_t k3Q = 0xC0;
125 static const uint8_t kOne = 0xFF;
126 return make_ringed_bitmap<uint8_t>(ctx, result, width, height, kAlpha_8_SkCo lorType,
127 kPremul_SkAlphaType, kZero, kOne, k3Q, kH alf);
128 }
129
130 /** Helper to reuse above functions to produce images rather than bmps */
131 static void bmp_to_image(TestPixels* result) {
132 SkASSERT(TestPixels::kBitmap == result->fType);
133 result->fImage.reset(SkImage::NewFromBitmap(result->fBitmap));
134 SkASSERT(result->fImage);
135 result->fType = TestPixels::kImage;
136 result->fBitmap.reset();
137 }
138
139 /** Color image case. */
140 bool make_ringed_color_image(GrContext* ctx, TestPixels* result, int width, int height) {
141 if (make_ringed_color_bitmap(ctx, result, width, height)) {
142 bmp_to_image(result);
143 return true;
144 }
145 return false;
146 }
147
148 /** Alpha image case. */
149 bool make_ringed_alpha_image(GrContext* ctx, TestPixels* result, int width, int height) {
150 if (make_ringed_alpha_bitmap(ctx, result, width, height)) {
151 bmp_to_image(result);
152 return true;
153 }
154 return false;
155 }
156
157 /** Similar to make_ringed_bitmap with these modifications:
158 - The backing store is a texture.
159 - The texture is larger than the bitmap dimensions (it is surrounded by non-content
160 padding on the right/bottom of the contents.)
161 - The right/bottom sides of the rings are omitted so that the rect to dr aw is adjacent to
162 the texture padding.
163 */
164 template <typename PIXEL_TYPE>
165 bool make_oversized_texture_bitmap(GrContext* ctx, TestPixels* result, int width , int height,
166 GrPixelConfig config, PIXEL_TYPE outerRingCol or,
167 PIXEL_TYPE innerRingColor, PIXEL_TYPE checkCo lor1,
168 PIXEL_TYPE checkColor2, PIXEL_TYPE padColor) {
151 SkASSERT(0 == width % 2 && 0 == height % 2); 169 SkASSERT(0 == width % 2 && 0 == height % 2);
152 170 SkASSERT(width >= 6 && height >= 6);
153 static const SkPMColor kZero = 0x00; 171 #if SK_SUPPORT_GPU
154 static const SkPMColor kHalf = 0x80; 172 if (!ctx) {
155 static const SkPMColor k3Q = 0xC0; 173 return false;
156 static const SkPMColor kOne = 0xFF; 174 }
157 SkImageInfo info = SkImageInfo::MakeA8(width, height); 175 /** Put arbitrary pad to the right and below the bitmap content. */
158 // The 4 byte alignment seems to be necessary to allow this bmp to be conver ted 176 static const int kXPad = 10;
159 // to an image. 177 static const int kYPad = 17;
160 result->allocPixels(info, SkAlign4(width)); 178 size_t rowBytes = (width + kXPad) * sizeof(PIXEL_TYPE);
161 179 SkAutoTMalloc<PIXEL_TYPE> pixels(rowBytes*(height + kYPad));
162 uint8_t* scanline = result->getAddr8(0, 0); 180
181 PIXEL_TYPE* scanline = pixels.get();
163 for (int x = 0; x < width; ++x) { 182 for (int x = 0; x < width; ++x) {
164 scanline[x] = kOne; 183 scanline[x] = outerRingColor;
165 } 184 }
166 scanline = result->getAddr8(0, 1); 185 for (int x = width; x < width + kXPad; ++x) {
167 scanline[0] = kOne; 186 scanline[x] = padColor;
168 for (int x = 1; x < width - 1; ++x) { 187 }
169 scanline[x] = kOne; 188
170 } 189 scanline = (PIXEL_TYPE*)((char*)scanline + rowBytes);
171 scanline[width - 1] = kZero; 190 scanline[0] = outerRingColor;
172 191 for (int x = 1; x < width; ++x) {
173 for (int y = 2; y < height / 2; ++y) { 192 scanline[x] = innerRingColor;
174 scanline = result->getAddr8(0, y); 193 }
175 scanline[0] = kZero; 194 for (int x = width; x < width + kXPad; ++x) {
176 scanline[1] = kOne; 195 scanline[x] = padColor;
177 for (int x = 2; x < width / 2; ++x) { 196 }
178 scanline[x] = k3Q; 197
179 } 198 for (int y = 2; y < height / 2 + 1; ++y) {
180 for (int x = width / 2; x < width - 2; ++x) { 199 scanline = (PIXEL_TYPE*)((char*)scanline + rowBytes);
181 scanline[x] = kHalf; 200 scanline[0] = outerRingColor;
182 } 201 scanline[1] = innerRingColor;
183 scanline[width - 2] = kOne; 202 for (int x = 2; x < width / 2 + 1; ++x) {
184 scanline[width - 1] = kZero; 203 scanline[x] = checkColor1;
185 } 204 }
186 205 for (int x = width / 2 + 1; x < width; ++x) {
187 for (int y = height / 2; y < height - 2; ++y) { 206 scanline[x] = checkColor2;
188 scanline = result->getAddr8(0, y); 207 }
189 scanline[0] = kZero; 208 for (int x = width; x < width + kXPad; ++x) {
190 scanline[1] = kOne; 209 scanline[x] = padColor;
191 for (int x = 2; x < width / 2; ++x) { 210 }
192 scanline[x] = kHalf; 211 }
193 } 212
194 for (int x = width / 2; x < width - 2; ++x) { 213 for (int y = height / 2 + 1; y < height; ++y) {
195 scanline[x] = k3Q; 214 scanline = (PIXEL_TYPE*)((char*)scanline + rowBytes);
196 } 215 scanline[0] = outerRingColor;
197 scanline[width - 2] = kOne; 216 scanline[1] = innerRingColor;
198 scanline[width - 1] = kZero; 217 for (int x = 2; x < width / 2 + 1; ++x) {
199 } 218 scanline[x] = checkColor2;
200 219 }
201 scanline = result->getAddr8(0, height - 2); 220 for (int x = width / 2 + 1; x < width; ++x) {
202 scanline[0] = kZero; 221 scanline[x] = checkColor1;
203 for (int x = 1; x < width - 1; ++x) { 222 }
204 scanline[x] = kOne; 223 for (int x = width; x < width + kXPad; ++x) {
205 } 224 scanline[x] = padColor;
206 scanline[width - 1] = kZero; 225 }
207 226 }
208 scanline = result->getAddr8(0, height - 1); 227
209 for (int x = 0; x < width; ++x) { 228 for (int y = height; y < height + kYPad; ++y) {
210 scanline[x] = kZero; 229 scanline = (PIXEL_TYPE*)((char*)scanline + rowBytes);
211 } 230 for (int x = 0; x < width + kXPad; ++x) {
212 result->setImmutable(); 231 scanline[x] = padColor;
232 }
233 }
234
235 GrSurfaceDesc desc;
236 desc.fConfig = config;
237 desc.fWidth = width + kXPad;
238 desc.fHeight = height + kYPad;
239 SkAutoTUnref<GrTexture> texture(ctx->textureProvider()->createTexture(desc, true, pixels.get(),
240 rowByt es));
241
242 if (!texture) {
243 return false;
244 }
245
246 GrWrapTextureInBitmap(texture, width, height, true, &result->fBitmap);
247 result->fType = TestPixels::kBitmap;
248 result->fBitmap.setImmutable();
249 result->fRect.set(2, 2, width, height);
250 return true;
251 #else
252 return false;
253 #endif
254 }
255
256 /** Make the color version of the oversized texture-backed bitmap */
257 static bool make_ringed_oversized_color_texture_bitmap(GrContext* ctx, TestPixel s* result,
258 int width, int height) {
259 static const SkPMColor kBlue = SkPreMultiplyColor(SK_ColorBLUE);
260 static const SkPMColor kRed = SkPreMultiplyColor(SK_ColorRED);
261 static const SkPMColor kBlack = SkPreMultiplyColor(SK_ColorBLACK);
262 static const SkPMColor kWhite = SkPreMultiplyColor(SK_ColorWHITE);
263 static const SkPMColor kGreen = SkPreMultiplyColor(SK_ColorGREEN);
264 return make_oversized_texture_bitmap<SkPMColor>(
265 ctx, result, width, height, kSkia8888_GrPixelConfig, kBlue, kRed, kBlack , kWhite, kGreen);
266 }
267
268 /** Make the alpha version of the oversized texture-backed bitmap */
269 static bool make_ringed_oversized_alpha_texture_bitmap(GrContext* ctx, TestPixel s* result,
270 int width, int height) {
271 static const uint8_t kZero = 0x00;
272 static const uint8_t kHalf = 0x80;
273 static const uint8_t k3Q = 0xC0;
274 static const uint8_t kOne = 0xFF;
275 static const uint8_t k1Q = 0x40;
276 return make_oversized_texture_bitmap<uint8_t>(
277 ctx, result, width, height, kAlpha_8_GrPixelConfig, kZero, kOne, k3Q, kH alf, k1Q);
213 } 278 }
214 279
215 static SkShader* make_shader() { 280 static SkShader* make_shader() {
216 static const SkPoint pts[] = { {0, 0}, {20, 20} }; 281 static const SkPoint pts[] = { {0, 0}, {20, 20} };
217 static const SkColor colors[] = { SK_ColorGREEN, SK_ColorYELLOW }; 282 static const SkColor colors[] = { SK_ColorGREEN, SK_ColorYELLOW };
218 return SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kMi rror_TileMode); 283 return SkGradientShader::CreateLinear(pts, colors, nullptr, 2, SkShader::kMi rror_TileMode);
219 } 284 }
220 285
221 static SkShader* make_null_shader() { return nullptr; } 286 static SkShader* make_null_shader() { return nullptr; }
222 287
223 enum BleedTest { 288 enum BleedTest {
224 kUseBitmap_BleedTest, 289 kUseBitmap_BleedTest,
225 kUseTextureBitmap_BleedTest, 290 kUseTextureBitmap_BleedTest,
226 kUseImage_BleedTest, 291 kUseImage_BleedTest,
227 kUseAlphaBitmap_BleedTest, 292 kUseAlphaBitmap_BleedTest,
228 kUseAlphaTextureBitmap_BleedTest, 293 kUseAlphaTextureBitmap_BleedTest,
229 kUseAlphaImage_BleedTest, 294 kUseAlphaImage_BleedTest,
230 kUseAlphaBitmapShader_BleedTest, 295 kUseAlphaBitmapShader_BleedTest,
231 kUseAlphaTextureBitmapShader_BleedTest, 296 kUseAlphaTextureBitmapShader_BleedTest,
232 kUseAlphaImageShader_BleedTest, 297 kUseAlphaImageShader_BleedTest,
233 }; 298 };
234 299
235 const struct { 300 const struct {
236 const char* fName; 301 const char* fName;
237 void(*fBmpMaker)(SkBitmap* result, int width, int height); 302 bool (*fPixelMaker)(GrContext*, TestPixels* result, int width, int height);
238 SkShader*(*fShaderMaker)(); 303 SkShader* (*fShaderMaker)();
239 void(*fDraw)(SkCanvas*, const SkBitmap&, const SkImage*, const SkRect&, cons t SkRect&,
240 const SkPaint*, SkCanvas::SrcRectConstraint);
241 } gBleedRec[] = { 304 } gBleedRec[] = {
242 { "bleed", make_ringed_color_bitmap, make_null_shad er, draw_bitmap_rect }, 305 { "bleed", make_ringed_color_bitmap, make_null_shader },
243 { "bleed_texture_bmp", make_ringed_color_bitmap, make_null_shad er, draw_texture_bitmap_rect }, 306 { "bleed_texture_bmp", make_ringed_oversized_color_texture_bitm ap, make_null_shader },
244 { "bleed_image", make_ringed_color_bitmap, make_null_shad er, draw_image_rect }, 307 { "bleed_image", make_ringed_color_image, make_null_shader },
245 { "bleed_alpha_bmp", make_ringed_alpha_bitmap, make_null_shad er, draw_bitmap_rect }, 308 { "bleed_alpha_bmp", make_ringed_alpha_bitmap, make_null_shader },
246 { "bleed_alpha_texture_bmp", make_ringed_alpha_bitmap, make_null_shad er, draw_texture_bitmap_rect }, 309 { "bleed_alpha_texture_bmp", make_ringed_oversized_alpha_texture_bitm ap, make_null_shader },
247 { "bleed_alpha_image", make_ringed_alpha_bitmap, make_null_shad er, draw_image_rect }, 310 { "bleed_alpha_image", make_ringed_alpha_image, make_null_shader },
248 { "bleed_alpha_bmp_shader", make_ringed_alpha_bitmap, make_shader, draw_bitmap_rect }, 311 { "bleed_alpha_bmp_shader", make_ringed_alpha_bitmap, make_shader },
249 { "bleed_alpha_texture_bmp_shader", make_ringed_alpha_bitmap, make_shader, draw_texture_bitmap_rect }, 312 { "bleed_alpha_texture_bmp_shader", make_ringed_oversized_alpha_texture_bitm ap, make_shader },
250 { "bleed_alpha_image_shader", make_ringed_alpha_bitmap, make_shader, draw_image_rect }, 313 { "bleed_alpha_image_shader", make_ringed_alpha_image, make_shader },
251 }; 314 };
252 315
253 // This GM exercises the drawBitmapRect constraints 316 /** This GM exercises the behavior of the drawBitmapRect & drawImageRect calls. Specifically their
317 handling of :
318 - SrcRectConstraint(bleed vs.no - bleed)
319 - handling of the sub - region feature(area - of - interest) of drawBitmap*
320 - handling of 8888 vs. A8 (including presence of a shader in the A8 case).
321 - (gpu - only) handling of tiled vs.non - tiled drawing)
322 - (gpu - only) texture's backing a bmp where the texture is larger than the bmp.
323 In particular, we should never see the padding outside of an SkBitmap's sub - region (green for
324 8888, 1/4 for alpha). In some instances we can see the two outer rings outsi de of the area o
325 interest (i.e., the inner four checks) due to AA or filtering if allowed by the
326 SrcRectConstraint.
327 */
254 class BleedGM : public skiagm::GM { 328 class BleedGM : public skiagm::GM {
255 public: 329 public:
256 BleedGM(BleedTest bt) : fBT(bt) {} 330 BleedGM(BleedTest bt) : fCreatedPixels(false), fBT(bt){}
257 331
258 protected: 332 protected:
259 333
260 SkString onShortName() override { 334 SkString onShortName() override {
261 return SkString(gBleedRec[fBT].fName); 335 return SkString(gBleedRec[fBT].fName);
262 } 336 }
263 337
264 SkISize onISize() override { 338 SkISize onISize() override {
265 return SkISize::Make(1200, 1080); 339 return SkISize::Make(1200, 1080);
266 } 340 }
267 341
268 void onOnceBeforeDraw() override { 342 void drawPixels(SkCanvas* canvas, const TestPixels& pixels, const SkRect& sr c,
269 gBleedRec[fBT].fBmpMaker(&fBitmapSmall, kSmallTextureSize, kSmallTexture Size); 343 const SkRect& dst, const SkPaint* paint,
270 fImageSmall.reset(SkImage::NewFromBitmap(fBitmapSmall)); 344 SkCanvas::SrcRectConstraint constraint) {
271 345 if (TestPixels::kBitmap == pixels.fType) {
272 // To exercise the GPU's tiling path we need a texture 346 canvas->drawBitmapRect(pixels.fBitmap, src, dst, paint, constraint);
273 // too big for the GPU to handle in one go 347 } else {
274 gBleedRec[fBT].fBmpMaker(&fBitmapBig, 2*kMaxTileSize, 2*kMaxTileSize); 348 canvas->drawImageRect(pixels.fImage, src, dst, paint, constraint);
275 fImageBig.reset(SkImage::NewFromBitmap(fBitmapBig)); 349 }
276 350 }
277 fShader.reset(gBleedRec[fBT].fShaderMaker()); 351
278 } 352 // Draw the area of interest of the small image
279
280 // Draw only the center of the small bitmap
281 void drawCase1(SkCanvas* canvas, int transX, int transY, bool aa, 353 void drawCase1(SkCanvas* canvas, int transX, int transY, bool aa,
282 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) { 354 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) {
283 SkRect src = SkRect::MakeXYWH(2, 2, 355
284 SkIntToScalar(kSmallTextureSize-4), 356 SkRect src = SkRect::Make(fSmallTestPixels.fRect);
285 SkIntToScalar(kSmallTextureSize-4));
286 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y), 357 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y),
287 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize)); 358 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize));
288 359
289 SkPaint paint; 360 SkPaint paint;
290 paint.setFilterQuality(filter); 361 paint.setFilterQuality(filter);
291 paint.setShader(fShader); 362 paint.setShader(fShader);
292 paint.setColor(SK_ColorBLUE); 363 paint.setColor(SK_ColorBLUE);
293 paint.setAntiAlias(aa); 364 paint.setAntiAlias(aa);
294 365
295 gBleedRec[fBT].fDraw(canvas, fBitmapSmall, fImageSmall, src, dst, &paint , constraint); 366 this->drawPixels(canvas, fSmallTestPixels, src, dst, &paint, constraint) ;
296 } 367 }
297 368
298 // Draw almost all of the large bitmap 369 // Draw the area of interest of the large image
299 void drawCase2(SkCanvas* canvas, int transX, int transY, bool aa, 370 void drawCase2(SkCanvas* canvas, int transX, int transY, bool aa,
300 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) { 371 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) {
301 SkRect src = SkRect::MakeXYWH(2, 2, 372 SkRect src = SkRect::Make(fBigTestPixels.fRect);
302 SkIntToScalar(fBitmapBig.width()-4),
303 SkIntToScalar(fBitmapBig.height()-4));
304 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y), 373 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y),
305 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize)); 374 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize));
306 375
307 SkPaint paint; 376 SkPaint paint;
308 paint.setFilterQuality(filter); 377 paint.setFilterQuality(filter);
309 paint.setShader(fShader); 378 paint.setShader(fShader);
310 paint.setColor(SK_ColorBLUE); 379 paint.setColor(SK_ColorBLUE);
311 paint.setAntiAlias(aa); 380 paint.setAntiAlias(aa);
312 381
313 gBleedRec[fBT].fDraw(canvas, fBitmapBig, fImageBig, src, dst, &paint, co nstraint); 382 this->drawPixels(canvas, fBigTestPixels, src, dst, &paint, constraint);
314 } 383 }
315 384
316 // Draw ~1/4 of the large bitmap 385 // Draw upper-left 1/4 of the area of interest of the large image
317 void drawCase3(SkCanvas* canvas, int transX, int transY, bool aa, 386 void drawCase3(SkCanvas* canvas, int transX, int transY, bool aa,
318 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) { 387 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) {
319 SkRect src = SkRect::MakeXYWH(2, 2, 388 SkRect src = SkRect::MakeXYWH(SkIntToScalar(fBigTestPixels.fRect.fLeft),
320 SkIntToScalar(fBitmapBig.width()/2-2), 389 SkIntToScalar(fBigTestPixels.fRect.fTop),
321 SkIntToScalar(fBitmapBig.height()/2-2)); 390 fBigTestPixels.fRect.width()/2.f,
391 fBigTestPixels.fRect.height()/2.f);
322 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y), 392 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y),
323 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize)); 393 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize));
324 394
325 SkPaint paint; 395 SkPaint paint;
326 paint.setFilterQuality(filter); 396 paint.setFilterQuality(filter);
327 paint.setShader(fShader); 397 paint.setShader(fShader);
328 paint.setColor(SK_ColorBLUE); 398 paint.setColor(SK_ColorBLUE);
329 paint.setAntiAlias(aa); 399 paint.setAntiAlias(aa);
330 400
331 gBleedRec[fBT].fDraw(canvas, fBitmapBig, fImageBig, src, dst, &paint, co nstraint); 401 this->drawPixels(canvas, fBigTestPixels, src, dst, &paint, constraint);
332 } 402 }
333 403
334 // Draw the center of the small bitmap with a normal blur 404 // Draw the area of interest of the small image with a normal blur
335 void drawCase4(SkCanvas* canvas, int transX, int transY, bool aa, 405 void drawCase4(SkCanvas* canvas, int transX, int transY, bool aa,
336 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) { 406 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) {
337 SkRect src = SkRect::MakeXYWH(2, 2, 407 SkRect src = SkRect::Make(fSmallTestPixels.fRect);
338 SkIntToScalar(kSmallTextureSize-4),
339 SkIntToScalar(kSmallTextureSize-4));
340 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y), 408 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y),
341 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize)); 409 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize));
342 410
343 SkPaint paint; 411 SkPaint paint;
344 paint.setFilterQuality(filter); 412 paint.setFilterQuality(filter);
345 SkMaskFilter* mf = SkBlurMaskFilter::Create(kNormal_SkBlurStyle, 413 SkMaskFilter* mf = SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
346 SkBlurMask::ConvertRadiusToSigma(3)); 414 SkBlurMask::ConvertRadiusToSigma(3));
347 paint.setMaskFilter(mf)->unref(); 415 paint.setMaskFilter(mf)->unref();
348 paint.setShader(fShader); 416 paint.setShader(fShader);
349 paint.setColor(SK_ColorBLUE); 417 paint.setColor(SK_ColorBLUE);
350 paint.setAntiAlias(aa); 418 paint.setAntiAlias(aa);
351 419
352 gBleedRec[fBT].fDraw(canvas, fBitmapSmall, fImageSmall, src, dst, &paint , constraint); 420 this->drawPixels(canvas, fSmallTestPixels, src, dst, &paint, constraint) ;
353 } 421 }
354 422
355 // Draw the center of the small bitmap with a outer blur 423 // Draw the area of interest of the small image with a outer blur
356 void drawCase5(SkCanvas* canvas, int transX, int transY, bool aa, 424 void drawCase5(SkCanvas* canvas, int transX, int transY, bool aa,
357 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) { 425 SkCanvas::SrcRectConstraint constraint, SkFilterQuality filte r) {
358 SkRect src = SkRect::MakeXYWH(2, 2, 426 SkRect src = SkRect::Make(fSmallTestPixels.fRect);
359 SkIntToScalar(kSmallTextureSize - 4),
360 SkIntToScalar(kSmallTextureSize - 4));
361 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y), 427 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(trans Y),
362 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize)); 428 SkIntToScalar(kBlockSize), SkIntToScalar(k BlockSize));
363 429
364 SkPaint paint; 430 SkPaint paint;
365 paint.setFilterQuality(filter); 431 paint.setFilterQuality(filter);
366 SkMaskFilter* mf = SkBlurMaskFilter::Create(kOuter_SkBlurStyle, 432 SkMaskFilter* mf = SkBlurMaskFilter::Create(kOuter_SkBlurStyle,
367 SkBlurMask::ConvertRadiusToS igma(7)); 433 SkBlurMask::ConvertRadiusToS igma(7));
368 paint.setMaskFilter(mf)->unref(); 434 paint.setMaskFilter(mf)->unref();
369 paint.setShader(fShader); 435 paint.setShader(fShader);
370 paint.setColor(SK_ColorBLUE); 436 paint.setColor(SK_ColorBLUE);
371 paint.setAntiAlias(aa); 437 paint.setAntiAlias(aa);
372 438
373 gBleedRec[fBT].fDraw(canvas, fBitmapSmall, fImageSmall, src, dst, &paint , constraint); 439 this->drawPixels(canvas, fSmallTestPixels, src, dst, &paint, constraint) ;
374 } 440 }
375 441
376 void onDraw(SkCanvas* canvas) override { 442 void onDraw(SkCanvas* canvas) override {
443 // We don't create pixels in an onOnceBeforeDraw() override because we w ant access to
444 // GrContext.
445 GrContext* context = canvas->getGrContext();
446 #if SK_SUPPORT_GPU
447 // Workaround for SampleApp.
448 if (GrTexture* tex = fBigTestPixels.fBitmap.getTexture()) {
449 if (tex->wasDestroyed()) {
450 fCreatedPixels = false;
451 }
452 }
453 #endif
454 bool madePixels = fCreatedPixels;
455
456 if (!madePixels) {
457 madePixels = gBleedRec[fBT].fPixelMaker(context, &fSmallTestPixels, kSmallTextureSize,
458 kSmallTextureSize);
459 madePixels &= gBleedRec[fBT].fPixelMaker(context, &fBigTestPixels, 2 * kMaxTileSize,
460 2 * kMaxTileSize);
461 fCreatedPixels = madePixels;
462 }
463
464 // Assume that if we coulnd't make the bitmap/image it's because it's a GPU test on a
465 // non-GPU backend.
466 if (!madePixels) {
467 skiagm::GM::DrawGpuOnlyMessage(canvas);
468 return;
469 }
470
471 fShader.reset(gBleedRec[fBT].fShaderMaker());
472
377 canvas->clear(SK_ColorGRAY); 473 canvas->clear(SK_ColorGRAY);
378 SkTDArray<SkMatrix> matrices; 474 SkTDArray<SkMatrix> matrices;
379 // Draw with identity 475 // Draw with identity
380 *matrices.append() = SkMatrix::I(); 476 *matrices.append() = SkMatrix::I();
381 477
382 // Draw with rotation and scale down in x, up in y. 478 // Draw with rotation and scale down in x, up in y.
383 SkMatrix m; 479 SkMatrix m;
384 static const SkScalar kBottom = SkIntToScalar(kRow4Y + kBlockSize + kBlo ckSpacing); 480 static const SkScalar kBottom = SkIntToScalar(kRow4Y + kBlockSize + kBlo ckSpacing);
385 m.setTranslate(0, kBottom); 481 m.setTranslate(0, kBottom);
386 m.preRotate(15.f, 0, kBottom + kBlockSpacing); 482 m.preRotate(15.f, 0, kBottom + kBlockSpacing);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 575
480 static const int kRow0Y = kBlockSpacing; 576 static const int kRow0Y = kBlockSpacing;
481 static const int kRow1Y = 2*kBlockSpacing + kBlockSize; 577 static const int kRow1Y = 2*kBlockSpacing + kBlockSize;
482 static const int kRow2Y = 3*kBlockSpacing + 2*kBlockSize; 578 static const int kRow2Y = 3*kBlockSpacing + 2*kBlockSize;
483 static const int kRow3Y = 4*kBlockSpacing + 3*kBlockSize; 579 static const int kRow3Y = 4*kBlockSpacing + 3*kBlockSize;
484 static const int kRow4Y = 5*kBlockSpacing + 4*kBlockSize; 580 static const int kRow4Y = 5*kBlockSpacing + 4*kBlockSize;
485 581
486 static const int kSmallTextureSize = 6; 582 static const int kSmallTextureSize = 6;
487 static const int kMaxTileSize = 32; 583 static const int kMaxTileSize = 32;
488 584
489 SkBitmap fBitmapSmall; 585 bool fCreatedPixels;
490 SkBitmap fBitmapBig; 586 TestPixels fBigTestPixels;
491 SkAutoTUnref<SkImage> fImageSmall; 587 TestPixels fSmallTestPixels;
492 SkAutoTUnref<SkImage> fImageBig; 588
493 589 SkAutoTUnref<SkShader> fShader;
494 SkAutoTUnref<SkShader> fShader; 590
495 591 const BleedTest fBT;
496 const BleedTest fBT;
497 592
498 typedef GM INHERITED; 593 typedef GM INHERITED;
499 }; 594 };
500 595
501 596
502 DEF_GM( return new BleedGM(kUseBitmap_BleedTest); ) 597 DEF_GM( return new BleedGM(kUseBitmap_BleedTest); )
503 DEF_GM( return new BleedGM(kUseTextureBitmap_BleedTest); ) 598 DEF_GM( return new BleedGM(kUseTextureBitmap_BleedTest); )
504 DEF_GM( return new BleedGM(kUseImage_BleedTest); ) 599 DEF_GM( return new BleedGM(kUseImage_BleedTest); )
505 DEF_GM( return new BleedGM(kUseAlphaBitmap_BleedTest); ) 600 DEF_GM( return new BleedGM(kUseAlphaBitmap_BleedTest); )
506 DEF_GM( return new BleedGM(kUseAlphaTextureBitmap_BleedTest); ) 601 DEF_GM( return new BleedGM(kUseAlphaTextureBitmap_BleedTest); )
507 DEF_GM( return new BleedGM(kUseAlphaImage_BleedTest); ) 602 DEF_GM( return new BleedGM(kUseAlphaImage_BleedTest); )
508 DEF_GM( return new BleedGM(kUseAlphaBitmapShader_BleedTest); ) 603 DEF_GM( return new BleedGM(kUseAlphaBitmapShader_BleedTest); )
509 DEF_GM( return new BleedGM(kUseAlphaTextureBitmapShader_BleedTest); ) 604 DEF_GM( return new BleedGM(kUseAlphaTextureBitmapShader_BleedTest); )
510 DEF_GM( return new BleedGM(kUseAlphaImageShader_BleedTest); ) 605 DEF_GM( return new BleedGM(kUseAlphaImageShader_BleedTest); )
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698