| OLD | NEW |
| 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 Loading... |
| 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); ) |
| OLD | NEW |