Home | History | Annotate | Download | only in gm
      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