Use explicit sampling in SkDraw

... on our way to adding the parameter to SkDevice

Bug: skia:7650
Change-Id: Iebde07e747741dfb47888426210bf2f231f295aa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345418
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Mike Reed 2020-12-17 15:57:55 -05:00 committed by Skia Commit-Bot
parent 4129b6b65f
commit 172ba9e276
7 changed files with 44 additions and 32 deletions

View File

@ -700,7 +700,7 @@ SkCodec::Result SkWuffsCodec::onIncrementalDecodeTwoPass() {
draw.fRC = &rc;
SkMatrix translate = SkMatrix::Translate(dirty_rect.min_incl_x, dirty_rect.min_incl_y);
draw.drawBitmap(src, translate, nullptr, paint);
draw.drawBitmap(src, translate, nullptr, SkSamplingOptions(), paint);
}
if (result == SkCodec::kSuccess) {

View File

@ -409,7 +409,8 @@ void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
bounds = &storage;
}
}
LOOP_TILER(drawBitmap(bitmap, matrix, dstOrNull, paint), bounds)
SkSamplingOptions sampling(paint.getFilterQuality()); // TODO, pass this in directly
LOOP_TILER(drawBitmap(bitmap, matrix, dstOrNull, sampling, paint), bounds)
}
static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
@ -529,7 +530,9 @@ void SkBitmapDevice::drawImageRect(const SkImage* image,
// construct a shader, so we can call drawRect with the dst
auto s = SkMakeBitmapShaderForPaint(paint, *bitmapPtr, SkTileMode::kClamp,
SkTileMode::kClamp, &matrix, kNever_SkCopyPixelsMode);
SkTileMode::kClamp,
SkSamplingOptions(paint.getFilterQuality()), &matrix,
kNever_SkCopyPixelsMode);
if (!s) {
return;
}
@ -579,8 +582,9 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, const SkPaint& paint) {
draw.fRC = &fRCStack.rc();
SkPaint deviceAsShader = paint;
deviceAsShader.setShader(src->fBitmap.makeShader(SkSamplingOptions()));
draw.drawBitmap(*src->fCoverage, SkMatrix::I(), nullptr, deviceAsShader);
SkSamplingOptions sampling; // nearest-neighbor, since we in sprite mode
deviceAsShader.setShader(src->fBitmap.makeShader(sampling));
draw.drawBitmap(*src->fCoverage, SkMatrix::I(), nullptr, sampling, deviceAsShader);
} else {
this->INHERITED::drawDevice(device, paint);
}
@ -600,7 +604,8 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* src,
draw.fDst = fBitmap.pixmap();
draw.fMatrixProvider = &matrixProvider;
draw.fRC = &fRCStack.rc();
draw.drawBitmap(resultBM, SkMatrix::I(), nullptr, paint);
draw.drawBitmap(resultBM, SkMatrix::I(), nullptr,
SkSamplingOptions(paint.getFilterQuality()), paint);
}
}
sk_sp<SkSpecialImage> SkBitmapDevice::makeSpecial(const SkBitmap& bitmap) {

View File

@ -37,11 +37,19 @@
#include <utility>
static SkPaint make_paint_with_image(
const SkPaint& origPaint, const SkBitmap& bitmap, SkMatrix* matrix = nullptr) {
static bool allows_sprite(const SkSamplingOptions& sampling) {
// Legacy behavior is to ignore sampling if there is no matrix, but new behavior
// should respect cubic, and not draw as sprite. Need to rebaseline test images
// to respect this...
// return !sampling.useCubic
return true;
}
static SkPaint make_paint_with_image(const SkPaint& origPaint, const SkBitmap& bitmap,
const SkSamplingOptions& sampling,
SkMatrix* matrix = nullptr) {
SkPaint paint(origPaint);
paint.setShader(SkMakeBitmapShaderForPaint(origPaint, bitmap, SkTileMode::kClamp,
SkTileMode::kClamp, matrix,
SkTileMode::kClamp, sampling, matrix,
kNever_SkCopyPixelsMode));
return paint;
}
@ -965,7 +973,8 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
}
void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const {
void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkSamplingOptions& sampling,
const SkPaint& paint) const {
SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
// nothing to draw
@ -974,7 +983,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons
}
SkMatrix ctm = fMatrixProvider->localToDevice();
if (SkTreatAsSprite(ctm, bitmap.dimensions(), paint)) {
if (allows_sprite(sampling) && SkTreatAsSprite(ctm, bitmap.dimensions(), paint)) {
int ix = SkScalarRoundToInt(ctm.getTranslateX());
int iy = SkScalarRoundToInt(ctm.getTranslateY());
@ -1040,8 +1049,7 @@ void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) cons
SkPaint tmpPaint;
tmpPaint.setAntiAlias(paint.isAntiAlias());
tmpPaint.setDither(paint.isDither());
tmpPaint.setFilterQuality(paint.getFilterQuality());
SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap);
SkPaint paintWithShader = make_paint_with_image(tmpPaint, bitmap, sampling);
SkRect rr;
rr.setIWH(bitmap.width(), bitmap.height());
c.drawRect(rr, paintWithShader);
@ -1069,7 +1077,8 @@ static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPi
}
void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
const SkRect* dstBounds, const SkPaint& origPaint) const {
const SkRect* dstBounds, const SkSamplingOptions& sampling,
const SkPaint& origPaint) const {
SkDEBUGCODE(this->validate();)
// nothing to draw
@ -1092,6 +1101,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
}
if (bitmap.colorType() != kAlpha_8_SkColorType
&& allows_sprite(sampling)
&& SkTreatAsSprite(matrix, bitmap.dimensions(), *paint)) {
//
// It is safe to call lock pixels now, since we know the matrix is
@ -1123,9 +1133,9 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
draw.fMatrixProvider = &matrixProvider;
if (bitmap.colorType() == kAlpha_8_SkColorType && !paint->getColorFilter()) {
draw.drawBitmapAsMask(bitmap, *paint);
draw.drawBitmapAsMask(bitmap, sampling, *paint);
} else {
SkPaint paintWithShader = make_paint_with_image(*paint, bitmap);
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);
@ -1178,7 +1188,7 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& ori
// create shader with offset
matrix.setTranslate(r.fLeft, r.fTop);
SkPaint paintWithShader = make_paint_with_image(paint, bitmap, &matrix);
SkPaint paintWithShader = make_paint_with_image(paint, bitmap, SkSamplingOptions(), &matrix);
SkDraw draw(*this);
SkOverrideDeviceMatrixProvider matrixProvider(*fMatrixProvider, SkMatrix::I());
draw.fMatrixProvider = &matrixProvider;

View File

@ -59,7 +59,7 @@ public:
/* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
const SkPaint&) const;
const SkSamplingOptions&, const SkPaint&) const;
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
void drawGlyphRunList(const SkGlyphRunList& glyphRunList,
SkGlyphRunListPainter* glyphPainter) const;
@ -124,7 +124,7 @@ public:
static SkScalar ComputeResScaleForStroking(const SkMatrix& );
private:
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
void drawBitmapAsMask(const SkBitmap&, const SkSamplingOptions&, const SkPaint&) const;
void draw_fixed_vertices(const SkVertices*, SkBlendMode, const SkPaint&, const SkMatrix&,
const SkPoint dev2[], const SkPoint3 dev3[], SkArenaAlloc*) const;
void draw_vdata_vertices(const SkVertices*, const SkPaint&, const SkMatrix&,

View File

@ -24,14 +24,15 @@ enum {kSkBlitterContextSize = 3332};
// If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader.
sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkTileMode, SkTileMode,
const SkMatrix* localMatrix, SkCopyPixelsMode);
const SkSamplingOptions&, const SkMatrix* localMatrix,
SkCopyPixelsMode);
// Convenience function to return a shader that implements the shader+image behavior defined for
// drawImage/Bitmap where the paint's shader is ignored when the bitmap is a color image, but
// properly compose them together when it is an alpha image. This allows the returned paint to
// be assigned to a paint clone without discarding the original behavior.
sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src,
SkTileMode, SkTileMode,
SkTileMode, SkTileMode, const SkSamplingOptions&,
const SkMatrix* localMatrix, SkCopyPixelsMode);
/**

View File

@ -500,17 +500,12 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "src/core/SkImagePriv.h"
sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkTileMode tmx, SkTileMode tmy,
const SkMatrix* localMatrix, SkCopyPixelsMode cpm) {
const SkSamplingOptions* inherit_from_paint = nullptr;
return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm),
tmx, tmy, inherit_from_paint, localMatrix);
}
sk_sp<SkShader> SkMakeBitmapShaderForPaint(const SkPaint& paint, const SkBitmap& src,
SkTileMode tmx, SkTileMode tmy,
const SkSamplingOptions& sampling,
const SkMatrix* localMatrix, SkCopyPixelsMode mode) {
auto s = SkMakeBitmapShader(src, tmx, tmy, localMatrix, mode);
auto s = SkImageShader::Make(SkMakeImageFromRasterBitmap(src, mode),
tmx, tmy, &sampling, localMatrix);
if (!s) {
return nullptr;
}

View File

@ -2024,9 +2024,10 @@ void SkXPSDevice::drawImageRect(const SkImage* image,
matrix.mapRect(&actualDst, srcBounds);
}
auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap, SkTileMode::kClamp,
SkTileMode::kClamp, &matrix,
kNever_SkCopyPixelsMode);
auto bitmapShader = SkMakeBitmapShaderForPaint(paint, bitmap,
SkTileMode::kClamp, SkTileMode::kClamp,
SkSamplingOptions(paint.getFilterQuality()),
&matrix, kNever_SkCopyPixelsMode);
SkASSERT(bitmapShader);
if (!bitmapShader) { return; }
SkPaint paintWithShader(paint);