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