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