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 "SkPath.h"
     10 #include "SkRegion.h"
     11 #include "SkShader.h"
     12 #include "SkUtils.h"
     13 #include "SkColorPriv.h"
     14 #include "SkColorFilter.h"
     15 #include "SkTypeface.h"
     16 
     17 // effects
     18 #include "SkGradientShader.h"
     19 #include "SkUnitMappers.h"
     20 #include "SkBlurDrawLooper.h"
     21 
     22 static void makebm(SkBitmap* bm, SkBitmap::Config config, int w, int h) {
     23     bm->setConfig(config, w, h);
     24     bm->allocPixels();
     25     bm->eraseColor(SK_ColorTRANSPARENT);
     26 
     27     SkCanvas    canvas(*bm);
     28     SkPoint     pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h)} };
     29     SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
     30     SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
     31     SkPaint     paint;
     32 
     33     SkUnitMapper*   um = NULL;
     34 
     35     um = new SkCosineMapper;
     36 //    um = new SkDiscreteMapper(12);
     37 
     38     SkAutoUnref au(um);
     39 
     40     paint.setDither(true);
     41     paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
     42                 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
     43     canvas.drawPaint(paint);
     44 }
     45 
     46 static void setup(SkPaint* paint, const SkBitmap& bm, bool filter,
     47                   SkShader::TileMode tmx, SkShader::TileMode tmy) {
     48     SkShader* shader = SkShader::CreateBitmapShader(bm, tmx, tmy);
     49     paint->setShader(shader)->unref();
     50     paint->setFilterLevel(filter ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
     51 }
     52 
     53 static const SkBitmap::Config gConfigs[] = {
     54     SkBitmap::kARGB_8888_Config,
     55     SkBitmap::kRGB_565_Config,
     56 };
     57 
     58 class TilingGM : public skiagm::GM {
     59 public:
     60     TilingGM(bool powerOfTwoSize)
     61             : fPowerOfTwoSize(powerOfTwoSize) {
     62     }
     63 
     64     SkBitmap    fTexture[SK_ARRAY_COUNT(gConfigs)];
     65 
     66 protected:
     67 
     68     enum {
     69         kPOTSize = 32,
     70         kNPOTSize = 21,
     71     };
     72 
     73     SkString onShortName() {
     74         SkString name("tilemodes");
     75         if (!fPowerOfTwoSize) {
     76             name.append("_npot");
     77         }
     78         return name;
     79     }
     80 
     81     SkISize onISize() { return SkISize::Make(880, 560); }
     82 
     83     virtual void onOnceBeforeDraw() SK_OVERRIDE {
     84         int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
     85         for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
     86             makebm(&fTexture[i], gConfigs[i], size, size);
     87         }
     88     }
     89 
     90     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
     91 
     92         int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
     93 
     94         SkRect r = { 0, 0, SkIntToScalar(size*2), SkIntToScalar(size*2) };
     95 
     96         static const char* gConfigNames[] = { "8888", "565", "4444" };
     97 
     98         static const bool           gFilters[] = { false, true };
     99         static const char*          gFilterNames[] = {     "point",                     "bilinear" };
    100 
    101         static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode };
    102         static const char*          gModeNames[] = {    "C",                    "R",                   "M" };
    103 
    104         SkScalar y = SkIntToScalar(24);
    105         SkScalar x = SkIntToScalar(10);
    106 
    107         for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
    108             for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
    109                 SkPaint p;
    110                 SkString str;
    111                 p.setAntiAlias(true);
    112                 p.setDither(true);
    113                 str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
    114 
    115                 p.setTextAlign(SkPaint::kCenter_Align);
    116                 canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);
    117 
    118                 x += r.width() * 4 / 3;
    119             }
    120         }
    121 
    122         y += SkIntToScalar(16);
    123 
    124         for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
    125             for (size_t j = 0; j < SK_ARRAY_COUNT(gFilters); j++) {
    126                 x = SkIntToScalar(10);
    127                 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
    128                     for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
    129                         SkPaint paint;
    130 #if 1 // Temporary change to regen bitmap before each draw. This may help tracking down an issue
    131       // on SGX where resizing NPOT textures to POT textures exhibits a driver bug.
    132                         if (!fPowerOfTwoSize) {
    133                             makebm(&fTexture[i], gConfigs[i], size, size);
    134                         }
    135 #endif
    136                         setup(&paint, fTexture[i], gFilters[j], gModes[kx], gModes[ky]);
    137                         paint.setDither(true);
    138 
    139                         canvas->save();
    140                         canvas->translate(x, y);
    141                         canvas->drawRect(r, paint);
    142                         canvas->restore();
    143 
    144                         x += r.width() * 4 / 3;
    145                     }
    146                 }
    147                 {
    148                     SkPaint p;
    149                     SkString str;
    150                     p.setAntiAlias(true);
    151                     str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
    152                     canvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
    153                 }
    154 
    155                 y += r.height() * 4 / 3;
    156             }
    157         }
    158     }
    159 
    160 private:
    161     bool fPowerOfTwoSize;
    162     typedef skiagm::GM INHERITED;
    163 };
    164 
    165 static const int gWidth = 32;
    166 static const int gHeight = 32;
    167 
    168 static SkShader* make_bm(SkShader::TileMode tx, SkShader::TileMode ty) {
    169     SkBitmap bm;
    170     makebm(&bm, SkBitmap::kARGB_8888_Config, gWidth, gHeight);
    171     return SkShader::CreateBitmapShader(bm, tx, ty);
    172 }
    173 
    174 static SkShader* make_grad(SkShader::TileMode tx, SkShader::TileMode ty) {
    175     SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(gWidth), SkIntToScalar(gHeight)} };
    176     SkPoint center = { SkIntToScalar(gWidth)/2, SkIntToScalar(gHeight)/2 };
    177     SkScalar rad = SkIntToScalar(gWidth)/2;
    178     SkColor colors[] = { 0xFFFF0000, 0xFF0044FF };
    179 
    180     int index = (int)ty;
    181     switch (index % 3) {
    182         case 0:
    183             return SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors), tx);
    184         case 1:
    185             return SkGradientShader::CreateRadial(center, rad, colors, NULL, SK_ARRAY_COUNT(colors), tx);
    186         case 2:
    187             return SkGradientShader::CreateSweep(center.fX, center.fY, colors, NULL, SK_ARRAY_COUNT(colors));
    188     }
    189 
    190     return NULL;
    191 }
    192 
    193 typedef SkShader* (*ShaderProc)(SkShader::TileMode, SkShader::TileMode);
    194 
    195 class Tiling2GM : public skiagm::GM {
    196     ShaderProc fProc;
    197     SkString   fName;
    198 public:
    199     Tiling2GM(ShaderProc proc, const char name[]) : fProc(proc) {
    200         fName.printf("tilemode_%s", name);
    201     }
    202 
    203 protected:
    204     SkString onShortName() {
    205         return fName;
    206     }
    207 
    208     SkISize onISize() { return SkISize::Make(880, 560); }
    209 
    210     virtual void onDraw(SkCanvas* canvas) {
    211         canvas->scale(SkIntToScalar(3)/2, SkIntToScalar(3)/2);
    212 
    213         const SkScalar w = SkIntToScalar(gWidth);
    214         const SkScalar h = SkIntToScalar(gHeight);
    215         SkRect r = { -w, -h, w*2, h*2 };
    216 
    217         static const SkShader::TileMode gModes[] = {
    218             SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode
    219         };
    220         static const char* gModeNames[] = {
    221             "Clamp", "Repeat", "Mirror"
    222         };
    223 
    224         SkScalar y = SkIntToScalar(24);
    225         SkScalar x = SkIntToScalar(66);
    226 
    227         SkPaint p;
    228         p.setAntiAlias(true);
    229         p.setTextAlign(SkPaint::kCenter_Align);
    230 
    231         for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
    232             SkString str(gModeNames[kx]);
    233             canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);
    234             x += r.width() * 4 / 3;
    235         }
    236 
    237         y += SkIntToScalar(16) + h;
    238         p.setTextAlign(SkPaint::kRight_Align);
    239 
    240         for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
    241             x = SkIntToScalar(16) + w;
    242 
    243             SkString str(gModeNames[ky]);
    244             canvas->drawText(str.c_str(), str.size(), x, y + h/2, p);
    245 
    246             x += SkIntToScalar(50);
    247             for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
    248                 SkPaint paint;
    249                 paint.setShader(fProc(gModes[kx], gModes[ky]))->unref();
    250 
    251                 canvas->save();
    252                 canvas->translate(x, y);
    253                 canvas->drawRect(r, paint);
    254                 canvas->restore();
    255 
    256                 x += r.width() * 4 / 3;
    257             }
    258             y += r.height() * 4 / 3;
    259         }
    260     }
    261 
    262 private:
    263     typedef skiagm::GM INHERITED;
    264 };
    265 
    266 //////////////////////////////////////////////////////////////////////////////
    267 
    268 DEF_GM( return new TilingGM(true); )
    269 DEF_GM( return new TilingGM(false); )
    270 DEF_GM( return new Tiling2GM(make_bm, "bitmap"); )
    271 DEF_GM( return new Tiling2GM(make_grad, "gradient"); )
    272