drawBitmapRect() should not touch the CTM when mask filters are present
Blur sigma calculations are CTM dependent, so we cannot take the drawBitmap() fast path in the presence of mask filters. BUG=skia:5682 R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2286873002 Review-Url: https://codereview.chromium.org/2286873002
This commit is contained in:
parent
febb224699
commit
ab83da7142
@ -93,17 +93,43 @@ static sk_sp<SkImage> makebm(SkCanvas* origCanvas, SkBitmap* resultBM, int w, in
|
||||
return image;
|
||||
}
|
||||
|
||||
static void canvasproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
|
||||
const SkRect& dstR) {
|
||||
canvas->drawBitmapRect(bm, srcR, dstR, nullptr);
|
||||
static void bitmapproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
|
||||
const SkRect& dstR, const SkPaint* paint) {
|
||||
canvas->drawBitmapRect(bm, srcR, dstR, paint);
|
||||
}
|
||||
|
||||
static void bitmapsubsetproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
|
||||
const SkRect& dstR, const SkPaint* paint) {
|
||||
if (!bm.bounds().contains(srcR)) {
|
||||
bitmapproc(canvas, nullptr, bm, srcR, dstR, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
SkBitmap subset;
|
||||
if (bm.extractSubset(&subset, srcR)) {
|
||||
canvas->drawBitmapRect(subset, dstR, paint);
|
||||
}
|
||||
}
|
||||
|
||||
static void imageproc(SkCanvas* canvas, SkImage* image, const SkBitmap&, const SkIRect& srcR,
|
||||
const SkRect& dstR) {
|
||||
canvas->drawImageRect(image, srcR, dstR, nullptr);
|
||||
const SkRect& dstR, const SkPaint* paint) {
|
||||
canvas->drawImageRect(image, srcR, dstR, paint);
|
||||
}
|
||||
|
||||
typedef void DrawRectRectProc(SkCanvas*, SkImage*, const SkBitmap&, const SkIRect&, const SkRect&);
|
||||
static void imagesubsetproc(SkCanvas* canvas, SkImage* image, const SkBitmap& bm,
|
||||
const SkIRect& srcR, const SkRect& dstR, const SkPaint* paint) {
|
||||
if (!image->bounds().contains(srcR)) {
|
||||
imageproc(canvas, image, bm, srcR, dstR, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sk_sp<SkImage> subset = image->makeSubset(srcR)) {
|
||||
canvas->drawImageRect(subset, dstR, paint);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void DrawRectRectProc(SkCanvas*, SkImage*, const SkBitmap&, const SkIRect&, const SkRect&,
|
||||
const SkPaint*);
|
||||
|
||||
static const int gSize = 1024;
|
||||
static const int gBmpSize = 2048;
|
||||
@ -164,7 +190,7 @@ protected:
|
||||
for (int h = 1; h <= kMaxSrcRectSize; h *= 4) {
|
||||
|
||||
SkIRect srcRect = SkIRect::MakeXYWH((gBmpSize - w) / 2, (gBmpSize - h) / 2, w, h);
|
||||
fProc(canvas, fImage.get(), fLargeBitmap, srcRect, dstRect);
|
||||
fProc(canvas, fImage.get(), fLargeBitmap, srcRect, dstRect, nullptr);
|
||||
|
||||
SkString label;
|
||||
label.appendf("%d x %d", w, h);
|
||||
@ -206,9 +232,10 @@ protected:
|
||||
paint.setMaskFilter(SkBlurMaskFilter::Make(
|
||||
kNormal_SkBlurStyle,
|
||||
SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
|
||||
SkBlurMaskFilter::kHighQuality_BlurFlag |
|
||||
SkBlurMaskFilter::kIgnoreTransform_BlurFlag));
|
||||
canvas->drawBitmapRect(bm, srcRect, dstRect, &paint);
|
||||
SkBlurMaskFilter::kHighQuality_BlurFlag));
|
||||
|
||||
sk_sp<SkImage> image(SkImage::MakeFromBitmap(bm));
|
||||
fProc(canvas, image.get(), bm, srcRect, dstRect, &paint);
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,5 +243,7 @@ private:
|
||||
typedef skiagm::GM INHERITED;
|
||||
};
|
||||
|
||||
DEF_GM( return new DrawBitmapRectGM(canvasproc, nullptr); )
|
||||
DEF_GM( return new DrawBitmapRectGM(imageproc, "-imagerect"); )
|
||||
DEF_GM( return new DrawBitmapRectGM(bitmapproc , nullptr); )
|
||||
DEF_GM( return new DrawBitmapRectGM(bitmapsubsetproc, "-subset"); )
|
||||
DEF_GM( return new DrawBitmapRectGM(imageproc , "-imagerect"); )
|
||||
DEF_GM( return new DrawBitmapRectGM(imagesubsetproc , "-imagerect-subset"); )
|
||||
|
@ -233,6 +233,15 @@ void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
draw.drawBitmap(bitmap, matrix, nullptr, paint);
|
||||
}
|
||||
|
||||
static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
|
||||
if (!paint.getMaskFilter()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Some mask filters parameters (sigma) depend on the CTM/scale.
|
||||
return m.getType() <= SkMatrix::kTranslate_Mask;
|
||||
}
|
||||
|
||||
void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
const SkRect* src, const SkRect& dst,
|
||||
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
|
||||
@ -309,8 +318,10 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
|
||||
// We can go faster by just calling drawBitmap, which will concat the
|
||||
// matrix with the CTM, and try to call drawSprite if it can. If not,
|
||||
// it will make a shader and call drawRect, as we do below.
|
||||
draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
return;
|
||||
if (CanApplyDstMatrixAsCTM(matrix, paint)) {
|
||||
draw.drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
USE_SHADER:
|
||||
|
Loading…
Reference in New Issue
Block a user