e267464b89
This also has several other bug fixes and refactorings within it that I realized were possible while updating every where that had checked sigma > 0 to be sigma > kEffectivelyZeroSigma. The big things are that SkBlurPriv.h goes away and its functions are just moved into SkGpuBlurUtils since they were only used by the GPU. The implementations of those functions are also collected into SkGpuBlurUtils.cpp. I removed the GrMatrixConvolution::MakeGaussian, in favor of SkGpuBlurUtils filling in the kernel itself and then calling the regular Make. This let me consolidate two different 1D kernel computing functions, and remove the 1D fallback code from the 2D kernel calculation because GaussianBlur() can detect that earlier. The new GM, BlurSigmaSmall, originally drew incorrectly on the GPU backend because it's small but non-zero sigma would trick the sigma > 0 checks in various places so we'd do a full 2 pass X/Y blur. However, when the sigma was too small, the kernel was just filled with 0s so the Y pass would effectively clear everything. While I could have just fixed that to be a [0, 1, 0] kernel, updating the blur pipeline to compare against integer radii seems more robust. Change-Id: I3c41e0235a27615a9056b25e627ffedd995264bd Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328797 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
150 lines
5.2 KiB
C++
150 lines
5.2 KiB
C++
/*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "gm/gm.h"
|
|
#include "include/core/SkBlurTypes.h"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkColor.h"
|
|
#include "include/core/SkFont.h"
|
|
#include "include/core/SkMaskFilter.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkPathBuilder.h"
|
|
#include "include/core/SkRect.h"
|
|
#include "include/core/SkRefCnt.h"
|
|
#include "include/core/SkScalar.h"
|
|
#include "include/core/SkTypeface.h"
|
|
#include "include/core/SkTypes.h"
|
|
#include "include/effects/SkImageFilters.h"
|
|
#include "src/core/SkBlurMask.h"
|
|
#include "tools/Resources.h"
|
|
#include "tools/ToolUtils.h"
|
|
|
|
DEF_SIMPLE_GM_BG(blurs, canvas, 700, 500, 0xFFDDDDDD) {
|
|
SkBlurStyle NONE = SkBlurStyle(-999);
|
|
const struct {
|
|
SkBlurStyle fStyle;
|
|
int fCx, fCy;
|
|
} gRecs[] = {
|
|
{ NONE, 0, 0 },
|
|
{ kInner_SkBlurStyle, -1, 0 },
|
|
{ kNormal_SkBlurStyle, 0, 1 },
|
|
{ kSolid_SkBlurStyle, 0, -1 },
|
|
{ kOuter_SkBlurStyle, 1, 0 },
|
|
};
|
|
|
|
SkPaint paint;
|
|
paint.setAntiAlias(true);
|
|
paint.setColor(SK_ColorBLUE);
|
|
|
|
canvas->translate(SkIntToScalar(-40), SkIntToScalar(0));
|
|
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
|
|
if (gRecs[i].fStyle != NONE) {
|
|
paint.setMaskFilter(SkMaskFilter::MakeBlur(gRecs[i].fStyle,
|
|
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(20))));
|
|
} else {
|
|
paint.setMaskFilter(nullptr);
|
|
}
|
|
canvas->drawCircle(SkIntToScalar(200 + gRecs[i].fCx*100),
|
|
SkIntToScalar(200 + gRecs[i].fCy*100),
|
|
SkIntToScalar(50),
|
|
paint);
|
|
}
|
|
// draw text
|
|
{
|
|
SkFont font(ToolUtils::create_portable_typeface(), 25);
|
|
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
|
|
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(4))));
|
|
SkScalar x = SkIntToScalar(70);
|
|
SkScalar y = SkIntToScalar(400);
|
|
paint.setColor(SK_ColorBLACK);
|
|
canvas->drawString("Hamburgefons Style", x, y, font, paint);
|
|
canvas->drawString("Hamburgefons Style",
|
|
x, y + SkIntToScalar(50), font, paint);
|
|
paint.setMaskFilter(nullptr);
|
|
paint.setColor(SK_ColorWHITE);
|
|
x -= SkIntToScalar(2);
|
|
y -= SkIntToScalar(2);
|
|
canvas->drawString("Hamburgefons Style", x, y, font, paint);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// exercise a special-case of blurs, which is two nested rects. These are drawn specially,
|
|
// and possibly cached.
|
|
//
|
|
// in particular, we want to notice that the 2nd rect draws slightly differently, since it
|
|
// is translated a fractional amount.
|
|
//
|
|
DEF_SIMPLE_GM(blur2rects, canvas, 700, 500) {
|
|
SkPaint paint;
|
|
|
|
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 2.3f));
|
|
|
|
SkRect outer = SkRect::MakeXYWH(10.125f, 10.125f, 100.125f, 100);
|
|
SkRect inner = SkRect::MakeXYWH(20.25f, 20.125f, 80, 80);
|
|
SkPath path = SkPathBuilder().addRect(outer, SkPathDirection::kCW)
|
|
.addRect(inner, SkPathDirection::kCCW)
|
|
.detach();
|
|
|
|
canvas->drawPath(path, paint);
|
|
// important to translate by a factional amount to exercise a different "phase"
|
|
// of the same path w.r.t. the pixel grid
|
|
SkScalar dx = SkScalarRoundToScalar(path.getBounds().width()) + 14 + 0.25f;
|
|
canvas->translate(dx, 0);
|
|
canvas->drawPath(path, paint);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(blur2rectsnonninepatch, canvas, 700, 500) {
|
|
SkPaint paint;
|
|
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 4.3f));
|
|
|
|
SkRect outer = SkRect::MakeXYWH(10, 110, 100, 100);
|
|
SkRect inner = SkRect::MakeXYWH(50, 150, 10, 10);
|
|
SkPath path = SkPathBuilder().addRect(outer, SkPathDirection::kCW)
|
|
.addRect(inner, SkPathDirection::kCW)
|
|
.detach();
|
|
canvas->drawPath(path, paint);
|
|
|
|
SkScalar dx = SkScalarRoundToScalar(path.getBounds().width()) + 40 + 0.25f;
|
|
canvas->translate(dx, 0);
|
|
canvas->drawPath(path, paint);
|
|
|
|
// Translate to outside of clip bounds.
|
|
canvas->translate(-dx, 0);
|
|
canvas->translate(-30, -150);
|
|
canvas->drawPath(path, paint);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(BlurDrawImage, canvas, 256, 256) {
|
|
SkPaint paint;
|
|
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 10));
|
|
canvas->clear(0xFF88FF88);
|
|
if (auto image = GetResourceAsImage("images/mandrill_512_q075.jpg")) {
|
|
canvas->scale(0.25, 0.25);
|
|
canvas->drawImage(image, 256, 256, &paint);
|
|
}
|
|
}
|
|
|
|
DEF_SIMPLE_GM(BlurBigSigma, canvas, 1024, 1024) {
|
|
SkPaint layerPaint, p;
|
|
|
|
p.setImageFilter(SkImageFilters::Blur(500, 500, nullptr));
|
|
|
|
canvas->drawRect(SkRect::MakeWH(700, 800), p);
|
|
}
|
|
|
|
DEF_SIMPLE_GM(BlurSmallSigma, canvas, 256, 256) {
|
|
// Normal sigma on x-axis, a small but non-zero sigma on y-axis that should
|
|
// be treated as identity.
|
|
|
|
SkPaint paint;
|
|
paint.setImageFilter(SkImageFilters::Blur(16.f, 1e-5f, nullptr));
|
|
canvas->drawRect(SkRect::MakeLTRB(64, 64, 192, 192), paint);
|
|
}
|