tilemodes.cpp revision 93a1215fe0ab007ce941c721f1fd3e9dcb5d4754
1451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 2451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray/* 3451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray * Copyright 2011 Google Inc. 4451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray * 5451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray * Use of this source code is governed by a BSD-style license that can be 6c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le * found in the LICENSE file. 7c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le */ 8451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray#include "gm.h" 9451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray#include "SkPath.h" 10c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le#include "SkRegion.h" 11c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le#include "SkShader.h" 12451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray#include "SkUtils.h" 135555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray#include "SkColorPriv.h" 145555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray#include "SkColorFilter.h" 155555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray#include "SkTypeface.h" 165555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray 175555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray// effects 18e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray#include "SkGradientShader.h" 19e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray#include "SkBlurDrawLooper.h" 20e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray 21e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguraystatic void makebm(SkBitmap* bm, SkColorType ct, int w, int h) { 22e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType)); 235555f62fedfdc36cc8c4911eb24299008d961263Arman Uguray bm->eraseColor(SK_ColorTRANSPARENT); 24c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu 25c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu SkCanvas canvas(*bm); 26a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h)} }; 27a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; 28c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 }; 29c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le SkPaint paint; 30c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 31a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray paint.setDither(true); 32c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos, 33c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode))->unref(); 34a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray canvas.drawPaint(paint); 35bcbd42836b870f3e84d851eab4bb64c90cdb6afeArman Uguray} 36c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 37c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Lestatic void setup(SkPaint* paint, const SkBitmap& bm, bool filter, 38a5b80d9fdb4d8a54bad447d9e78a6e0b6d4c2d23Arman Uguray SkShader::TileMode tmx, SkShader::TileMode tmy) { 39c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu SkShader* shader = SkShader::CreateBitmapShader(bm, tmx, tmy); 40451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray paint->setShader(shader)->unref(); 41451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray paint->setFilterQuality(filter ? kLow_SkFilterQuality : kNone_SkFilterQuality); 42451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray} 433ecbf9e5d6b26e75b59f7f631fae9e6150f6e936Arman Uguray 44c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Lestatic const SkColorType gColorTypes[] = { 45c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le kN32_SkColorType, 46451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray kRGB_565_SkColorType, 47c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le}; 48c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 49451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Ugurayclass TilingGM : public skiagm::GM { 50451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguraypublic: 51c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu TilingGM(bool powerOfTwoSize) 52451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray : fPowerOfTwoSize(powerOfTwoSize) { 53451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray } 54451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 55451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkBitmap fTexture[SK_ARRAY_COUNT(gColorTypes)]; 56c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 57c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Leprotected: 58451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 59451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray enum { 60c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu kPOTSize = 32, 61451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray kNPOTSize = 21, 62451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray }; 63451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 64451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkString onShortName() SK_OVERRIDE { 65451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkString name("tilemodes"); 66e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray if (!fPowerOfTwoSize) { 67e94efecceed2a21d35c7a56b306498b53f0fa68eArman Uguray name.append("_npot"); 68451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray } 69451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray return name; 70451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray } 71c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu 72451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkISize onISize() SK_OVERRIDE { return SkISize::Make(880, 560); } 73451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 74c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le void onOnceBeforeDraw() SK_OVERRIDE { 75c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize; 76c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) { 77c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le makebm(&fTexture[i], gColorTypes[i], size, size); 78c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le } 79c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le } 80451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 81451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray void onDraw(SkCanvas* canvas) SK_OVERRIDE { 82c43ea562a0447330b26eeec3c7b1fb935958e985Prathmesh Prabhu 83451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize; 84c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 8533b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray SkRect r = { 0, 0, SkIntToScalar(size*2), SkIntToScalar(size*2) }; 86c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 8733b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray static const char* gConfigNames[] = { "8888", "565", "4444" }; 8833b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray 8933b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray static const bool gFilters[] = { false, true }; 9033b35f950ee30c7bd5e969b73d00239aefa7ea63Arman Uguray static const char* gFilterNames[] = { "point", "bilinear" }; 91451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 92451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode }; 93b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray static const char* gModeNames[] = { "C", "R", "M" }; 94b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray 95b718932651a1f46e975d3a8aff3fae20c838bcbcArman Uguray SkScalar y = SkIntToScalar(24); 96c45d1da740fbeeacedc7a1e605a3cc6d7505203eArman Uguray SkScalar x = SkIntToScalar(10); 97c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 98451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) { 99451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) { 100451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkPaint p; 101451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray SkString str; 102c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le p.setAntiAlias(true); 103c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le sk_tool_utils::set_portable_typeface(&p); 104451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray p.setDither(true); 105451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]); 106c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le 107451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray p.setTextAlign(SkPaint::kCenter_Align); 108451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p); 109c45d1da740fbeeacedc7a1e605a3cc6d7505203eArman Uguray 110c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le x += r.width() * 4 / 3; 111c569e99b922542e7ddbbc4cd465fc8328ec16214Thieu Le } 112451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray } 113451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 114451ce7ac8f6b7834dd01f94bb7f6ffa889a6da2cArman Uguray 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 153private: 154 bool fPowerOfTwoSize; 155 typedef skiagm::GM INHERITED; 156}; 157 158static const int gWidth = 32; 159static const int gHeight = 32; 160 161static 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 167static 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 186typedef SkShader* (*ShaderProc)(SkShader::TileMode, SkShader::TileMode); 187 188class Tiling2GM : public skiagm::GM { 189 ShaderProc fProc; 190 SkString fName; 191public: 192 Tiling2GM(ShaderProc proc, const char name[]) : fProc(proc) { 193 fName.printf("tilemode_%s", name); 194 } 195 196protected: 197 198 SkString onShortName() SK_OVERRIDE { 199 return fName; 200 } 201 202 SkISize onISize() SK_OVERRIDE { return SkISize::Make(880, 560); } 203 204 void onDraw(SkCanvas* canvas) SK_OVERRIDE { 205 canvas->scale(SkIntToScalar(3)/2, SkIntToScalar(3)/2); 206 207 const SkScalar w = SkIntToScalar(gWidth); 208 const SkScalar h = SkIntToScalar(gHeight); 209 SkRect r = { -w, -h, w*2, h*2 }; 210 211 static const SkShader::TileMode gModes[] = { 212 SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode 213 }; 214 static const char* gModeNames[] = { 215 "Clamp", "Repeat", "Mirror" 216 }; 217 218 SkScalar y = SkIntToScalar(24); 219 SkScalar x = SkIntToScalar(66); 220 221 SkPaint p; 222 p.setAntiAlias(true); 223 sk_tool_utils::set_portable_typeface(&p); 224 p.setTextAlign(SkPaint::kCenter_Align); 225 226 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) { 227 SkString str(gModeNames[kx]); 228 canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p); 229 x += r.width() * 4 / 3; 230 } 231 232 y += SkIntToScalar(16) + h; 233 p.setTextAlign(SkPaint::kRight_Align); 234 235 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) { 236 x = SkIntToScalar(16) + w; 237 238 SkString str(gModeNames[ky]); 239 canvas->drawText(str.c_str(), str.size(), x, y + h/2, p); 240 241 x += SkIntToScalar(50); 242 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) { 243 SkPaint paint; 244 paint.setShader(fProc(gModes[kx], gModes[ky]))->unref(); 245 246 canvas->save(); 247 canvas->translate(x, y); 248 canvas->drawRect(r, paint); 249 canvas->restore(); 250 251 x += r.width() * 4 / 3; 252 } 253 y += r.height() * 4 / 3; 254 } 255 } 256 257private: 258 typedef skiagm::GM INHERITED; 259}; 260 261////////////////////////////////////////////////////////////////////////////// 262 263DEF_GM( return new TilingGM(true); ) 264DEF_GM( return new TilingGM(false); ) 265DEF_GM( return new Tiling2GM(make_bm, "bitmap"); ) 266DEF_GM( return new Tiling2GM(make_grad, "gradient"); ) 267