diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/skia/gm/complexclip.cpp | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-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.cpp | 183 |
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); + } +} |