summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Caches.cpp4
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp5
-rw-r--r--libs/hwui/GlLayer.cpp8
-rw-r--r--libs/hwui/GlLayer.h2
-rw-r--r--libs/hwui/Layer.cpp4
-rw-r--r--libs/hwui/Layer.h24
-rw-r--r--libs/hwui/hwui/Bitmap.cpp1
-rw-r--r--libs/hwui/pipeline/skia/LayerDrawable.cpp29
-rw-r--r--libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp3
9 files changed, 64 insertions, 16 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 0ffd116236f5..3c774a3313d2 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -234,13 +234,13 @@ void Caches::flush(FlushMode mode) {
gradientCache.clear();
fontRenderer.clear();
fboCache.clear();
- [[fallthrough]];
+ // fall through
case FlushMode::Moderate:
fontRenderer.flush();
textureCache.flush();
pathCache.clear();
tessellationCache.clear();
- [[fallthrough]];
+ // fall through
case FlushMode::Layers:
renderBufferCache.clear();
break;
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 569de76f294e..c060740dc9a4 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -133,9 +133,10 @@ void DeferredLayerUpdater::doUpdateTexImage() {
bool forceFilter = false;
sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
if (buffer != nullptr) {
+ mLayer->setBufferSize(buffer->getWidth(), buffer->getHeight());
// force filtration if buffer size != layer size
- forceFilter = mWidth != static_cast<int>(buffer->getWidth()) ||
- mHeight != static_cast<int>(buffer->getHeight());
+ forceFilter = mWidth != static_cast<int>(mLayer->getBufferWidth()) ||
+ mHeight != static_cast<int>(mLayer->getBufferHeight());
}
#if DEBUG_RENDERER
diff --git a/libs/hwui/GlLayer.cpp b/libs/hwui/GlLayer.cpp
index 42ae29d76898..8357f8ebde2e 100644
--- a/libs/hwui/GlLayer.cpp
+++ b/libs/hwui/GlLayer.cpp
@@ -72,5 +72,13 @@ void GlLayer::generateTexture() {
}
}
+SkBlendMode GlLayer::getMode() const {
+ if (texture.blend || mode != SkBlendMode::kSrcOver) {
+ return mode;
+ } else {
+ return SkBlendMode::kSrc;
+ }
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/GlLayer.h b/libs/hwui/GlLayer.h
index 28749a0d125c..4cf8f2522ff9 100644
--- a/libs/hwui/GlLayer.h
+++ b/libs/hwui/GlLayer.h
@@ -66,6 +66,8 @@ public:
*/
void onGlContextLost();
+ SkBlendMode getMode() const override;
+
private:
Caches& caches;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index fb8f0337c95e..b86ae121af55 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -27,10 +27,10 @@ Layer::Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter> colorFilter
SkBlendMode mode)
: GpuMemoryTracker(GpuObjectType::Layer)
, mRenderState(renderState)
+ , mode(mode)
, mApi(api)
, mColorFilter(colorFilter)
- , alpha(alpha)
- , mode(mode) {
+ , alpha(alpha) {
// TODO: This is a violation of Android's typical ref counting, but it
// preserves the old inc/dec ref locations. This should be changed...
incStrong(nullptr);
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 89bcddcc96d0..d41c9703e908 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -72,7 +72,7 @@ public:
inline int getAlpha() const { return alpha; }
- inline SkBlendMode getMode() const { return mode; }
+ virtual SkBlendMode getMode() const { return mode; }
inline SkColorFilter* getColorFilter() const { return mColorFilter.get(); }
@@ -94,12 +94,26 @@ public:
*/
void postDecStrong();
+ inline void setBufferSize(uint32_t width, uint32_t height) {
+ mBufferWidth = width;
+ mBufferHeight = height;
+ }
+
+ inline uint32_t getBufferWidth() const { return mBufferWidth; }
+
+ inline uint32_t getBufferHeight() const { return mBufferHeight; }
+
protected:
Layer(RenderState& renderState, Api api, sk_sp<SkColorFilter>, int alpha,
SkBlendMode mode);
RenderState& mRenderState;
+ /**
+ * Blending mode of the layer.
+ */
+ SkBlendMode mode;
+
private:
void buildColorSpaceWithFilter();
@@ -131,11 +145,6 @@ private:
int alpha;
/**
- * Blending mode of the layer.
- */
- SkBlendMode mode;
-
- /**
* Optional texture coordinates transform.
*/
mat4 texTransform;
@@ -145,6 +154,9 @@ private:
*/
mat4 transform;
+ uint32_t mBufferWidth = 0;
+
+ uint32_t mBufferHeight = 0;
}; // struct Layer
}; // namespace uirenderer
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 263d249d20e9..e7ffbee521ff 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -223,6 +223,7 @@ Bitmap::~Bitmap() {
break;
case PixelStorageType::Heap:
free(mPixelStorage.heap.address);
+ mallopt(M_PURGE, 0);
break;
case PixelStorageType::Hardware:
auto buffer = mPixelStorage.hardware.buffer;
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 6e7511da07ff..ab1d5c2546ed 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -46,6 +46,11 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer
sk_sp<SkImage> layerImage;
const int layerWidth = layer->getWidth();
const int layerHeight = layer->getHeight();
+ const int bufferWidth = layer->getBufferWidth();
+ const int bufferHeight = layer->getBufferHeight();
+ if (bufferWidth <= 0 || bufferHeight <=0) {
+ return false;
+ }
if (layer->getApi() == Layer::Api::OpenGL) {
GlLayer* glLayer = static_cast<GlLayer*>(layer);
GrGLTextureInfo externalTexture;
@@ -57,7 +62,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer
// this is anticipated to have is that for some format types if we are not bound as an OES
// texture we may get invalid results for SKP capture if we read back the texture.
externalTexture.fFormat = GL_RGBA8;
- GrBackendTexture backendTexture(layerWidth, layerHeight, GrMipMapped::kNo, externalTexture);
+ GrBackendTexture backendTexture(bufferWidth, bufferHeight, GrMipMapped::kNo, externalTexture);
layerImage = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, nullptr);
} else {
@@ -76,7 +81,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer
flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1);
textureMatrixInv.preConcat(flipV);
textureMatrixInv.preScale(1.0f / layerWidth, 1.0f / layerHeight);
- textureMatrixInv.postScale(layerWidth, layerHeight);
+ textureMatrixInv.postScale(bufferWidth, bufferHeight);
SkMatrix textureMatrix;
if (!textureMatrixInv.invert(&textureMatrix)) {
textureMatrix = textureMatrixInv;
@@ -101,6 +106,7 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer
canvas->save();
canvas->concat(matrix);
}
+ const SkMatrix& totalMatrix = canvas->getTotalMatrix();
if (dstRect) {
SkMatrix matrixInv;
if (!matrix.invert(&matrixInv)) {
@@ -110,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
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index cb503593c6c8..270527d551a9 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -331,8 +331,7 @@ sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThr
switch (info.colorType()) {
case kRGBA_8888_SkColorType:
isSupported = true;
- // ARGB_4444 is upconverted to RGBA_8888
- [[fallthrough]];
+ // ARGB_4444 is upconverted to RGBA_8888
case kARGB_4444_SkColorType:
pixelFormat = PIXEL_FORMAT_RGBA_8888;
format = GL_RGBA;