In the CPU backend, stop treating alpha images as coverage

This makes behavior (more) consistent with the GPU. In particular, the
alpha_image GM now looks roughly identical (it was very different
before).

Bug: skia:9692
Change-Id: I405375760ffe90577f863fa2d8eb9d2fc0f6edf8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/472799
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2021-11-17 12:20:09 -05:00 committed by SkCQ
parent 6d1d2c0898
commit f1660bf1ba
4 changed files with 5 additions and 144 deletions

View File

@ -273,20 +273,6 @@ void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
/////////////////////// these are not virtual, just helpers
void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
if (clip.quickReject(mask.fBounds)) {
return;
}
SkRegion::Cliperator clipper(clip, mask.fBounds);
while (!clipper.done()) {
const SkIRect& cr = clipper.rect();
this->blitMask(mask, cr);
clipper.next();
}
}
void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
SkRegion::Cliperator clipper(clip, rect);

View File

@ -132,7 +132,6 @@ public:
}
///@name non-virtual helpers
void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
void blitRegion(const SkRegion& clip);
///@}

View File

@ -700,37 +700,6 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
}
}
void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
if (srcM.fBounds.isEmpty()) {
return;
}
const SkMask* mask = &srcM;
SkMask dstM;
if (paint.getMaskFilter() &&
as_MFB(paint.getMaskFilter())
->filterMask(&dstM, srcM, fMatrixProvider->localToDevice(), nullptr)) {
mask = &dstM;
}
SkAutoMaskFreeImage ami(dstM.fImage);
SkAutoBlitterChoose blitterChooser(*this, nullptr, paint);
SkBlitter* blitter = blitterChooser.get();
SkAAClipBlitterWrapper wrapper;
const SkRegion* clipRgn;
if (fRC->isBW()) {
clipRgn = &fRC->bwRgn();
} else {
wrapper.init(*fRC, blitter);
clipRgn = &wrapper.getRgn();
blitter = wrapper.getBlitter();
}
blitter->blitMaskRegion(*mask, *clipRgn);
}
static SkScalar fast_len(const SkVector& vec) {
SkScalar x = SkScalarAbs(vec.fX);
SkScalar y = SkScalarAbs(vec.fY);
@ -957,92 +926,6 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
}
void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkSamplingOptions& sampling,
const SkPaint& paint) const {
SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
// nothing to draw
if (fRC->isEmpty()) {
return;
}
SkMatrix ctm = fMatrixProvider->localToDevice();
if (SkTreatAsSprite(ctm, bitmap.dimensions(), sampling, paint))
{
int ix = SkScalarRoundToInt(ctm.getTranslateX());
int iy = SkScalarRoundToInt(ctm.getTranslateY());
SkPixmap pmap;
if (!bitmap.peekPixels(&pmap)) {
return;
}
SkMask mask;
mask.fBounds.setXYWH(ix, iy, pmap.width(), pmap.height());
mask.fFormat = SkMask::kA8_Format;
mask.fRowBytes = SkToU32(pmap.rowBytes());
// fImage is typed as writable, but in this case it is used read-only
mask.fImage = (uint8_t*)pmap.addr8(0, 0);
this->drawDevMask(mask, paint);
} else { // need to xform the bitmap first
SkRect r;
SkMask mask;
r.setIWH(bitmap.width(), bitmap.height());
ctm.mapRect(&r);
r.round(&mask.fBounds);
// set the mask's bounds to the transformed bitmap-bounds,
// clipped to the actual device and further limited by the clip bounds
{
SkASSERT(fDst.bounds().contains(fRC->getBounds()));
SkIRect devBounds = fDst.bounds();
devBounds.intersect(fRC->getBounds().makeOutset(1, 1));
// need intersect(l, t, r, b) on irect
if (!mask.fBounds.intersect(devBounds)) {
return;
}
}
mask.fFormat = SkMask::kA8_Format;
mask.fRowBytes = SkAlign4(mask.fBounds.width());
size_t size = mask.computeImageSize();
if (0 == size) {
// the mask is too big to allocated, draw nothing
return;
}
// allocate (and clear) our temp buffer to hold the transformed bitmap
SkAutoTMalloc<uint8_t> storage(size);
mask.fImage = storage.get();
memset(mask.fImage, 0, size);
// now draw our bitmap(src) into mask(dst), transformed by the matrix
{
SkBitmap device;
device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
mask.fImage, mask.fRowBytes);
SkCanvas c(device);
// need the unclipped top/left for the translate
c.translate(-SkIntToScalar(mask.fBounds.fLeft),
-SkIntToScalar(mask.fBounds.fTop));
c.concat(ctm);
// We can't call drawBitmap, or we'll infinitely recurse. Instead
// we manually build a shader and draw that into our new mask
SkPaint tmpPaint;
tmpPaint.setAntiAlias(paint.isAntiAlias());
tmpPaint.setDither(paint.isDither());
SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap, sampling);
SkRect rr;
rr.setIWH(bitmap.width(), bitmap.height());
c.drawRect(rr, paintWithShader);
}
this->drawDevMask(mask, paint);
}
}
static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
const SkRect& srcR) {
SkRect dstR;
@ -1116,16 +999,12 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
SkDraw draw(*this);
draw.fMatrixProvider = &matrixProvider;
if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) {
draw.drawBitmapAsMask(bitmap, sampling, *paint);
SkPaint paintWithShader = make_paint_with_image(*paint, bitmap, sampling);
const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
if (dstBounds) {
this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds);
} else {
SkPaint paintWithShader = make_paint_with_image(*paint, bitmap, sampling);
const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
if (dstBounds) {
this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds);
} else {
draw.drawRect(srcBounds, paintWithShader);
}
draw.drawRect(srcBounds, paintWithShader);
}
}

View File

@ -102,8 +102,6 @@ public:
SkMask* mask, SkMask::CreateMode mode,
SkStrokeRec::InitStyle style);
void drawDevMask(const SkMask& mask, const SkPaint&) const;
enum RectType {
kHair_RectType,
kFill_RectType,
@ -123,7 +121,6 @@ public:
SkPoint* strokeSize);
private:
void drawBitmapAsMask(const SkBitmap&, const SkSamplingOptions&, const SkPaint&) const;
void drawFixedVertices(const SkVertices* vertices,
sk_sp<SkBlender> blender,
const SkPaint& paint,