diff options
author | 2021-08-12 15:55:12 +0000 | |
---|---|---|
committer | 2021-08-17 16:16:09 +0000 | |
commit | 3952ed68a52099d8779453a2ab4218f600808d98 (patch) | |
tree | 32531bb91b6800a0be60e2ee48d7e2d2498e7ff4 | |
parent | 9fa8e7a7b4bc1e5b18d09bd5527839a6f3145d2d (diff) |
Added crop rect and removed inverse of the texture matrix.
BUG=152621633
Test: Verified manually and with
atest TextureViewCameraTest
atest TextureViewTest
atest TextureViewSnapshotTest
atest TextureViewStressTest
atest PixelCopyTest
atest BitmapTest
atest HardwareBitmapTests
Change-Id: Ie993a18fd3511576617a1eb859bf228c33d12f78
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 14 | ||||
-rw-r--r-- | libs/hwui/DeferredLayerUpdater.h | 4 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 25 | ||||
-rw-r--r-- | libs/hwui/Readback.cpp | 23 | ||||
-rw-r--r-- | libs/hwui/Readback.h | 3 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 86 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp | 5 |
9 files changed, 79 insertions, 85 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 2b86b1eb7542..0b3b39397ee4 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -167,12 +167,13 @@ void DeferredLayerUpdater::apply() { // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer. AHardwareBuffer_release(hardwareBuffer); if (layerImage.get()) { - SkMatrix textureTransform; - mat4(transformMatrix).copyTo(textureTransform); // force filtration if buffer size != layer size bool forceFilter = mWidth != layerImage->width() || mHeight != layerImage->height(); - updateLayer(forceFilter, textureTransform, layerImage); + SkRect currentCropRect = + SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right, + currentCrop.bottom); + updateLayer(forceFilter, layerImage, outTransform, currentCropRect); } } } @@ -184,12 +185,13 @@ void DeferredLayerUpdater::apply() { } } -void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform, - const sk_sp<SkImage>& layerImage) { +void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, + const uint32_t transform, SkRect currentCrop) { mLayer->setBlend(mBlend); mLayer->setForceFilter(forceFilter); mLayer->setSize(mWidth, mHeight); - mLayer->getTexTransform() = textureTransform; + mLayer->setCurrentCropRect(currentCrop); + mLayer->setWindowTransform(transform); mLayer->setImage(layerImage); } diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 8f79c4ec97b8..da8041f0d0fe 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -90,8 +90,8 @@ public: void detachSurfaceTexture(); - void updateLayer(bool forceFilter, const SkMatrix& textureTransform, - const sk_sp<SkImage>& layerImage); + void updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform, + SkRect currentCrop); void destroyLayer(); diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 47c47e0427a4..9053c1240957 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -35,7 +35,6 @@ Layer::Layer(RenderState& renderState, sk_sp<SkColorFilter> colorFilter, int alp // preserves the old inc/dec ref locations. This should be changed... incStrong(nullptr); renderState.registerLayer(this); - texTransform.setIdentity(); transform.setIdentity(); } @@ -101,7 +100,6 @@ void Layer::draw(SkCanvas* canvas) { const int layerHeight = getHeight(); if (layerImage) { SkMatrix textureMatrixInv; - textureMatrixInv = getTexTransform(); // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed // use bottom left origin and remove flipV and invert transformations. SkMatrix flipV; diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index e99e76299317..0789344f970e 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -74,10 +74,18 @@ public: void setColorFilter(sk_sp<SkColorFilter> filter) { mColorFilter = filter; }; - inline SkMatrix& getTexTransform() { return texTransform; } - inline SkMatrix& getTransform() { return transform; } + inline SkRect getCurrentCropRect() { return mCurrentCropRect; } + + inline void setCurrentCropRect(const SkRect currentCropRect) { + mCurrentCropRect = currentCropRect; + } + + inline void setWindowTransform(uint32_t windowTransform) { mWindowTransform = windowTransform; } + + inline uint32_t getWindowTransform() { return mWindowTransform; } + /** * Posts a decStrong call to the appropriate thread. * Thread-safe. @@ -116,14 +124,19 @@ private: SkBlendMode mode; /** - * Optional texture coordinates transform. + * Optional transform. */ - SkMatrix texTransform; + SkMatrix transform; /** - * Optional transform. + * Optional crop */ - SkMatrix transform; + SkRect mCurrentCropRect; + + /** + * Optional transform + */ + uint32_t mWindowTransform; /** * An image backing the layer. diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index a743d30939d0..4cce87ad1a2f 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -243,18 +243,14 @@ CopyResult Readback::copySurfaceIntoLegacy(ANativeWindow* window, const Rect& sr static_cast<android_dataspace>(ANativeWindow_getBuffersDataSpace(window))); sk_sp<SkImage> image = SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace); - return copyImageInto(image, texTransform, srcRect, bitmap); + return copyImageInto(image, srcRect, bitmap); } CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { LOG_ALWAYS_FATAL_IF(!hwBitmap->isHardware()); Rect srcRect; - Matrix4 transform; - transform.loadScale(1, -1, 1); - transform.translate(0, -1); - - return copyImageInto(hwBitmap->makeImage(), transform, srcRect, bitmap); + return copyImageInto(hwBitmap->makeImage(), srcRect, bitmap); } CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap* bitmap) { @@ -279,14 +275,11 @@ CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) { Rect srcRect; - Matrix4 transform; - transform.loadScale(1, -1, 1); - transform.translate(0, -1); - return copyImageInto(image, transform, srcRect, bitmap); + return copyImageInto(image, srcRect, bitmap); } -CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform, - const Rect& srcRect, SkBitmap* bitmap) { +CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect, + SkBitmap* bitmap) { ATRACE_CALL(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { mRenderThread.requireGlContext(); @@ -303,11 +296,6 @@ CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTran CopyResult copyResult = CopyResult::UnknownError; int displayedWidth = imgWidth, displayedHeight = imgHeight; - // If this is a 90 or 270 degree rotation we need to swap width/height to get the device - // size. - if (texTransform[Matrix4::kSkewX] >= 0.5f || texTransform[Matrix4::kSkewX] <= -0.5f) { - std::swap(displayedWidth, displayedHeight); - } SkRect skiaDestRect = SkRect::MakeWH(bitmap->width(), bitmap->height()); SkRect skiaSrcRect = srcRect.toSkRect(); if (skiaSrcRect.isEmpty()) { @@ -320,7 +308,6 @@ CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTran Layer layer(mRenderThread.renderState(), nullptr, 255, SkBlendMode::kSrc); layer.setSize(displayedWidth, displayedHeight); - texTransform.copyTo(layer.getTexTransform()); layer.setImage(image); // Scaling filter is not explicitly set here, because it is done inside copyLayerInfo // after checking the necessity based on the src/dest rect size and the transformation. diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h index da252695dd3b..d0d748ff5c16 100644 --- a/libs/hwui/Readback.h +++ b/libs/hwui/Readback.h @@ -56,8 +56,7 @@ public: private: CopyResult copySurfaceIntoLegacy(ANativeWindow* window, const Rect& srcRect, SkBitmap* bitmap); - CopyResult copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTransform, - const Rect& srcRect, SkBitmap* bitmap); + CopyResult copyImageInto(const sk_sp<SkImage>& image, const Rect& srcRect, SkBitmap* bitmap); bool copyLayerInto(Layer* layer, const SkRect* srcRect, const SkRect* dstRect, SkBitmap* bitmap); diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index e32788c9ec51..6db717096da7 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -21,6 +21,7 @@ #include "SkColorFilter.h" #include "SkSurface.h" #include "gl/GrGLTypes.h" +#include "system/window.h" namespace android { namespace uirenderer { @@ -29,7 +30,8 @@ namespace skiapipeline { void LayerDrawable::onDraw(SkCanvas* canvas) { Layer* layer = mLayerUpdater->backingLayer(); if (layer) { - DrawLayer(canvas->recordingContext(), canvas, layer, nullptr, nullptr, true); + SkRect srcRect = layer->getCurrentCropRect(); + DrawLayer(canvas->recordingContext(), canvas, layer, &srcRect, nullptr, true); } } @@ -79,62 +81,63 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, return false; } // transform the matrix based on the layer - SkMatrix layerTransform = layer->getTransform(); + // SkMatrix layerTransform = layer->getTransform(); + const uint32_t windowTransform = layer->getWindowTransform(); sk_sp<SkImage> layerImage = layer->getImage(); const int layerWidth = layer->getWidth(); const int layerHeight = layer->getHeight(); if (layerImage) { - SkMatrix textureMatrixInv; - textureMatrixInv = layer->getTexTransform(); - // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed - // use bottom left origin and remove flipV and invert transformations. - SkMatrix flipV; - flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1); - textureMatrixInv.preConcat(flipV); - textureMatrixInv.preScale(1.0f / layerWidth, 1.0f / layerHeight); - textureMatrixInv.postScale(layerImage->width(), layerImage->height()); - SkMatrix textureMatrix; - if (!textureMatrixInv.invert(&textureMatrix)) { - textureMatrix = textureMatrixInv; - } + const int imageWidth = layerImage->width(); + const int imageHeight = layerImage->height(); - SkMatrix matrix; if (useLayerTransform) { - matrix = SkMatrix::Concat(layerTransform, textureMatrix); - } else { - matrix = textureMatrix; + canvas->save(); + canvas->concat(layer->getTransform()); } SkPaint paint; paint.setAlpha(layer->getAlpha()); paint.setBlendMode(layer->getMode()); paint.setColorFilter(layer->getColorFilter()); - const bool nonIdentityMatrix = !matrix.isIdentity(); - if (nonIdentityMatrix) { - canvas->save(); - canvas->concat(matrix); - } const SkMatrix& totalMatrix = canvas->getTotalMatrix(); - if (dstRect || srcRect) { - SkMatrix matrixInv; - if (!matrix.invert(&matrixInv)) { - matrixInv = matrix; - } + if (srcRect || dstRect) { SkRect skiaSrcRect; - if (srcRect) { + if (srcRect && !srcRect->isEmpty()) { skiaSrcRect = *srcRect; } else { - skiaSrcRect = SkRect::MakeIWH(layerWidth, layerHeight); + skiaSrcRect = SkRect::MakeIWH(imageWidth, imageHeight); } - matrixInv.mapRect(&skiaSrcRect); SkRect skiaDestRect; - if (dstRect) { + if (dstRect && !dstRect->isEmpty()) { skiaDestRect = *dstRect; } else { - skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight); + skiaDestRect = (windowTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) + ? SkRect::MakeIWH(layerHeight, layerWidth) + : SkRect::MakeIWH(layerWidth, layerHeight); + } + + const float px = skiaDestRect.centerX(); + const float py = skiaDestRect.centerY(); + SkMatrix m; + if (windowTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { + m.postScale(-1.f, 1.f, px, py); + } + if (windowTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { + m.postScale(1.f, -1.f, px, py); + } + if (windowTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + m.postRotate(90, 0, 0); + m.postTranslate(skiaDestRect.height(), 0); + } + auto constraint = SkCanvas::kFast_SrcRectConstraint; + if (srcRect && !srcRect->isEmpty()) { + constraint = SkCanvas::kStrict_SrcRectConstraint; } - matrixInv.mapRect(&skiaDestRect); + + canvas->save(); + canvas->concat(m); + // If (matrix is a rect-to-rect transform) // and (src/dst buffers size match in screen coordinates) // and (src/dst corners align fractionally), @@ -146,18 +149,13 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) { sampling = SkSamplingOptions(SkFilterMode::kLinear); } + 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)) { - sampling = SkSamplingOptions(SkFilterMode::kLinear); - } - canvas->drawImage(layerImage.get(), 0, 0, sampling, &paint); + constraint); + canvas->restore(); } // restore the original matrix - if (nonIdentityMatrix) { + if (useLayerTransform) { canvas->restore(); } } diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index e8ba15fe92af..491af4336f97 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -74,7 +74,7 @@ sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater( layerUpdater->setTransform(&transform); // updateLayer so it's ready to draw - layerUpdater->updateLayer(true, SkMatrix::I(), nullptr); + layerUpdater->updateLayer(true, nullptr, 0, SkRect::MakeEmpty()); return layerUpdater; } diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp index 955a5e7d8b3a..0c389bfe8b71 100644 --- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp +++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp @@ -36,19 +36,16 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { EXPECT_EQ(0u, layerUpdater->backingLayer()->getHeight()); EXPECT_FALSE(layerUpdater->backingLayer()->getForceFilter()); EXPECT_FALSE(layerUpdater->backingLayer()->isBlend()); - EXPECT_EQ(Matrix4::identity(), layerUpdater->backingLayer()->getTexTransform()); // push the deferred updates to the layer - SkMatrix scaledMatrix = SkMatrix::Scale(0.5, 0.5); SkBitmap bitmap; bitmap.allocN32Pixels(16, 16); sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap); - layerUpdater->updateLayer(true, scaledMatrix, layerImage); + layerUpdater->updateLayer(true, layerImage, 0, SkRect::MakeEmpty()); // the backing layer should now have all the properties applied. EXPECT_EQ(100u, layerUpdater->backingLayer()->getWidth()); EXPECT_EQ(100u, layerUpdater->backingLayer()->getHeight()); EXPECT_TRUE(layerUpdater->backingLayer()->getForceFilter()); EXPECT_TRUE(layerUpdater->backingLayer()->isBlend()); - EXPECT_EQ(scaledMatrix, layerUpdater->backingLayer()->getTexTransform()); } |