diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/Caches.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/DeferredLayerUpdater.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/GlLayer.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/GlLayer.h | 2 | ||||
| -rw-r--r-- | libs/hwui/Layer.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/Layer.h | 24 | ||||
| -rw-r--r-- | libs/hwui/hwui/Bitmap.cpp | 1 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/LayerDrawable.cpp | 29 | ||||
| -rw-r--r-- | libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | 3 |
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; |