Merge "Modernize calls to drawImage" into sc-dev

This commit is contained in:
Leon Scroggins
2021-01-29 19:17:49 +00:00
committed by Android (Google) Code Review
15 changed files with 66 additions and 40 deletions

View File

@@ -362,13 +362,8 @@ static SkBitmap makeHwCompatible(const FormatInfo& format, const SkBitmap& sourc
return source; return source;
} else { } else {
SkBitmap bitmap; SkBitmap bitmap;
const SkImageInfo& info = source.info(); bitmap.allocPixels(source.info().makeColorType(kN32_SkColorType));
bitmap.allocPixels(info.makeColorType(kN32_SkColorType)); bitmap.writePixels(source.pixmap());
SkCanvas canvas(bitmap);
canvas.drawColor(0);
canvas.drawBitmap(source, 0.0f, 0.0f, nullptr);
return bitmap; return bitmap;
} }
} }

View File

@@ -127,10 +127,11 @@ void Layer::draw(SkCanvas* canvas) {
const SkMatrix& totalMatrix = canvas->getTotalMatrix(); const SkMatrix& totalMatrix = canvas->getTotalMatrix();
SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height()); SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
SkSamplingOptions sampling;
if (getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) { if (getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
paint.setFilterQuality(kLow_SkFilterQuality); sampling = SkSamplingOptions(SkFilterMode::kLinear);
} }
canvas->drawImage(layerImage.get(), 0, 0, &paint); canvas->drawImage(layerImage.get(), 0, 0, sampling, &paint);
// restore the original matrix // restore the original matrix
if (nonIdentityMatrix) { if (nonIdentityMatrix) {
canvas->restore(); canvas->restore();

View File

@@ -487,7 +487,9 @@ struct DrawVectorDrawable final : Op {
tree->getPaintFor(&paint, tree->stagingProperties()); tree->getPaintFor(&paint, tree->stagingProperties());
} }
void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); } void draw(SkCanvas* canvas, const SkMatrix&) const {
mRoot->draw(canvas, mBounds, paint);
}
sp<VectorDrawableRoot> mRoot; sp<VectorDrawableRoot> mRoot;
SkRect mBounds; SkRect mBounds;

View File

@@ -565,7 +565,8 @@ void SkiaCanvas::drawVertices(const SkVertices* vertices, SkBlendMode mode, cons
void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) { void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) {
auto image = bitmap.makeImage(); auto image = bitmap.makeImage();
apply_looper(paint, [&](const SkPaint& p) { apply_looper(paint, [&](const SkPaint& p) {
mCanvas->drawImage(image, left, top, &p); auto sampling = SkSamplingOptions(p.getFilterQuality());
mCanvas->drawImage(image, left, top, sampling, &p);
}); });
} }
@@ -574,7 +575,8 @@ void SkiaCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const Paint*
SkAutoCanvasRestore acr(mCanvas, true); SkAutoCanvasRestore acr(mCanvas, true);
mCanvas->concat(matrix); mCanvas->concat(matrix);
apply_looper(paint, [&](const SkPaint& p) { apply_looper(paint, [&](const SkPaint& p) {
mCanvas->drawImage(image, 0, 0, &p); auto sampling = SkSamplingOptions(p.getFilterQuality());
mCanvas->drawImage(image, 0, 0, sampling, &p);
}); });
} }
@@ -586,10 +588,17 @@ void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float s
SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
apply_looper(paint, [&](const SkPaint& p) { apply_looper(paint, [&](const SkPaint& p) {
mCanvas->drawImageRect(image, srcRect, dstRect, &p, SkCanvas::kFast_SrcRectConstraint); auto sampling = SkSamplingOptions(p.getFilterQuality());
mCanvas->drawImageRect(image, srcRect, dstRect, sampling, &p,
SkCanvas::kFast_SrcRectConstraint);
}); });
} }
static SkFilterMode paintToFilter(const Paint* paint) {
return paint && paint->isFilterBitmap() ? SkFilterMode::kLinear
: SkFilterMode::kNearest;
}
void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
const float* vertices, const int* colors, const Paint* paint) { const float* vertices, const int* colors, const Paint* paint) {
const int ptCount = (meshWidth + 1) * (meshHeight + 1); const int ptCount = (meshWidth + 1) * (meshHeight + 1);
@@ -664,18 +673,25 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
} }
#endif #endif
auto image = bitmap.makeImage();
// cons-up a shader for the bitmap // cons-up a shader for the bitmap
Paint pnt; Paint pnt;
if (paint) { if (paint) {
pnt = *paint; pnt = *paint;
} }
SkSamplingOptions sampling(pnt.isFilterBitmap() ? SkFilterMode::kLinear SkSamplingOptions sampling(paintToFilter(&pnt));
: SkFilterMode::kNearest, pnt.setShader(image->makeShader(sampling));
SkMipmapMode::kNone);
pnt.setShader(bitmap.makeImage()->makeShader(sampling));
auto v = builder.detach(); auto v = builder.detach();
apply_looper(&pnt, [&](const SkPaint& p) { apply_looper(&pnt, [&](const SkPaint& p) {
mCanvas->drawVertices(v, SkBlendMode::kModulate, p); SkPaint copy(p);
auto s = SkSamplingOptions(p.getFilterQuality());
if (s != sampling) {
// apply_looper changed the quality?
copy.setShader(image->makeShader(s));
}
mCanvas->drawVertices(v, SkBlendMode::kModulate, copy);
}); });
} }
@@ -700,13 +716,11 @@ void SkiaCanvas::drawNinePatch(Bitmap& bitmap, const Res_png_9patch& chunk, floa
NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk, colors.get()); NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk, colors.get());
} }
SkFilterMode filter = paint && paint->isFilterBitmap() ? SkFilterMode::kLinear
: SkFilterMode::kNearest;
lattice.fBounds = nullptr; lattice.fBounds = nullptr;
SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
auto image = bitmap.makeImage(); auto image = bitmap.makeImage();
apply_looper(paint, [&](const SkPaint& p) { apply_looper(paint, [&](const SkPaint& p) {
auto filter = SkSamplingOptions(p.getFilterQuality()).filter;
mCanvas->drawImageLattice(image.get(), lattice, dst, filter, &p); mCanvas->drawImageLattice(image.get(), lattice, dst, filter, &p);
}); });
} }

View File

@@ -507,10 +507,12 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint)
sk_sp<SkImage> cachedBitmap = getBitmapUpdateIfDirty().makeImage(); sk_sp<SkImage> cachedBitmap = getBitmapUpdateIfDirty().makeImage();
// HWUI always draws VD with bilinear filtering.
auto sampling = SkSamplingOptions(SkFilterMode::kLinear);
int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth());
int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight());
canvas->drawImageRect(cachedBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, canvas->drawImageRect(cachedBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds,
&paint, SkCanvas::kFast_SrcRectConstraint); sampling, &paint, SkCanvas::kFast_SrcRectConstraint);
} }
void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) { void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {

View File

@@ -351,21 +351,24 @@ struct CanvasOp<CanvasOpType::DrawImage> {
const sk_sp<Bitmap>& bitmap, const sk_sp<Bitmap>& bitmap,
float left, float left,
float top, float top,
SkFilterMode filter,
SkPaint paint SkPaint paint
) : left(left), ) : left(left),
top(top), top(top),
filter(filter),
paint(std::move(paint)), paint(std::move(paint)),
bitmap(bitmap), bitmap(bitmap),
image(bitmap->makeImage()) { } image(bitmap->makeImage()) { }
float left; float left;
float top; float top;
SkFilterMode filter;
SkPaint paint; SkPaint paint;
sk_sp<Bitmap> bitmap; sk_sp<Bitmap> bitmap;
sk_sp<SkImage> image; sk_sp<SkImage> image;
void draw(SkCanvas* canvas) const { void draw(SkCanvas* canvas) const {
canvas->drawImage(image, left, top, &paint); canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint);
} }
ASSERT_DRAWABLE() ASSERT_DRAWABLE()
}; };
@@ -377,15 +380,18 @@ struct CanvasOp<CanvasOpType::DrawImageRect> {
const sk_sp<Bitmap>& bitmap, const sk_sp<Bitmap>& bitmap,
SkRect src, SkRect src,
SkRect dst, SkRect dst,
SkFilterMode filter,
SkPaint paint SkPaint paint
) : src(src), ) : src(src),
dst(dst), dst(dst),
filter(filter),
paint(std::move(paint)), paint(std::move(paint)),
bitmap(bitmap), bitmap(bitmap),
image(bitmap->makeImage()) { } image(bitmap->makeImage()) { }
SkRect src; SkRect src;
SkRect dst; SkRect dst;
SkFilterMode filter;
SkPaint paint; SkPaint paint;
sk_sp<Bitmap> bitmap; sk_sp<Bitmap> bitmap;
sk_sp<SkImage> image; sk_sp<SkImage> image;
@@ -394,6 +400,7 @@ struct CanvasOp<CanvasOpType::DrawImageRect> {
canvas->drawImageRect(image, canvas->drawImageRect(image,
src, src,
dst, dst,
SkSamplingOptions(filter),
&paint, &paint,
SkCanvas::kFast_SrcRectConstraint SkCanvas::kFast_SrcRectConstraint
); );

View File

@@ -437,11 +437,11 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
if (outputMatrix.invert(&inverse)) { if (outputMatrix.invert(&inverse)) {
SkCanvas canvas(tmp, SkCanvas::ColorBehavior::kLegacy); SkCanvas canvas(tmp, SkCanvas::ColorBehavior::kLegacy);
canvas.setMatrix(inverse); canvas.setMatrix(inverse);
SkPaint paint;
paint.setFilterQuality(kLow_SkFilterQuality); // bilinear
SkBitmap priorFrame; SkBitmap priorFrame;
priorFrame.installPixels(outputInfo, pixels, rowBytes); priorFrame.installPixels(outputInfo, pixels, rowBytes);
canvas.drawBitmap(priorFrame, 0, 0, &paint); priorFrame.setImmutable(); // Don't want asImage() to force a copy
canvas.drawImage(priorFrame.asImage(), 0, 0,
SkSamplingOptions(SkFilterMode::kLinear));
} else { } else {
ALOGE("Failed to invert matrix!"); ALOGE("Failed to invert matrix!");
} }
@@ -458,11 +458,11 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) {
SkPaint paint; SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc); paint.setBlendMode(SkBlendMode::kSrc);
paint.setFilterQuality(kLow_SkFilterQuality); // bilinear filtering
SkCanvas canvas(scaledBm, SkCanvas::ColorBehavior::kLegacy); SkCanvas canvas(scaledBm, SkCanvas::ColorBehavior::kLegacy);
canvas.setMatrix(outputMatrix); canvas.setMatrix(outputMatrix);
canvas.drawBitmap(tmp, 0.0f, 0.0f, &paint); tmp.setImmutable(); // Don't want asImage() to force copy
canvas.drawImage(tmp.asImage(), 0, 0, SkSamplingOptions(SkFilterMode::kLinear), &paint);
} }
return result; return result;

View File

@@ -457,11 +457,12 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream,
// outputBitmap. Otherwise we would blend by default, which is not // outputBitmap. Otherwise we would blend by default, which is not
// what we want. // what we want.
paint.setBlendMode(SkBlendMode::kSrc); paint.setBlendMode(SkBlendMode::kSrc);
paint.setFilterQuality(kLow_SkFilterQuality); // bilinear filtering
SkCanvas canvas(outputBitmap, SkCanvas::ColorBehavior::kLegacy); SkCanvas canvas(outputBitmap, SkCanvas::ColorBehavior::kLegacy);
canvas.scale(scaleX, scaleY); canvas.scale(scaleX, scaleY);
canvas.drawBitmap(decodingBitmap, 0.0f, 0.0f, &paint); decodingBitmap.setImmutable(); // so .asImage() doesn't make a copy
canvas.drawImage(decodingBitmap.asImage(), 0.0f, 0.0f,
SkSamplingOptions(SkFilterMode::kLinear), &paint);
} else { } else {
outputBitmap.swap(decodingBitmap); outputBitmap.swap(decodingBitmap);
} }

View File

@@ -141,18 +141,20 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context,
// then use nearest neighbor, otherwise use bilerp sampling. // then use nearest neighbor, otherwise use bilerp sampling.
// Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works // Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works
// only for SrcOver blending and without color filter (readback uses Src blending). // only for SrcOver blending and without color filter (readback uses Src blending).
SkSamplingOptions sampling(SkFilterMode::kNearest);
if (layer->getForceFilter() || if (layer->getForceFilter() ||
shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) { shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) {
paint.setFilterQuality(kLow_SkFilterQuality); sampling = SkSamplingOptions(SkFilterMode::kLinear);
} }
canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint, canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint,
SkCanvas::kFast_SrcRectConstraint); SkCanvas::kFast_SrcRectConstraint);
} else { } else {
SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height()); SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
SkSamplingOptions sampling(SkFilterMode::kNearest);
if (layer->getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) { if (layer->getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
paint.setFilterQuality(kLow_SkFilterQuality); sampling = SkSamplingOptions(SkFilterMode::kLinear);
} }
canvas->drawImage(layerImage.get(), 0, 0, &paint); canvas->drawImage(layerImage.get(), 0, 0, sampling, &paint);
} }
// restore the original matrix // restore the original matrix
if (nonIdentityMatrix) { if (nonIdentityMatrix) {

View File

@@ -169,7 +169,6 @@ void RenderNodeDrawable::forceDraw(SkCanvas* canvas) const {
static bool layerNeedsPaint(const LayerProperties& properties, float alphaMultiplier, static bool layerNeedsPaint(const LayerProperties& properties, float alphaMultiplier,
SkPaint* paint) { SkPaint* paint) {
paint->setFilterQuality(kLow_SkFilterQuality);
if (alphaMultiplier < 1.0f || properties.alpha() < 255 || if (alphaMultiplier < 1.0f || properties.alpha() < 255 ||
properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr || properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr ||
properties.getImageFilter() != nullptr) { properties.getImageFilter() != nullptr) {
@@ -226,6 +225,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer); SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer);
SkPaint paint; SkPaint paint;
layerNeedsPaint(layerProperties, alphaMultiplier, &paint); layerNeedsPaint(layerProperties, alphaMultiplier, &paint);
SkSamplingOptions sampling(SkFilterMode::kLinear);
// surfaces for layers are created on LAYER_SIZE boundaries (which are >= layer size) so // surfaces for layers are created on LAYER_SIZE boundaries (which are >= layer size) so
// we need to restrict the portion of the surface drawn to the size of the renderNode. // we need to restrict the portion of the surface drawn to the size of the renderNode.
@@ -239,7 +239,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
"SurfaceID|%" PRId64, renderNode->uniqueId()).c_str(), nullptr); "SurfaceID|%" PRId64, renderNode->uniqueId()).c_str(), nullptr);
} }
canvas->drawImageRect(renderNode->getLayerSurface()->makeImageSnapshot(), bounds, canvas->drawImageRect(renderNode->getLayerSurface()->makeImageSnapshot(), bounds,
bounds, &paint); bounds, sampling, &paint, SkCanvas::kStrict_SrcRectConstraint);
if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) { if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) {
renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true; renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;

View File

@@ -656,7 +656,7 @@ void SkiaPipeline::renderOverdraw(const SkRect& clip,
SkPaint paint; SkPaint paint;
const SkColor* colors = kOverdrawColors[static_cast<int>(Properties::overdrawColorSet)]; const SkColor* colors = kOverdrawColors[static_cast<int>(Properties::overdrawColorSet)];
paint.setColorFilter(SkOverdrawColorFilter::MakeWithSkColors(colors)); paint.setColorFilter(SkOverdrawColorFilter::MakeWithSkColors(colors));
surface->getCanvas()->drawImage(counts.get(), 0.0f, 0.0f, &paint); surface->getCanvas()->drawImage(counts.get(), 0.0f, 0.0f, SkSamplingOptions(), &paint);
} }
} /* namespace skiapipeline */ } /* namespace skiapipeline */

View File

@@ -182,7 +182,7 @@ void VkInteropFunctorDrawable::onDraw(SkCanvas* canvas) {
auto functorImage = SkImage::MakeFromAHardwareBuffer(mFrameBuffer.get(), kPremul_SkAlphaType, auto functorImage = SkImage::MakeFromAHardwareBuffer(mFrameBuffer.get(), kPremul_SkAlphaType,
canvas->imageInfo().refColorSpace(), canvas->imageInfo().refColorSpace(),
kBottomLeft_GrSurfaceOrigin); kBottomLeft_GrSurfaceOrigin);
canvas->drawImage(functorImage, 0, 0, &paint); canvas->drawImage(functorImage, 0, 0, SkSamplingOptions(), &paint);
canvas->restore(); canvas->restore();
} }

View File

@@ -51,7 +51,7 @@ public:
hardwareBitmap->height(), &canvasBitmap)); hardwareBitmap->height(), &canvasBitmap));
SkCanvas skCanvas(canvasBitmap); SkCanvas skCanvas(canvasBitmap);
skCanvas.drawBitmap(readback, 0, 0); skCanvas.drawImage(readback.asImage(), 0, 0);
canvas.drawBitmap(*heapBitmap, 0, 0, nullptr); canvas.drawBitmap(*heapBitmap, 0, 0, nullptr);
canvas.drawBitmap(*hardwareBitmap, 0, 500, nullptr); canvas.drawBitmap(*hardwareBitmap, 0, 500, nullptr);

View File

@@ -85,6 +85,7 @@ void BM_CanvasOpBuffer_record_simpleBitmapView(benchmark::State& benchState) {
iconBitmap, iconBitmap,
0, 0,
0, 0,
SkFilterMode::kNearest,
SkPaint{} SkPaint{}
}); });
canvas.restore(); canvas.restore();

View File

@@ -474,6 +474,7 @@ TEST(CanvasOp, simpleDrawImage) {
bitmap, bitmap,
7, 7,
19, 19,
SkFilterMode::kNearest,
SkPaint{} SkPaint{}
} }
); );
@@ -496,7 +497,7 @@ TEST(CanvasOp, simpleDrawImageRect) {
buffer.push<Op::DrawImageRect> ({ buffer.push<Op::DrawImageRect> ({
bitmap, SkRect::MakeWH(100, 100), bitmap, SkRect::MakeWH(100, 100),
SkRect::MakeLTRB(120, 110, 220, 210), SkRect::MakeLTRB(120, 110, 220, 210),
SkPaint{} SkFilterMode::kNearest, SkPaint{}
} }
); );