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