Add GM to exercise some of the darker corners of SkMagnifierImageFilter

An upcoming CL (https://skia-review.googlesource.com/c/7995/ (Remove asTextureRef from SkSpecialImage & update effects accordingly)) modifies some untested portions of the SkMagnifierImageFilter.

This adds a test to prevents regressions.

Change-Id: I9fa406f699e39fa393212e7f63a457b015b36edb
Reviewed-on: https://skia-review.googlesource.com/8023
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2017-02-06 12:32:55 -05:00 committed by Skia Commit-Bot
parent fd197d5034
commit 8bb3b21a4a
3 changed files with 127 additions and 6 deletions

112
gm/simple_magnification.cpp Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright 2017 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 "SkImageSource.h"
#include "SkMagnifierImageFilter.h"
#include "SkSurface.h"
static sk_sp<SkImage> make_image(GrContext* context, int size, GrSurfaceOrigin origin) {
if (context) {
SkImageInfo ii = SkImageInfo::Make(size, size, kN32_SkColorType, kPremul_SkAlphaType);
sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, 0,
origin, nullptr));
SkCanvas* canvas = surf->getCanvas();
canvas->clear(SK_ColorRED);
canvas->drawPoint(1.5f, 1.5f, SK_ColorGREEN);
canvas->drawPoint(2.5f, 1.5f, SK_ColorBLUE);
canvas->drawPoint(1.5f, 2.5f, SK_ColorCYAN);
canvas->drawPoint(2.5f, 2.5f, SK_ColorGRAY);
return surf->makeImageSnapshot();
} else {
SkBitmap bm;
bm.allocN32Pixels(size, size);
bm.eraseRGB(255, 0, 0);
*bm.getAddr32(1, 1) = SkPackARGB32(0xFF, 0x00, 0xFF, 0x00);
*bm.getAddr32(2, 1) = SkPackARGB32(0xFF, 0x00, 0x00, 0xFF);
*bm.getAddr32(1, 2) = SkPackARGB32(0xFF, 0x00, 0xFF, 0xFF);
*bm.getAddr32(2, 2) = SkPackARGB32(0xFF, 0x88, 0x88, 0x88);
return SkImage::MakeFromBitmap(bm);
}
}
/*
* This GM creates an image with a 2x2:
* Green | Blue
* ------------
* Cyan | Gray
* block of pixels in one corner of a 33x33 field. The 'srcRect' feature of the
* SkMagnifierImageFilter is then used to blow it up with different inset border widths.
*
* In GPU-mode we wind up drawing 4 rects:
*
* BottomLeft origin + 1-wide inset | TopLeft origin + 1-wide inset
* ----------------------------------------------------------------
* BottomLeft origin + 7-wide inset | TopLeft origin + 7-wide inset
*
* In Raster-mode the source origin isn't used.
*/
class SimpleMagnificationGM : public skiagm::GM {
public:
SimpleMagnificationGM() {
this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
}
protected:
SkString onShortName() override {
return SkString("simple-magnification");
}
SkISize onISize() override {
return SkISize::Make(3*kPad+2*kImgSize, 3*kPad+2*kImgSize);
}
void draw(SkCanvas* canvas, sk_sp<SkImage> image, const SkIPoint& offset, int inset) {
sk_sp<SkImageFilter> imgSrc(SkImageSource::Make(std::move(image)));
SkRect srcRect = SkRect::MakeXYWH(1.0f, 1.0f, 2.0f, 2.0f);
sk_sp<SkImageFilter> magFilter(SkMagnifierImageFilter::Make(srcRect, inset, imgSrc));
SkPaint paint;
paint.setImageFilter(std::move(magFilter));
canvas->save();
canvas->translate(offset.fX, offset.fY);
SkRect rect = SkRect::MakeWH(kImgSize, kImgSize);
canvas->drawRect(rect, paint);
canvas->restore();
}
void onDraw(SkCanvas* canvas) override {
GrContext* context = canvas->getGrContext();
sk_sp<SkImage> bottomLImg = make_image(context, kImgSize, kBottomLeft_GrSurfaceOrigin);
sk_sp<SkImage> topLImg = make_image(context, kImgSize, kTopLeft_GrSurfaceOrigin);
int bigOffset = 2 * kPad + kImgSize;
this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, kPad), 1);
this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, kPad), 1);
this->draw(canvas, bottomLImg, SkIPoint::Make(kPad, bigOffset), 7);
this->draw(canvas, topLImg, SkIPoint::Make(bigOffset, bigOffset), 7);
}
private:
static const int kImgSize = 33;
static const int kPad = 2;
typedef skiagm::GM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_GM(return new SimpleMagnificationGM;)

View File

@ -253,6 +253,7 @@ gm_sources = [
"$_gm/shapes.cpp",
"$_gm/showmiplevels.cpp",
"$_gm/simpleaaclip.cpp",
"$_gm/simple_magnification.cpp",
"$_gm/simplerect.cpp",
"$_gm/skbug_257.cpp",
"$_gm/skbug_4868.cpp",

View File

@ -83,12 +83,20 @@ sk_sp<SkSpecialImage> SkImageSource::onFilterImage(SkSpecialImage* source, const
ctx.ctm().mapRect(&dstRect, fDstRect);
SkRect bounds = SkRect::MakeIWH(fImage->width(), fImage->height());
if (fSrcRect == bounds && dstRect == bounds) {
// No regions cropped out or resized; return entire image.
offset->fX = offset->fY = 0;
return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(fImage->width(), fImage->height()),
fImage, ctx.outputProperties().colorSpace(),
&source->props());
if (fSrcRect == bounds) {
int iLeft = dstRect.fLeft;
int iTop = dstRect.fTop;
// TODO: this seems to be a very noise-prone way to determine this (esp. the floating-point
// widths & heights).
if (dstRect.width() == bounds.width() && dstRect.height() == bounds.height() &&
iLeft == dstRect.fLeft && iTop == dstRect.fTop) {
// The dest is just an un-scaled integer translation of the entire image; return it
offset->fX = iLeft;
offset->fY = iTop;
return SkSpecialImage::MakeFromImage(SkIRect::MakeWH(fImage->width(), fImage->height()),
fImage, ctx.outputProperties().colorSpace(),
&source->props());
}
}
const SkIRect dstIRect = dstRect.roundOut();