17b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com/* 27b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com* Copyright 2013 Google Inc. 37b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com* 47b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com* Use of this source code is governed by a BSD-style license that can be 57b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com* found in the LICENSE file. 67b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com*/ 77b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 87b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "gm.h" 933d2055e594177b27360f84e0631b26d74a55a9bMike Klein#include "sk_tool_utils.h" 107b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkBlurMask.h" 117b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkBlurMaskFilter.h" 127b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkCanvas.h" 137b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkColorFilter.h" 147b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkLayerDrawLooper.h" 157b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkPaint.h" 167b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkPath.h" 177b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkPoint.h" 187b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkRect.h" 197b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkRRect.h" 207b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com#include "SkString.h" 217b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 228610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com// This GM mimics a blurred RR seen in the wild. 237b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.comclass BlurRoundRectGM : public skiagm::GM { 247b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.compublic: 258610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com BlurRoundRectGM(int width, int height) 26b10fe4941b08172378d3d1928959122f106ced37herb : fName("blurroundrect"), fWidth(width), fHeight(height) { 27ef470f185f0dcd94943d0c470ddf8cc109f30325scroggo fName.appendf("-WH-%ix%i-unevenCorners", width, height); 287b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 297b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 3036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkString onShortName() override { 317b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com return fName; 327b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 337b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 3436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkISize onISize() override { 35b10fe4941b08172378d3d1928959122f106ced37herb return SkISize::Make(fWidth, fHeight); 36b10fe4941b08172378d3d1928959122f106ced37herb } 37b10fe4941b08172378d3d1928959122f106ced37herb 38b10fe4941b08172378d3d1928959122f106ced37herb void onOnceBeforeDraw() override { 39b10fe4941b08172378d3d1928959122f106ced37herb SkVector radii[4]; 40b10fe4941b08172378d3d1928959122f106ced37herb radii[0].set(SkIntToScalar(30), SkIntToScalar(30)); 41b10fe4941b08172378d3d1928959122f106ced37herb radii[1].set(SkIntToScalar(10), SkIntToScalar(10)); 42b10fe4941b08172378d3d1928959122f106ced37herb radii[2].set(SkIntToScalar(30), SkIntToScalar(30)); 43b10fe4941b08172378d3d1928959122f106ced37herb radii[3].set(SkIntToScalar(10), SkIntToScalar(10)); 44b10fe4941b08172378d3d1928959122f106ced37herb SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); 45b10fe4941b08172378d3d1928959122f106ced37herb fRRect.setRectRadii(r, radii); 467b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 477b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 4836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDraw(SkCanvas* canvas) override { 4973cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org SkLayerDrawLooper::Builder looperBuilder; 507b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com { 517b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com SkLayerDrawLooper::LayerInfo info; 528610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit 538610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com | SkLayerDrawLooper::kColorFilter_Bit; 54faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reed info.fColorMode = SkBlendMode::kSrc; 557b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); 567b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com info.fPostTranslate = false; 5773cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org SkPaint* paint = looperBuilder.addLayerOnTop(info); 58efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed paint->setMaskFilter(SkBlurMaskFilter::Make( 59e396455d2d60ddf8e625b5037254f3c09fbcdcf5commit-bot@chromium.org kNormal_SkBlurStyle, 606c1e49af8de1f6dfdc5fb09cd0edfc2e469e945frobertphillips@google.com SkBlurMask::ConvertRadiusToSigma(SK_ScalarHalf), 61efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed SkBlurMaskFilter::kHighQuality_BlurFlag)); 62d053ce9c54d4e5937a142278359e5a4cde18095ereed paint->setColorFilter(SkColorFilter::MakeModeFilter( 63f597c42c50718d5c39769077040de1768c89bbd3caryclark sk_tool_utils::color_to_565(SK_ColorLTGRAY), 647d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed SkBlendMode::kSrcIn)); 65f597c42c50718d5c39769077040de1768c89bbd3caryclark paint->setColor(sk_tool_utils::color_to_565(SK_ColorGRAY)); 667b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 677b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com { 687b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com SkLayerDrawLooper::LayerInfo info; 6973cb15351f33459e0c861a96135c634dec77ef9dcommit-bot@chromium.org looperBuilder.addLayerOnTop(info); 707b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 717b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com SkPaint paint; 728610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com canvas->drawRect(fRRect.rect(), paint); 737b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 747b380d0d0e91ae6967c52bfa14853a77b9551de4reed paint.setLooper(looperBuilder.detach()); 755fdef98f627697966763b88d770a8a8e45c8197ascroggo@google.com paint.setColor(SK_ColorCYAN); 767b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com paint.setAntiAlias(true); 777b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 788610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com canvas->drawRRect(fRRect, paint); 797b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 807b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 817b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.comprivate: 828610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com SkString fName; 838610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com SkRRect fRRect; 84b10fe4941b08172378d3d1928959122f106ced37herb int fWidth, fHeight; 858610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com 868610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com typedef skiagm::GM INHERITED; 877b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com}; 887b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 89341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt#include "SkGradientShader.h" 90341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt/* 91341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt * Spits out a dummy gradient to test blur with shader on paint 92341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt */ 932ad1aa67c6894696cdd65ec56057f81031d1c24areedstatic sk_sp<SkShader> MakeRadial() { 94341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkPoint pts[2] = { 95341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt { 0, 0 }, 96341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt { SkIntToScalar(100), SkIntToScalar(100) } 97341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt }; 98341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkShader::TileMode tm = SkShader::kClamp_TileMode; 99341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, }; 100341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt const SkScalar pos[] = { SK_Scalar1/4, SK_Scalar1*3/4 }; 101341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkMatrix scale; 102341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt scale.setScale(0.5f, 0.5f); 103341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt scale.postTranslate(5.f, 5.f); 104341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkPoint center0, center1; 105341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt center0.set(SkScalarAve(pts[0].fX, pts[1].fX), 106341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkScalarAve(pts[0].fY, pts[1].fY)); 107341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), 108341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); 1092ad1aa67c6894696cdd65ec56057f81031d1c24areed return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7, 1102ad1aa67c6894696cdd65ec56057f81031d1c24areed center0, (pts[1].fX - pts[0].fX) / 2, 1112ad1aa67c6894696cdd65ec56057f81031d1c24areed colors, pos, SK_ARRAY_COUNT(colors), tm, 1122ad1aa67c6894696cdd65ec56057f81031d1c24areed 0, &scale); 113341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt} 114341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt 1158610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com// Simpler blurred RR test cases where all the radii are the same. 1168610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.comclass SimpleBlurRoundRectGM : public skiagm::GM { 1177b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.compublic: 1188610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com SimpleBlurRoundRectGM() 1198610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com : fName("simpleblurroundrect") { 1207b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 1217b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 1227b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.comprotected: 123341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt 12436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkString onShortName() override { 1258610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com return fName; 1268610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com } 1278610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com 12836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkISize onISize() override { 129341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt return SkISize::Make(1000, 500); 1307b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 1317b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 13236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDraw(SkCanvas* canvas) override { 1334b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org canvas->scale(1.5f, 1.5f); 1343d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org canvas->translate(50,50); 1358610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com 1363d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const float blurRadii[] = { 1,5,10,20 }; 1373d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org const int cornerRadii[] = { 1,5,10,20 }; 138341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt const SkRect r = SkRect::MakeWH(SkIntToScalar(25), SkIntToScalar(25)); 1398610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) { 1408610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com SkAutoCanvasRestore autoRestore(canvas, true); 1413d8bf232bd2e4903d2ee2bb575637e7555361604commit-bot@chromium.org canvas->translate(0, (r.height() + SkIntToScalar(50)) * i); 1428610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) { 143341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt for (int k = 0; k <= 1; k++) { 144341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkPaint paint; 145341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt paint.setColor(SK_ColorBLACK); 146efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 147efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])), 148efdfd51b68a300d5c6e28743fe0344ca05d1cec9reed SkBlurMaskFilter::kHighQuality_BlurFlag)); 149341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt 150341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt bool useRadial = SkToBool(k); 151341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt if (useRadial) { 1522ad1aa67c6894696cdd65ec56057f81031d1c24areed paint.setShader(MakeRadial()); 153341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt } 154341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt 155341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkRRect rrect; 156341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), 157341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt SkIntToScalar(cornerRadii[j])); 158341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt canvas->drawRRect(rrect, paint); 159341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt canvas->translate(r.width() + SkIntToScalar(50), 0); 160341400ea7ba0f711ac4c6ead0b33c5c89b4ac55cjoshualitt } 1618610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com } 1628610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com } 1637b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com } 1647b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.comprivate: 1658610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com const SkString fName; 1667b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 1678610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com typedef skiagm::GM INHERITED; 1687b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com}; 1697b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com 1707b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com// Create one with dimensions/rounded corners based on the skp 1717e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com// 1727e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com// TODO(scroggo): Disabled in an attempt to rememdy 1737e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com// https://code.google.com/p/skia/issues/detail?id=1801 ('Win7 Test bots all failing GenerateGMs: 1747e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com// ran wrong number of tests') 1757e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com//DEF_GM(return new BlurRoundRectGM(600, 5514, 6);) 1767e6e80a6eba2ce4250466d4d61e91ad8c609a593epoger@google.com 1777b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com// Rounded rect with two opposite corners with large radii, the other two 1787b0565907272bfe6682b09a36f7a8fef85e0f73dscroggo@google.com// small. 1798610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.comDEF_GM(return new BlurRoundRectGM(100, 100);) 1808610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.com 1818610d2cdbdcc0e1cf28f9a1ffea0ebab53a33485scroggo@google.comDEF_GM(return new SimpleBlurRoundRectGM();) 182