diff options
author | 2021-01-28 18:06:26 -0500 | |
---|---|---|
committer | 2021-01-29 11:46:48 -0500 | |
commit | 7994a3120b96f079a8100599f1bb5a5a6571e96e (patch) | |
tree | 7fdcb2b4cd4d677467d5b47560c72facff33c8a8 | |
parent | 7ee87037f51e651e43c207c67582b36999b3de4a (diff) |
Modernize calls to drawImage
1. drawBitmap --> drawImage
2. drawImage now always requires sampling parameter
Bug:178700363
Test: make
Change-Id: I96f610a180b3774ba955cc334949fd62b1cf4d69
-rw-r--r-- | libs/hwui/HardwareBitmapUploader.cpp | 9 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 36 | ||||
-rw-r--r-- | libs/hwui/VectorDrawable.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/canvas/CanvasOps.h | 9 | ||||
-rw-r--r-- | libs/hwui/hwui/ImageDecoder.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/jni/BitmapFactory.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/RenderNodeDrawable.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaPipeline.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/tests/microbench/CanvasOpBench.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/tests/unit/CanvasOpTests.cpp | 3 |
15 files changed, 66 insertions, 40 deletions
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp index ab9b8b55a4cb..859a5556323d 100644 --- a/libs/hwui/HardwareBitmapUploader.cpp +++ b/libs/hwui/HardwareBitmapUploader.cpp @@ -362,13 +362,8 @@ static SkBitmap makeHwCompatible(const FormatInfo& format, const SkBitmap& sourc return source; } else { SkBitmap bitmap; - const SkImageInfo& info = source.info(); - bitmap.allocPixels(info.makeColorType(kN32_SkColorType)); - - SkCanvas canvas(bitmap); - canvas.drawColor(0); - canvas.drawBitmap(source, 0.0f, 0.0f, nullptr); - + bitmap.allocPixels(source.info().makeColorType(kN32_SkColorType)); + bitmap.writePixels(source.pixmap()); return bitmap; } } diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index f4c633fbe58f..ca2ada9e8141 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -127,10 +127,11 @@ void Layer::draw(SkCanvas* canvas) { const SkMatrix& totalMatrix = canvas->getTotalMatrix(); SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height()); + SkSamplingOptions sampling; 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 if (nonIdentityMatrix) { canvas->restore(); diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 11a908696903..96118aaec29b 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -487,7 +487,9 @@ struct DrawVectorDrawable final : Op { 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; SkRect mBounds; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 1a8d9eb1f74f..8fddf713f1fa 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -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) { auto image = bitmap.makeImage(); 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); mCanvas->concat(matrix); 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); 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, const float* vertices, const int* colors, const Paint* paint) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); @@ -664,18 +673,25 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight, } #endif + auto image = bitmap.makeImage(); + // cons-up a shader for the bitmap Paint pnt; if (paint) { pnt = *paint; } - SkSamplingOptions sampling(pnt.isFilterBitmap() ? SkFilterMode::kLinear - : SkFilterMode::kNearest, - SkMipmapMode::kNone); - pnt.setShader(bitmap.makeImage()->makeShader(sampling)); + SkSamplingOptions sampling(paintToFilter(&pnt)); + pnt.setShader(image->makeShader(sampling)); + auto v = builder.detach(); 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()); } - SkFilterMode filter = paint && paint->isFilterBitmap() ? SkFilterMode::kLinear - : SkFilterMode::kNearest; - lattice.fBounds = nullptr; SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); auto image = bitmap.makeImage(); apply_looper(paint, [&](const SkPaint& p) { + auto filter = SkSamplingOptions(p.getFilterQuality()).filter; mCanvas->drawImageLattice(image.get(), lattice, dst, filter, &p); }); } diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index 6030c36add7a..4a21ad6ab945 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -507,10 +507,12 @@ void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) sk_sp<SkImage> cachedBitmap = getBitmapUpdateIfDirty().makeImage(); + // HWUI always draws VD with bilinear filtering. + auto sampling = SkSamplingOptions(SkFilterMode::kLinear); int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); canvas->drawImageRect(cachedBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), bounds, - &paint, SkCanvas::kFast_SrcRectConstraint); + sampling, &paint, SkCanvas::kFast_SrcRectConstraint); } void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) { diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h index cceba59cc639..86b1ac71f692 100644 --- a/libs/hwui/canvas/CanvasOps.h +++ b/libs/hwui/canvas/CanvasOps.h @@ -351,21 +351,24 @@ struct CanvasOp<CanvasOpType::DrawImage> { const sk_sp<Bitmap>& bitmap, float left, float top, + SkFilterMode filter, SkPaint paint ) : left(left), top(top), + filter(filter), paint(std::move(paint)), bitmap(bitmap), image(bitmap->makeImage()) { } float left; float top; + SkFilterMode filter; SkPaint paint; sk_sp<Bitmap> bitmap; sk_sp<SkImage> image; void draw(SkCanvas* canvas) const { - canvas->drawImage(image, left, top, &paint); + canvas->drawImage(image, left, top, SkSamplingOptions(filter), &paint); } ASSERT_DRAWABLE() }; @@ -377,15 +380,18 @@ struct CanvasOp<CanvasOpType::DrawImageRect> { const sk_sp<Bitmap>& bitmap, SkRect src, SkRect dst, + SkFilterMode filter, SkPaint paint ) : src(src), dst(dst), + filter(filter), paint(std::move(paint)), bitmap(bitmap), image(bitmap->makeImage()) { } SkRect src; SkRect dst; + SkFilterMode filter; SkPaint paint; sk_sp<Bitmap> bitmap; sk_sp<SkImage> image; @@ -394,6 +400,7 @@ struct CanvasOp<CanvasOpType::DrawImageRect> { canvas->drawImageRect(image, src, dst, + SkSamplingOptions(filter), &paint, SkCanvas::kFast_SrcRectConstraint ); diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp index f055c6e0fa44..ade63e5b832c 100644 --- a/libs/hwui/hwui/ImageDecoder.cpp +++ b/libs/hwui/hwui/ImageDecoder.cpp @@ -437,11 +437,11 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) { if (outputMatrix.invert(&inverse)) { SkCanvas canvas(tmp, SkCanvas::ColorBehavior::kLegacy); canvas.setMatrix(inverse); - SkPaint paint; - paint.setFilterQuality(kLow_SkFilterQuality); // bilinear SkBitmap priorFrame; 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 { ALOGE("Failed to invert matrix!"); } @@ -458,11 +458,11 @@ SkCodec::Result ImageDecoder::decode(void* pixels, size_t rowBytes) { SkPaint paint; paint.setBlendMode(SkBlendMode::kSrc); - paint.setFilterQuality(kLow_SkFilterQuality); // bilinear filtering SkCanvas canvas(scaledBm, SkCanvas::ColorBehavior::kLegacy); 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; diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp index cf02051831c6..4e9daa4b0c16 100644 --- a/libs/hwui/jni/BitmapFactory.cpp +++ b/libs/hwui/jni/BitmapFactory.cpp @@ -457,11 +457,12 @@ static jobject doDecode(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream, // outputBitmap. Otherwise we would blend by default, which is not // what we want. paint.setBlendMode(SkBlendMode::kSrc); - paint.setFilterQuality(kLow_SkFilterQuality); // bilinear filtering SkCanvas canvas(outputBitmap, SkCanvas::ColorBehavior::kLegacy); 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 { outputBitmap.swap(decodingBitmap); } diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index f95f347cffaf..34df5ddbb210 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -141,18 +141,20 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, // then use nearest neighbor, otherwise use bilerp sampling. // 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). + SkSamplingOptions sampling(SkFilterMode::kNearest); if (layer->getForceFilter() || 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); } else { SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height()); + SkSamplingOptions sampling(SkFilterMode::kNearest); 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 if (nonIdentityMatrix) { diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index 070a765cf7ca..75815bb6e63d 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -169,7 +169,6 @@ void RenderNodeDrawable::forceDraw(SkCanvas* canvas) const { static bool layerNeedsPaint(const LayerProperties& properties, float alphaMultiplier, SkPaint* paint) { - paint->setFilterQuality(kLow_SkFilterQuality); if (alphaMultiplier < 1.0f || properties.alpha() < 255 || properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr || properties.getImageFilter() != nullptr) { @@ -226,6 +225,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer); SkPaint paint; layerNeedsPaint(layerProperties, alphaMultiplier, &paint); + SkSamplingOptions sampling(SkFilterMode::kLinear); // 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. @@ -239,7 +239,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { "SurfaceID|%" PRId64, renderNode->uniqueId()).c_str(), nullptr); } canvas->drawImageRect(renderNode->getLayerSurface()->makeImageSnapshot(), bounds, - bounds, &paint); + bounds, sampling, &paint, SkCanvas::kStrict_SrcRectConstraint); if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) { renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true; diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index 80eddafbde4f..6456e36a847a 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -656,7 +656,7 @@ void SkiaPipeline::renderOverdraw(const SkRect& clip, SkPaint paint; const SkColor* colors = kOverdrawColors[static_cast<int>(Properties::overdrawColorSet)]; 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 */ diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp index bc8ce428ce2e..bae11f7d074c 100644 --- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp @@ -182,7 +182,7 @@ void VkInteropFunctorDrawable::onDraw(SkCanvas* canvas) { auto functorImage = SkImage::MakeFromAHardwareBuffer(mFrameBuffer.get(), kPremul_SkAlphaType, canvas->imageInfo().refColorSpace(), kBottomLeft_GrSurfaceOrigin); - canvas->drawImage(functorImage, 0, 0, &paint); + canvas->drawImage(functorImage, 0, 0, SkSamplingOptions(), &paint); canvas->restore(); } diff --git a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp index 1d17a021069b..716d3979bdcb 100644 --- a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp +++ b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp @@ -51,7 +51,7 @@ public: hardwareBitmap->height(), &canvasBitmap)); SkCanvas skCanvas(canvasBitmap); - skCanvas.drawBitmap(readback, 0, 0); + skCanvas.drawImage(readback.asImage(), 0, 0); canvas.drawBitmap(*heapBitmap, 0, 0, nullptr); canvas.drawBitmap(*hardwareBitmap, 0, 500, nullptr); diff --git a/libs/hwui/tests/microbench/CanvasOpBench.cpp b/libs/hwui/tests/microbench/CanvasOpBench.cpp index ef5749e6b79b..e7ba471ee807 100644 --- a/libs/hwui/tests/microbench/CanvasOpBench.cpp +++ b/libs/hwui/tests/microbench/CanvasOpBench.cpp @@ -85,6 +85,7 @@ void BM_CanvasOpBuffer_record_simpleBitmapView(benchmark::State& benchState) { iconBitmap, 0, 0, + SkFilterMode::kNearest, SkPaint{} }); canvas.restore(); diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp index c9e8d808f995..54970df534b9 100644 --- a/libs/hwui/tests/unit/CanvasOpTests.cpp +++ b/libs/hwui/tests/unit/CanvasOpTests.cpp @@ -474,6 +474,7 @@ TEST(CanvasOp, simpleDrawImage) { bitmap, 7, 19, + SkFilterMode::kNearest, SkPaint{} } ); @@ -496,7 +497,7 @@ TEST(CanvasOp, simpleDrawImageRect) { buffer.push<Op::DrawImageRect> ({ bitmap, SkRect::MakeWH(100, 100), SkRect::MakeLTRB(120, 110, 220, 210), - SkPaint{} + SkFilterMode::kNearest, SkPaint{} } ); |