From 7bf96a0a6f4824f2d15ec95249b8ff038fe02239 Mon Sep 17 00:00:00 2001 From: John Reck Date: Wed, 28 Jun 2017 11:08:07 -0700 Subject: [PATCH] Selectively disable filtering if estimated safe If the output matches the source rect then use GL_NEAREST instead of GL_FILTER. This is a more pixel-exact capture. Bug: 38242146 Test: CtsUiRendering & CtsViewTestCases:.PixelCopyTest passes on fugu Change-Id: I9f57a4124374568f83d45fdc8f83cc767ded888a --- libs/hwui/GlopBuilder.cpp | 6 ++++-- libs/hwui/GlopBuilder.h | 3 ++- libs/hwui/OpenGLReadback.cpp | 8 +++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 931a55a70fd89..248e92f7c97b9 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -456,11 +456,13 @@ GlopBuilder& GlopBuilder::setFillTextureLayer(GlLayer& layer, float alpha) { return *this; } -GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) { +GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform, + bool requiresFilter) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage | kRoundRectClipStage); - mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform }; + GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST; + mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform }; setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr); diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index 87b1568ed72bb..6d11da19e1383 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -75,7 +75,8 @@ public: GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha); // TODO: setFillLayer normally forces its own wrap & filter mode, // which isn't always correct. - GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform); + GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform, + bool requiresFilter); GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags); diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp index c460c0d2dfd47..51927d5a2c617 100644 --- a/libs/hwui/OpenGLReadback.cpp +++ b/libs/hwui/OpenGLReadback.cpp @@ -191,6 +191,7 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, GL_TEXTURE_2D, texture, 0); { + bool requiresFilter; // Draw & readback renderState.setViewport(destWidth, destHeight); renderState.scissor().setEnabled(false); @@ -208,12 +209,17 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(), srcRect.getHeight() / sourceTexture.height(), 1); croppedTexTransform.multiply(sFlipV); + requiresFilter = srcRect.getWidth() != (float) destWidth + || srcRect.getHeight() != (float) destHeight; + } else { + requiresFilter = sourceTexture.width() != (uint32_t) destWidth + || sourceTexture.height() != (uint32_t) destHeight; } Glop glop; GlopBuilder(renderState, caches, &glop) .setRoundRectClipState(nullptr) .setMeshTexturedUnitQuad(nullptr) - .setFillExternalTexture(sourceTexture, croppedTexTransform) + .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter) .setTransform(Matrix4::identity(), TransformFlags::None) .setModelViewMapUnitToRect(Rect(destWidth, destHeight)) .build();