diff options
author | 2018-11-26 16:41:34 -0800 | |
---|---|---|
committer | 2018-11-26 16:41:34 -0800 | |
commit | 0aff62d12f5b214e09628dc5d933ffdac7950f11 (patch) | |
tree | bb9519e5e9ee122c010bdf87c9b6648568263984 | |
parent | 9a72ec33d78a43c8771bfa03061c0fc9d6e4225d (diff) |
Fix failing TextureViewTest
A tiny scaleX/scaleY is sneaking into the matrix,
throwing off the nearest/bilerp calculation.
This tiny scaleX/scaleY appears to be coming from
the inverse texture matrix necessary to workaround
skia issue https://bugs.chromium.org/p/skia/issues/detail?id=7075
So add another workaround for SkMatrix::getType()
reporting this as having a scale, even though there really
isn't one.
Bug: 119783323
Test: atest android.view.cts.TextureViewTest#testSamplingWithTransform
Change-Id: I3e675102ef99ce093f698460242c19dfe7e90345
-rw-r--r-- | libs/hwui/Matrix.h | 1 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/utils/MathUtils.h | 4 |
3 files changed, 26 insertions, 5 deletions
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index f0a3a959617d..1b5cb60ca4bd 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -27,6 +27,7 @@ namespace android { namespace uirenderer { #define SK_MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]" +#define SK_MATRIX_STRING_V "[%.9f %.9f %.9f] [%.9f %.9f %.9f] [%.9f %.9f %.9f]" #define SK_MATRIX_ARGS(m) \ (m)->get(0), (m)->get(1), (m)->get(2), (m)->get(3), (m)->get(4), (m)->get(5), (m)->get(6), \ (m)->get(7), (m)->get(8) diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index 13d2dae8e281..0cd64069bc5c 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <utils/MathUtils.h> #include "LayerDrawable.h" #include "GrBackendSurface.h" @@ -32,6 +33,24 @@ void LayerDrawable::onDraw(SkCanvas* canvas) { } } +// This is a less-strict matrix.isTranslate() that will still report being translate-only +// on imperceptibly small scaleX & scaleY values. +static bool isBasicallyTranslate(const SkMatrix& matrix) { + if (!matrix.isScaleTranslate()) return false; + return MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY()); +} + +static bool shouldFilter(const SkMatrix& matrix) { + if (!matrix.isScaleTranslate()) return true; + + // We only care about meaningful scale here + bool noScale = MathUtils::isOne(matrix.getScaleX()) + && MathUtils::isOne(matrix.getScaleY()); + bool pixelAligned = SkScalarIsInt(matrix.getTranslateX()) + && SkScalarIsInt(matrix.getTranslateY()); + return !(noScale && pixelAligned); +} + bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer, const SkRect* srcRect, const SkRect* dstRect, bool useLayerTransform) { @@ -101,7 +120,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer // 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() + bool isIntegerTranslate = isBasicallyTranslate(totalMatrix) && SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX]) == SkScalarFraction(skiaSrcRect.fLeft) && SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY]) @@ -112,10 +131,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint, SkCanvas::kFast_SrcRectConstraint); } else { - bool isIntegerTranslate = totalMatrix.isTranslate() - && SkScalarIsInt(totalMatrix[SkMatrix::kMTransX]) - && SkScalarIsInt(totalMatrix[SkMatrix::kMTransY]); - if (layer->getForceFilter() || !isIntegerTranslate) { + if (layer->getForceFilter() || shouldFilter(totalMatrix)) { paint.setFilterQuality(kLow_SkFilterQuality); } canvas->drawImage(layerImage.get(), 0, 0, &paint); diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h index 5475898bff28..cc8d83f10d43 100644 --- a/libs/hwui/utils/MathUtils.h +++ b/libs/hwui/utils/MathUtils.h @@ -34,6 +34,10 @@ public: return (value >= -NON_ZERO_EPSILON) && (value <= NON_ZERO_EPSILON); } + inline static bool isOne(float value) { + return areEqual(value, 1.0f); + } + inline static bool isPositive(float value) { return value >= NON_ZERO_EPSILON; } /** |