Merge "Added crop rect and removed inverse of the texture matrix."
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
@@ -115,16 +123,21 @@ private:
|
||||
*/
|
||||
SkBlendMode mode;
|
||||
|
||||
/**
|
||||
* Optional texture coordinates transform.
|
||||
*/
|
||||
SkMatrix texTransform;
|
||||
|
||||
/**
|
||||
* Optional transform.
|
||||
*/
|
||||
SkMatrix transform;
|
||||
|
||||
/**
|
||||
* Optional crop
|
||||
*/
|
||||
SkRect mCurrentCropRect;
|
||||
|
||||
/**
|
||||
* Optional transform
|
||||
*/
|
||||
uint32_t mWindowTransform;
|
||||
|
||||
/**
|
||||
* An image backing the layer.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
matrixInv.mapRect(&skiaDestRect);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user