1 2 /* 3 * Copyright 2011 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 "gm.h" 9 #include "SkCanvas.h" 10 #include "SkGradientShader.h" 11 #include "SkGraphics.h" 12 #include "SkPath.h" 13 #include "SkRegion.h" 14 #include "SkShader.h" 15 16 static void make_bitmap(SkBitmap* bitmap) { 17 bitmap->allocN32Pixels(64, 64); 18 19 SkCanvas canvas(*bitmap); 20 21 canvas.drawColor(SK_ColorRED); 22 SkPaint paint; 23 paint.setAntiAlias(true); 24 const SkPoint pts[] = { { 0, 0 }, { 64, 64 } }; 25 const SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE }; 26 paint.setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2, 27 SkShader::kClamp_TileMode))->unref(); 28 canvas.drawCircle(32, 32, 32, paint); 29 } 30 31 class DrawBitmapRect2 : public skiagm::GM { 32 bool fUseIRect; 33 public: 34 DrawBitmapRect2(bool useIRect) : fUseIRect(useIRect) { 35 } 36 37 protected: 38 virtual SkString onShortName() SK_OVERRIDE { 39 SkString str; 40 str.printf("bitmaprect_%s", fUseIRect ? "i" : "s"); 41 return str; 42 } 43 44 virtual SkISize onISize() SK_OVERRIDE { 45 return SkISize::Make(640, 480); 46 } 47 48 #ifdef SK_CPU_ARM64 49 // Skip tiled drawing on 64-bit ARM until https://skbug.com/2908 is fixed. 50 virtual uint32_t onGetFlags() const SK_OVERRIDE { 51 return kSkipTiled_Flag; 52 } 53 #endif 54 55 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 56 canvas->drawColor(0xFFCCCCCC); 57 58 const SkIRect src[] = { 59 { 0, 0, 32, 32 }, 60 { 0, 0, 80, 80 }, 61 { 32, 32, 96, 96 }, 62 { -32, -32, 32, 32, } 63 }; 64 65 SkPaint paint; 66 paint.setStyle(SkPaint::kStroke_Style); 67 68 SkBitmap bitmap; 69 make_bitmap(&bitmap); 70 71 SkRect dstR = { 0, 200, 128, 380 }; 72 73 canvas->translate(16, 40); 74 for (size_t i = 0; i < SK_ARRAY_COUNT(src); i++) { 75 SkRect srcR; 76 srcR.set(src[i]); 77 78 canvas->drawBitmap(bitmap, 0, 0, &paint); 79 if (!fUseIRect) { 80 canvas->drawBitmapRectToRect(bitmap, &srcR, dstR, &paint); 81 } else { 82 canvas->drawBitmapRect(bitmap, &src[i], dstR, &paint); 83 } 84 85 canvas->drawRect(dstR, paint); 86 canvas->drawRect(srcR, paint); 87 88 canvas->translate(160, 0); 89 } 90 } 91 92 private: 93 typedef skiagm::GM INHERITED; 94 }; 95 96 ////////////////////////////////////////////////////////////////////////////// 97 static void make_3x3_bitmap(SkBitmap* bitmap) { 98 99 static const int gXSize = 3; 100 static const int gYSize = 3; 101 102 SkColor textureData[gXSize][gYSize] = { 103 { SK_ColorRED, SK_ColorWHITE, SK_ColorBLUE }, 104 { SK_ColorGREEN, SK_ColorBLACK, SK_ColorCYAN }, 105 { SK_ColorYELLOW, SK_ColorGRAY, SK_ColorMAGENTA } 106 }; 107 108 109 bitmap->allocN32Pixels(gXSize, gYSize); 110 for (int y = 0; y < gYSize; y++) { 111 for (int x = 0; x < gXSize; x++) { 112 *bitmap->getAddr32(x, y) = textureData[x][y]; 113 } 114 } 115 } 116 117 // This GM attempts to make visible any issues drawBitmapRectToRect may have 118 // with partial source rects. In this case the eight pixels on the border 119 // should be half the width/height of the central pixel, i.e.: 120 // __|____|__ 121 // | | 122 // __|____|__ 123 // | | 124 class DrawBitmapRect3 : public skiagm::GM { 125 public: 126 DrawBitmapRect3() { 127 this->setBGColor(SK_ColorBLACK); 128 } 129 130 protected: 131 virtual SkString onShortName() SK_OVERRIDE { 132 SkString str; 133 str.printf("3x3bitmaprect"); 134 return str; 135 } 136 137 virtual SkISize onISize() SK_OVERRIDE { 138 return SkISize::Make(640, 480); 139 } 140 141 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 142 143 SkBitmap bitmap; 144 make_3x3_bitmap(&bitmap); 145 146 SkRect srcR = { 0.5f, 0.5f, 2.5f, 2.5f }; 147 SkRect dstR = { 100, 100, 300, 200 }; 148 149 canvas->drawBitmapRectToRect(bitmap, &srcR, dstR, NULL); 150 } 151 152 private: 153 typedef skiagm::GM INHERITED; 154 }; 155 156 ////////////////////////////////////////////////////////////////////////////// 157 static void make_big_bitmap(SkBitmap* bitmap) { 158 159 static const int gXSize = 4096; 160 static const int gYSize = 4096; 161 static const int gBorderWidth = 10; 162 163 bitmap->allocN32Pixels(gXSize, gYSize); 164 for (int y = 0; y < gYSize; ++y) { 165 for (int x = 0; x < gXSize; ++x) { 166 if (x <= gBorderWidth || x >= gXSize-gBorderWidth || 167 y <= gBorderWidth || y >= gYSize-gBorderWidth) { 168 *bitmap->getAddr32(x, y) = 0x88FFFFFF; 169 } else { 170 *bitmap->getAddr32(x, y) = 0x88FF0000; 171 } 172 } 173 } 174 } 175 176 // This GM attempts to reveal any issues we may have when the GPU has to 177 // break up a large texture in order to draw it. The XOR transfer mode will 178 // create stripes in the image if there is imprecision in the destination 179 // tile placement. 180 class DrawBitmapRect4 : public skiagm::GM { 181 bool fUseIRect; 182 SkBitmap fBigBitmap; 183 184 public: 185 DrawBitmapRect4(bool useIRect) : fUseIRect(useIRect) { 186 this->setBGColor(0x88444444); 187 } 188 189 protected: 190 virtual SkString onShortName() SK_OVERRIDE { 191 SkString str; 192 str.printf("bigbitmaprect_%s", fUseIRect ? "i" : "s"); 193 return str; 194 } 195 196 virtual SkISize onISize() SK_OVERRIDE { 197 return SkISize::Make(640, 480); 198 } 199 200 virtual void onOnceBeforeDraw() SK_OVERRIDE { 201 make_big_bitmap(&fBigBitmap); 202 } 203 204 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 205 206 SkXfermode* mode = SkXfermode::Create(SkXfermode::kXor_Mode); 207 208 SkPaint paint; 209 paint.setAlpha(128); 210 paint.setXfermode(mode)->unref(); 211 212 SkRect srcR1 = { 0.0f, 0.0f, 4096.0f, 2040.0f }; 213 SkRect dstR1 = { 10.1f, 10.1f, 629.9f, 400.9f }; 214 215 SkRect srcR2 = { 4085.0f, 10.0f, 4087.0f, 12.0f }; 216 SkRect dstR2 = { 10, 410, 30, 430 }; 217 218 if (!fUseIRect) { 219 canvas->drawBitmapRectToRect(fBigBitmap, &srcR1, dstR1, &paint); 220 canvas->drawBitmapRectToRect(fBigBitmap, &srcR2, dstR2, &paint); 221 } else { 222 SkIRect iSrcR1, iSrcR2; 223 224 srcR1.roundOut(&iSrcR1); 225 srcR2.roundOut(&iSrcR2); 226 227 canvas->drawBitmapRect(fBigBitmap, &iSrcR1, dstR1, &paint); 228 canvas->drawBitmapRect(fBigBitmap, &iSrcR2, dstR2, &paint); 229 } 230 } 231 232 private: 233 typedef skiagm::GM INHERITED; 234 }; 235 236 ////////////////////////////////////////////////////////////////////////////// 237 238 static skiagm::GM* MyFactory0(void*) { return new DrawBitmapRect2(false); } 239 static skiagm::GM* MyFactory1(void*) { return new DrawBitmapRect2(true); } 240 241 static skiagm::GM* MyFactory2(void*) { return new DrawBitmapRect3(); } 242 243 #ifndef SK_BUILD_FOR_ANDROID 244 static skiagm::GM* MyFactory3(void*) { return new DrawBitmapRect4(false); } 245 static skiagm::GM* MyFactory4(void*) { return new DrawBitmapRect4(true); } 246 #endif 247 248 static skiagm::GMRegistry reg0(MyFactory0); 249 static skiagm::GMRegistry reg1(MyFactory1); 250 251 static skiagm::GMRegistry reg2(MyFactory2); 252 253 #ifndef SK_BUILD_FOR_ANDROID 254 static skiagm::GMRegistry reg3(MyFactory3); 255 static skiagm::GMRegistry reg4(MyFactory4); 256 #endif 257