tilemodes_scaled.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright 2011 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "gm/gm.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkCanvas.h"
  10. #include "include/core/SkColor.h"
  11. #include "include/core/SkFilterQuality.h"
  12. #include "include/core/SkFont.h"
  13. #include "include/core/SkImageInfo.h"
  14. #include "include/core/SkPaint.h"
  15. #include "include/core/SkPoint.h"
  16. #include "include/core/SkRect.h"
  17. #include "include/core/SkRefCnt.h"
  18. #include "include/core/SkScalar.h"
  19. #include "include/core/SkShader.h"
  20. #include "include/core/SkSize.h"
  21. #include "include/core/SkString.h"
  22. #include "include/core/SkTileMode.h"
  23. #include "include/core/SkTypeface.h"
  24. #include "include/core/SkTypes.h"
  25. #include "include/effects/SkGradientShader.h"
  26. #include "include/utils/SkTextUtils.h"
  27. #include "tools/ToolUtils.h"
  28. static void makebm(SkBitmap* bm, SkColorType ct, int w, int h) {
  29. bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType));
  30. bm->eraseColor(SK_ColorTRANSPARENT);
  31. SkCanvas canvas(*bm);
  32. SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h)} };
  33. SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
  34. SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
  35. SkPaint paint;
  36. paint.setDither(true);
  37. paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos,
  38. SK_ARRAY_COUNT(colors), SkTileMode::kClamp));
  39. canvas.drawPaint(paint);
  40. }
  41. static void setup(SkPaint* paint, const SkBitmap& bm, SkFilterQuality filter_level,
  42. SkTileMode tmx, SkTileMode tmy) {
  43. paint->setShader(bm.makeShader(tmx, tmy));
  44. paint->setFilterQuality(filter_level);
  45. }
  46. constexpr SkColorType gColorTypes[] = {
  47. kN32_SkColorType,
  48. kRGB_565_SkColorType,
  49. };
  50. class ScaledTilingGM : public skiagm::GM {
  51. public:
  52. ScaledTilingGM(bool powerOfTwoSize)
  53. : fPowerOfTwoSize(powerOfTwoSize) {
  54. }
  55. SkBitmap fTexture[SK_ARRAY_COUNT(gColorTypes)];
  56. protected:
  57. enum {
  58. kPOTSize = 4,
  59. kNPOTSize = 3,
  60. };
  61. SkString onShortName() override {
  62. SkString name("scaled_tilemodes");
  63. if (!fPowerOfTwoSize) {
  64. name.append("_npot");
  65. }
  66. return name;
  67. }
  68. SkISize onISize() override { return SkISize::Make(880, 760); }
  69. void onOnceBeforeDraw() override {
  70. int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
  71. for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
  72. makebm(&fTexture[i], gColorTypes[i], size, size);
  73. }
  74. }
  75. void onDraw(SkCanvas* canvas) override {
  76. SkPaint textPaint;
  77. SkFont font(ToolUtils::create_portable_typeface(), 12);
  78. float scale = 32.f/kPOTSize;
  79. int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
  80. SkRect r = { 0, 0, SkIntToScalar(size*2), SkIntToScalar(size*2) };
  81. const char* gColorTypeNames[] = { "8888" , "565", "4444" };
  82. constexpr SkFilterQuality gFilterQualitys[] =
  83. { kNone_SkFilterQuality,
  84. kLow_SkFilterQuality,
  85. kMedium_SkFilterQuality,
  86. kHigh_SkFilterQuality };
  87. const char* gFilterNames[] = { "None", "Low", "Medium", "High" };
  88. constexpr SkTileMode gModes[] = {
  89. SkTileMode::kClamp, SkTileMode::kRepeat, SkTileMode::kMirror };
  90. const char* gModeNames[] = { "C", "R", "M" };
  91. SkScalar y = SkIntToScalar(24);
  92. SkScalar x = SkIntToScalar(10)/scale;
  93. for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
  94. for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
  95. SkString str;
  96. str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
  97. SkTextUtils::DrawString(canvas, str.c_str(), scale*(x + r.width()/2), y, font, SkPaint(),
  98. SkTextUtils::kCenter_Align);
  99. x += r.width() * 4 / 3;
  100. }
  101. }
  102. y = SkIntToScalar(40) / scale;
  103. for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
  104. for (size_t j = 0; j < SK_ARRAY_COUNT(gFilterQualitys); j++) {
  105. x = SkIntToScalar(10)/scale;
  106. for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
  107. for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
  108. SkPaint paint;
  109. #if 1 // Temporary change to regen bitmap before each draw. This may help tracking down an issue
  110. // on SGX where resizing NPOT textures to POT textures exhibits a driver bug.
  111. if (!fPowerOfTwoSize) {
  112. makebm(&fTexture[i], gColorTypes[i], size, size);
  113. }
  114. #endif
  115. setup(&paint, fTexture[i], gFilterQualitys[j], gModes[kx], gModes[ky]);
  116. paint.setDither(true);
  117. canvas->save();
  118. canvas->scale(scale,scale);
  119. canvas->translate(x, y);
  120. canvas->drawRect(r, paint);
  121. canvas->restore();
  122. x += r.width() * 4 / 3;
  123. }
  124. }
  125. canvas->drawString(SkStringPrintf("%s, %s", gColorTypeNames[i], gFilterNames[j]),
  126. scale * x, scale * (y + r.height() * 2 / 3), font, textPaint);
  127. y += r.height() * 4 / 3;
  128. }
  129. }
  130. }
  131. private:
  132. bool fPowerOfTwoSize;
  133. typedef skiagm::GM INHERITED;
  134. };
  135. constexpr int gWidth = 32;
  136. constexpr int gHeight = 32;
  137. static sk_sp<SkShader> make_bm(SkTileMode tx, SkTileMode ty) {
  138. SkBitmap bm;
  139. makebm(&bm, kN32_SkColorType, gWidth, gHeight);
  140. return bm.makeShader(tx, ty);
  141. }
  142. static sk_sp<SkShader> make_grad(SkTileMode tx, SkTileMode ty) {
  143. SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(gWidth), SkIntToScalar(gHeight)} };
  144. SkPoint center = { SkIntToScalar(gWidth)/2, SkIntToScalar(gHeight)/2 };
  145. SkScalar rad = SkIntToScalar(gWidth)/2;
  146. SkColor colors[] = {0xFFFF0000, ToolUtils::color_to_565(0xFF0044FF)};
  147. int index = (int)ty;
  148. switch (index % 3) {
  149. case 0:
  150. return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors), tx);
  151. case 1:
  152. return SkGradientShader::MakeRadial(center, rad, colors, nullptr, SK_ARRAY_COUNT(colors), tx);
  153. case 2:
  154. return SkGradientShader::MakeSweep(center.fX, center.fY, colors, nullptr, SK_ARRAY_COUNT(colors));
  155. }
  156. return nullptr;
  157. }
  158. typedef sk_sp<SkShader> (*ShaderProc)(SkTileMode, SkTileMode);
  159. class ScaledTiling2GM : public skiagm::GM {
  160. ShaderProc fProc;
  161. const char* fName;
  162. public:
  163. ScaledTiling2GM(ShaderProc proc, const char name[]) : fProc(proc), fName(name) {}
  164. private:
  165. SkString onShortName() override { return SkString(fName); }
  166. SkISize onISize() override { return SkISize::Make(650, 610); }
  167. void onDraw(SkCanvas* canvas) override {
  168. canvas->scale(SkIntToScalar(3)/2, SkIntToScalar(3)/2);
  169. const SkScalar w = SkIntToScalar(gWidth);
  170. const SkScalar h = SkIntToScalar(gHeight);
  171. SkRect r = { -w, -h, w*2, h*2 };
  172. constexpr SkTileMode gModes[] = {
  173. SkTileMode::kClamp, SkTileMode::kRepeat, SkTileMode::kMirror
  174. };
  175. const char* gModeNames[] = {
  176. "Clamp", "Repeat", "Mirror"
  177. };
  178. SkScalar y = SkIntToScalar(24);
  179. SkScalar x = SkIntToScalar(66);
  180. SkFont font(ToolUtils::create_portable_typeface());
  181. for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
  182. SkString str(gModeNames[kx]);
  183. SkTextUtils::DrawString(canvas, str.c_str(), x + r.width()/2, y, font, SkPaint(),
  184. SkTextUtils::kCenter_Align);
  185. x += r.width() * 4 / 3;
  186. }
  187. y += SkIntToScalar(16) + h;
  188. for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
  189. x = SkIntToScalar(16) + w;
  190. SkString str(gModeNames[ky]);
  191. SkTextUtils::DrawString(canvas, str.c_str(), x, y + h/2, font, SkPaint(), SkTextUtils::kRight_Align);
  192. x += SkIntToScalar(50);
  193. for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
  194. SkPaint paint;
  195. paint.setShader(fProc(gModes[kx], gModes[ky]));
  196. canvas->save();
  197. canvas->translate(x, y);
  198. canvas->drawRect(r, paint);
  199. canvas->restore();
  200. x += r.width() * 4 / 3;
  201. }
  202. y += r.height() * 4 / 3;
  203. }
  204. }
  205. };
  206. //////////////////////////////////////////////////////////////////////////////
  207. DEF_GM( return new ScaledTilingGM(true); )
  208. DEF_GM( return new ScaledTilingGM(false); )
  209. DEF_GM( return new ScaledTiling2GM(make_bm, "scaled_tilemode_bitmap"); )
  210. DEF_GM( return new ScaledTiling2GM(make_grad, "scaled_tilemode_gradient"); )