From 402fff12596fdf6cc270f5ce74029563a863127d Mon Sep 17 00:00:00 2001 From: Stan Iliev Date: Thu, 25 Oct 2018 16:28:27 -0400 Subject: [PATCH] Use bilerp sampling when drawing TextureView with non-translate matrix Draw TextureView with bilerp sampling, when the matrix is not integer translate or identity. For example scaling matrix or translation on X by 0.4f will draw with GL_LINEAR on OpenGL pipeline. Translation on X by 3.0f will draw TextureView with GL_NEAREST. Bug: 117890671 Test: Passed CtsViewTestCases and CtsUiRenderingTestCases Change-Id: I72033410c8b0ab637c2e6b816ac9b04434286fbb Merged-In: I3acd710ff2cb4ee7b14dd4b7d9227842187130c9 --- libs/hwui/pipeline/skia/LayerDrawable.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index 093c7cf62cd2a..ab1d5c2546ed0 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -100,15 +100,13 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer paint.setAlpha(layer->getAlpha()); paint.setBlendMode(layer->getMode()); paint.setColorFilter(layer->getColorSpaceWithFilter()); - if (layer->getForceFilter()) { - paint.setFilterQuality(kLow_SkFilterQuality); - } const bool nonIdentityMatrix = !matrix.isIdentity(); if (nonIdentityMatrix) { canvas->save(); canvas->concat(matrix); } + const SkMatrix& totalMatrix = canvas->getTotalMatrix(); if (dstRect) { SkMatrix matrixInv; if (!matrix.invert(&matrixInv)) { @@ -118,9 +116,28 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer matrixInv.mapRect(&srcRect); SkRect skiaDestRect = *dstRect; matrixInv.mapRect(&skiaDestRect); + // If (matrix is identity or an integer translation) and (src/dst buffers size match), + // then use nearest neighbor, otherwise use bilerp sampling. + // Integer translation is defined as when src rect and dst rect align fractionally. + // 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). + bool isIntegerTranslate = totalMatrix.isTranslate() + && SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX]) + == SkScalarFraction(srcRect.fLeft) + && SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY]) + == SkScalarFraction(srcRect.fTop); + if (layer->getForceFilter() || !isIntegerTranslate) { + paint.setFilterQuality(kLow_SkFilterQuality); + } canvas->drawImageRect(layerImage.get(), srcRect, skiaDestRect, &paint, SkCanvas::kFast_SrcRectConstraint); } else { + bool isIntegerTranslate = totalMatrix.isTranslate() + && SkScalarIsInt(totalMatrix[SkMatrix::kMTransX]) + && SkScalarIsInt(totalMatrix[SkMatrix::kMTransY]); + if (layer->getForceFilter() || !isIntegerTranslate) { + paint.setFilterQuality(kLow_SkFilterQuality); + } canvas->drawImage(layerImage.get(), 0, 0, &paint); } // restore the original matrix