diff options
author | 2015-04-09 06:47:12 -0700 | |
---|---|---|
committer | 2015-04-09 06:47:12 -0700 | |
commit | e275fdf812b1dc09beaa3b14570eb0b641a07e6a (patch) | |
tree | 248ed71d69d11bb80b90d37ce51bfd340eafb944 | |
parent | f57546ec7f9ab116d80044e19aa5e72060dbff09 (diff) |
Add GM to repro crbug.com/472795
This CL also adds a new parameter to SkBitmapSource which gives the user control of the filter quality.
BUG=472795
Review URL: https://codereview.chromium.org/1072603002
-rw-r--r-- | gm/bitmapsource2.cpp | 90 | ||||
-rw-r--r-- | gyp/gmslides.gypi | 1 | ||||
-rw-r--r-- | include/effects/SkBitmapSource.h | 13 | ||||
-rw-r--r-- | src/effects/SkBitmapSource.cpp | 14 |
4 files changed, 110 insertions, 8 deletions
diff --git a/gm/bitmapsource2.cpp b/gm/bitmapsource2.cpp new file mode 100644 index 0000000000..bc4acf717c --- /dev/null +++ b/gm/bitmapsource2.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkBitmapSource.h" + +namespace skiagm { + +// This GM reproduces the issue in crbug.com/472795. The SkBitmapSource image +// is shifted for high quality mode between cpu and gpu. +class BitmapSourceGM : public GM { +public: + BitmapSourceGM(const char* suffix, SkFilterQuality filter) : fSuffix(suffix), fFilter(filter) { + this->setBGColor(0xFFFFFFFF); + } + +protected: + SkString onShortName() override { + SkString name("bitmapsrc2_"); + name.append(fSuffix); + return name; + } + + SkISize onISize() override { return SkISize::Make(256, 256); } + + // Create a bitmap with high frequency vertical stripes + void onOnceBeforeDraw() override { + static const SkPMColor gColors[] = { + SK_ColorRED, SK_ColorGRAY, + SK_ColorGREEN, SK_ColorGRAY, + SK_ColorBLUE, SK_ColorGRAY, + SK_ColorCYAN, SK_ColorGRAY, + SK_ColorMAGENTA, SK_ColorGRAY, + SK_ColorYELLOW, SK_ColorGRAY, + SK_ColorWHITE, SK_ColorGRAY, + }; + + fBM.allocN32Pixels(kImageSize, kImageSize, true); + + SkCanvas canvas(fBM); + + int curColor = 0; + + for (int x = 0; x < kImageSize; x += 3) { + SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(0), + SkIntToScalar(3), SkIntToScalar(kImageSize)); + SkPaint p; + p.setColor(gColors[curColor]); + canvas.drawRect(r, p); + + curColor = (curColor+1) % SK_ARRAY_COUNT(gColors); + } + } + + void onDraw(SkCanvas* canvas) override { + SkRect srcRect = SkRect::MakeLTRB(0, 0, + SkIntToScalar(kImageSize), SkIntToScalar(kImageSize)); + SkRect dstRect = SkRect::MakeLTRB(0.75f, 0.75f, 225.75f, 225.75f); + + SkAutoTUnref<SkImageFilter> filter(SkBitmapSource::Create(fBM, srcRect, dstRect, fFilter)); + + SkPaint p; + p.setImageFilter(filter); + + canvas->saveLayer(NULL, &p); + canvas->restore(); + } + +private: + static const int kImageSize = 503; + + SkString fSuffix; + SkFilterQuality fFilter; + SkBitmap fBM; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM( return SkNEW_ARGS(BitmapSourceGM, ("none", kNone_SkFilterQuality) ); ) +DEF_GM( return SkNEW_ARGS(BitmapSourceGM, ("low", kLow_SkFilterQuality) ); ) +DEF_GM( return SkNEW_ARGS(BitmapSourceGM, ("med", kMedium_SkFilterQuality) ); ) +DEF_GM( return SkNEW_ARGS(BitmapSourceGM, ("high", kHigh_SkFilterQuality) ); ) + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 09615fd2ba..dc8062e9d9 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -38,6 +38,7 @@ '../gm/bitmapscroll.cpp', '../gm/bitmapshader.cpp', '../gm/bitmapsource.cpp', + '../gm/bitmapsource2.cpp', '../gm/bleed.cpp', '../gm/blurcircles.cpp', '../gm/blurs.cpp', diff --git a/include/effects/SkBitmapSource.h b/include/effects/SkBitmapSource.h index cd43e8f61f..55b5bedabe 100644 --- a/include/effects/SkBitmapSource.h +++ b/include/effects/SkBitmapSource.h @@ -16,9 +16,10 @@ public: static SkBitmapSource* Create(const SkBitmap& bitmap) { return SkNEW_ARGS(SkBitmapSource, (bitmap)); } - static SkBitmapSource* Create(const SkBitmap& bitmap, const SkRect& srcRect, - const SkRect& dstRect) { - return SkNEW_ARGS(SkBitmapSource, (bitmap, srcRect, dstRect)); + static SkBitmapSource* Create(const SkBitmap& bitmap, + const SkRect& srcRect, const SkRect& dstRect, + SkFilterQuality filterQuality = kHigh_SkFilterQuality) { + return SkNEW_ARGS(SkBitmapSource, (bitmap, srcRect, dstRect, filterQuality)); } void computeFastBounds(const SkRect& src, SkRect* dst) const override; @@ -27,7 +28,9 @@ public: protected: explicit SkBitmapSource(const SkBitmap& bitmap); - SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect); + SkBitmapSource(const SkBitmap& bitmap, + const SkRect& srcRect, const SkRect& dstRect, + SkFilterQuality filterQuality); void flatten(SkWriteBuffer&) const override; virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, @@ -36,6 +39,8 @@ protected: private: SkBitmap fBitmap; SkRect fSrcRect, fDstRect; + SkFilterQuality fFilterQuality; + typedef SkImageFilter INHERITED; }; diff --git a/src/effects/SkBitmapSource.cpp b/src/effects/SkBitmapSource.cpp index 87c6053cc4..ee8b798936 100644 --- a/src/effects/SkBitmapSource.cpp +++ b/src/effects/SkBitmapSource.cpp @@ -18,13 +18,18 @@ SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap) , fSrcRect(SkRect::MakeWH(SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()))) , fDstRect(fSrcRect) -{} + , fFilterQuality(kHigh_SkFilterQuality) { +} -SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect) +SkBitmapSource::SkBitmapSource(const SkBitmap& bitmap, + const SkRect& srcRect, const SkRect& dstRect, + SkFilterQuality filterQuality) : INHERITED(0, 0) , fBitmap(bitmap) , fSrcRect(srcRect) - , fDstRect(dstRect) {} + , fDstRect(dstRect) + , fFilterQuality(filterQuality) { +} SkFlattenable* SkBitmapSource::CreateProc(SkReadBuffer& buffer) { SkRect src, dst; @@ -71,12 +76,13 @@ bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& // None filtering when it's translate-only paint.setFilterQuality( fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? - kNone_SkFilterQuality : kHigh_SkFilterQuality); + kNone_SkFilterQuality : fFilterQuality); canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); *result = device.get()->accessBitmap(false); offset->fX = dstIRect.fLeft; offset->fY = dstIRect.fTop; + return true; } |