add decal tilemode to shaders
Plenty more to follow-up:
- gradients
- gpu impl
Bug: skia:7638
Change-Id: I8e54fd0e24921f040f178c793b36c7fb855b136e
Reviewed-on: https://skia-review.googlesource.com/107420
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
diff --git a/gm/tilemodes.cpp b/gm/tilemodes.cpp
index f6bd362..587e558 100644
--- a/gm/tilemodes.cpp
+++ b/gm/tilemodes.cpp
@@ -12,12 +12,12 @@
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
-
-
// effects
#include "SkGradientShader.h"
#include "SkBlurDrawLooper.h"
+#include "Resources.h"
+
static void makebm(SkBitmap* bm, SkColorType ct, int w, int h) {
bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType));
bm->eraseColor(SK_ColorTRANSPARENT);
@@ -154,6 +154,8 @@
bool fPowerOfTwoSize;
typedef skiagm::GM INHERITED;
};
+DEF_GM( return new TilingGM(true); )
+DEF_GM( return new TilingGM(false); )
constexpr int gWidth = 32;
constexpr int gHeight = 32;
@@ -257,10 +259,61 @@
private:
typedef skiagm::GM INHERITED;
};
-
-//////////////////////////////////////////////////////////////////////////////
-
-DEF_GM( return new TilingGM(true); )
-DEF_GM( return new TilingGM(false); )
DEF_GM( return new Tiling2GM(make_bm, "bitmap"); )
DEF_GM( return new Tiling2GM(make_grad, "gradient"); )
+
+////////////////////
+
+#include "SkGradientShader.h"
+
+DEF_SIMPLE_GM(tilemode_decal, canvas, 715, 560) {
+ auto img = GetResourceAsImage("images/mandrill_128.png");
+ SkPaint bgpaint;
+ bgpaint.setColor(SK_ColorYELLOW);
+
+ SkRect r = { -20, -20, img->width() + 20.0f, img->height() + 20.0f };
+ canvas->translate(25, 25);
+
+ std::function<void(SkPaint*, SkShader::TileMode, SkShader::TileMode)> shader_procs[] = {
+ [img](SkPaint* paint, SkShader::TileMode tx, SkShader::TileMode ty) {
+ paint->setShader(img->makeShader(tx, ty));
+ },
+ [img](SkPaint* paint, SkShader::TileMode tx, SkShader::TileMode ty) {
+ SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
+ const SkPoint pts[] = {{ 0, 0 }, {img->width()*1.0f, img->height()*1.0f }};
+ const SkScalar* pos = nullptr;
+ const int count = SK_ARRAY_COUNT(colors);
+ paint->setShader(SkGradientShader::MakeLinear(pts, colors, pos, count, tx));
+ },
+ [img](SkPaint* paint, SkShader::TileMode tx, SkShader::TileMode ty) {
+ SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
+ const SkScalar* pos = nullptr;
+ const int count = SK_ARRAY_COUNT(colors);
+ paint->setShader(SkGradientShader::MakeRadial({ img->width()*0.5f, img->width()*0.5f },
+ img->width()*0.5f, colors, pos, count, tx));
+ },
+ };
+
+ const struct XY {
+ SkShader::TileMode fX;
+ SkShader::TileMode fY;
+ } pairs[] = {
+ { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode },
+ { SkShader::kClamp_TileMode, SkShader::kDecal_TileMode },
+ { SkShader::kDecal_TileMode, SkShader::kClamp_TileMode },
+ { SkShader::kDecal_TileMode, SkShader::kDecal_TileMode },
+ };
+ for (const auto& p : pairs) {
+ SkPaint paint;
+ canvas->save();
+ for (const auto& proc : shader_procs) {
+ canvas->drawRect(r, bgpaint);
+ proc(&paint, p.fX, p.fY);
+ canvas->drawRect(r, paint);
+ canvas->translate(0, r.height() + 20);
+ }
+ canvas->restore();
+ canvas->translate(r.width() + 10, 0);
+ }
+}
+