summaryrefslogtreecommitdiff
path: root/chromium/third_party/skia/gm/complexclip.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/skia/gm/complexclip.cpp
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/skia/gm/complexclip.cpp')
-rw-r--r--chromium/third_party/skia/gm/complexclip.cpp183
1 files changed, 182 insertions, 1 deletions
diff --git a/chromium/third_party/skia/gm/complexclip.cpp b/chromium/third_party/skia/gm/complexclip.cpp
index 6e22dc0b208..e6bef93aaec 100644
--- a/chromium/third_party/skia/gm/complexclip.cpp
+++ b/chromium/third_party/skia/gm/complexclip.cpp
@@ -19,6 +19,7 @@
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
+#include "include/effects/SkGradientShader.h"
#include "src/core/SkClipOpPriv.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"
@@ -239,7 +240,7 @@ DEF_SIMPLE_GM(clip_shader, canvas, 840, 650) {
canvas->translate(img->width() + 10, img->height() + 10);
canvas->clipShader(sh, SkClipOp::kIntersect);
canvas->save();
- SkMatrix lm = SkMatrix::MakeScale(1.0f / 5);
+ SkMatrix lm = SkMatrix::Scale(1.0f/5, 1.0f/5);
canvas->clipShader(img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &lm));
canvas->drawImage(img, 0, 0, nullptr);
@@ -262,3 +263,183 @@ DEF_SIMPLE_GM(clip_shader_layer, canvas, 430, 320) {
canvas->drawColor(0xFFFF0000);
canvas->restore();
}
+
+DEF_SIMPLE_GM(clip_shader_nested, canvas, 256, 256) {
+ float w = 64.f;
+ float h = 64.f;
+
+ const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
+ auto s = SkGradientShader::MakeRadial({0.5f * w, 0.5f * h}, 0.1f * w, gradColors, nullptr,
+ 2, SkTileMode::kRepeat, 0, nullptr);
+
+ SkPaint p;
+
+ // A large black rect affected by two gradient clips
+ canvas->save();
+ canvas->clipShader(s);
+ canvas->scale(2.f, 2.f);
+ canvas->clipShader(s);
+ canvas->drawRect(SkRect::MakeWH(w, h), p);
+ canvas->restore();
+
+ canvas->translate(0.f, 2.f * h);
+
+ // A small red rect, with no clipping
+ canvas->save();
+ p.setColor(SK_ColorRED);
+ canvas->drawRect(SkRect::MakeWH(w, h), p);
+ canvas->restore();
+}
+
+namespace {
+
+// Where is canvas->concat(persp) called relative to the clipShader calls.
+enum ConcatPerspective {
+ kConcatBeforeClips,
+ kConcatAfterClips,
+ kConcatBetweenClips
+};
+// Order in which clipShader(image) and clipShader(gradient) are specified; only meaningful
+// when CanvasPerspective is kConcatBetweenClips.
+enum ClipOrder {
+ kClipImageFirst,
+ kClipGradientFirst,
+
+ kDoesntMatter = kClipImageFirst
+};
+// Which shaders have perspective applied as a local matrix.
+enum LocalMatrix {
+ kNoLocalMat,
+ kImageWithLocalMat,
+ kGradientWithLocalMat,
+ kBothWithLocalMat
+};
+struct Config {
+ ConcatPerspective fConcat;
+ ClipOrder fOrder;
+ LocalMatrix fLM;
+};
+
+static void draw_banner(SkCanvas* canvas, Config config) {
+ SkString banner;
+ banner.append("Persp: ");
+
+ if (config.fConcat == kConcatBeforeClips || config.fLM == kBothWithLocalMat) {
+ banner.append("Both Clips");
+ } else {
+ SkASSERT((config.fConcat == kConcatBetweenClips && config.fLM == kNoLocalMat) ||
+ (config.fConcat == kConcatAfterClips && (config.fLM == kImageWithLocalMat ||
+ config.fLM == kGradientWithLocalMat)));
+ if ((config.fConcat == kConcatBetweenClips && config.fOrder == kClipImageFirst) ||
+ config.fLM == kGradientWithLocalMat) {
+ banner.append("Gradient");
+ } else {
+ SkASSERT(config.fOrder == kClipGradientFirst || config.fLM == kImageWithLocalMat);
+ banner.append("Image");
+ }
+ }
+ if (config.fLM != kNoLocalMat) {
+ banner.append(" (w/ LM, should equal top row)");
+ }
+
+ static const SkFont kFont(ToolUtils::create_portable_typeface(), 12);
+ canvas->drawString(banner.c_str(), 20.f, -30.f, kFont, SkPaint());
+};
+
+} // anonymous
+
+DEF_SIMPLE_GM(clip_shader_persp, canvas, 1370, 1030) {
+ // Each draw has a clipShader(image-shader), a clipShader(gradient-shader), a concat(persp-mat),
+ // and each shader may or may not be wrapped with a perspective local matrix.
+
+ // Pairs of configs that should match in appearance where first config doesn't use a local
+ // matrix (top row of GM) and the second does (bottom row of GM).
+ Config matches[][2] = {
+ // Everything has perspective
+ {{kConcatBeforeClips, kDoesntMatter, kNoLocalMat},
+ {kConcatAfterClips, kDoesntMatter, kBothWithLocalMat}},
+ // Image shader has perspective
+ {{kConcatBetweenClips, kClipGradientFirst, kNoLocalMat},
+ {kConcatAfterClips, kDoesntMatter, kImageWithLocalMat}},
+ // Gradient shader has perspective
+ {{kConcatBetweenClips, kClipImageFirst, kNoLocalMat},
+ {kConcatAfterClips, kDoesntMatter, kGradientWithLocalMat}}
+ };
+
+ // The image that is drawn
+ auto img = GetResourceAsImage("images/yellow_rose.png");
+ // Scale factor always applied to the image shader so that it tiles
+ SkMatrix scale = SkMatrix::Scale(1.f / 4.f, 1.f / 4.f);
+ // The perspective matrix applied wherever needed
+ SkPoint src[4];
+ SkRect::Make(img->dimensions()).toQuad(src);
+ SkPoint dst[4] = {{0, 80.f},
+ {img->width() + 28.f, -100.f},
+ {img->width() - 28.f, img->height() + 100.f},
+ {0.f, img->height() - 80.f}};
+ SkMatrix persp;
+ SkAssertResult(persp.setPolyToPoly(src, dst, 4));
+
+ SkMatrix perspScale = SkMatrix::Concat(persp, scale);
+
+ auto drawConfig = [&](Config config) {
+ canvas->save();
+
+ draw_banner(canvas, config);
+
+ // Make clipShaders (possibly with local matrices)
+ bool gradLM = config.fLM == kGradientWithLocalMat || config.fLM == kBothWithLocalMat;
+ const SkColor gradColors[] = {SK_ColorBLACK, SkColorSetARGB(128, 128, 128, 128)};
+ auto gradShader = SkGradientShader::MakeRadial({0.5f * img->width(), 0.5f * img->height()},
+ 0.1f * img->width(), gradColors, nullptr, 2,
+ SkTileMode::kRepeat, 0,
+ gradLM ? &persp : nullptr);
+ bool imageLM = config.fLM == kImageWithLocalMat || config.fLM == kBothWithLocalMat;
+ auto imgShader = img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
+ imageLM ? perspScale : scale);
+
+ // Perspective before any clipShader
+ if (config.fConcat == kConcatBeforeClips) {
+ canvas->concat(persp);
+ }
+
+ // First clipshader
+ canvas->clipShader(config.fOrder == kClipImageFirst ? imgShader : gradShader);
+
+ // Perspective between clipShader
+ if (config.fConcat == kConcatBetweenClips) {
+ canvas->concat(persp);
+ }
+
+ // Second clipShader
+ canvas->clipShader(config.fOrder == kClipImageFirst ? gradShader : imgShader);
+
+ // Perspective after clipShader
+ if (config.fConcat == kConcatAfterClips) {
+ canvas->concat(persp);
+ }
+
+ // Actual draw and clip boundary are the same for all configs
+ canvas->clipRect(SkRect::MakeIWH(img->width(), img->height()));
+ canvas->clear(SK_ColorBLACK);
+ canvas->drawImage(img, 0, 0);
+
+ canvas->restore();
+ };
+
+ SkIRect grid = persp.mapRect(SkRect::Make(img->dimensions())).roundOut();
+ grid.fLeft -= 20; // manual adjust to look nicer
+
+ canvas->translate(10.f, 10.f);
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(matches); ++i) {
+ canvas->save();
+ canvas->translate(-grid.fLeft, -grid.fTop);
+ drawConfig(matches[i][0]);
+ canvas->translate(0.f, grid.height());
+ drawConfig(matches[i][1]);
+ canvas->restore();
+
+ canvas->translate(grid.width(), 0.f);
+ }
+}