From 4e9d9b2a590105035c29f12ecf0689333e6b55e7 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Fri, 12 Jun 2015 11:07:23 -0700 Subject: [PATCH] Revert to save-layer based alpha if layer would be too large bug:21011574 Change-Id: I323f2398188ffc2bbed6a98578d25d7e5f6c337d --- libs/hwui/RenderNode.cpp | 22 +++++++++++++++++++--- libs/hwui/RenderProperties.cpp | 19 ++++++++++++++++++- libs/hwui/RenderProperties.h | 6 +++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 4ac43625db079..75e700a5e6900 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -392,11 +392,27 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { if (isLayer) { clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer } - LOG_ALWAYS_FATAL_IF(!isLayer && properties().getHasOverlappingRendering()); - renderer.scaleAlpha(properties().getAlpha()); + if (CC_LIKELY(isLayer || !properties().getHasOverlappingRendering())) { + // simply scale rendering content's alpha + renderer.scaleAlpha(properties().getAlpha()); + } else { + // savelayer needed to create an offscreen buffer + Rect layerBounds(0, 0, getWidth(), getHeight()); + if (clipFlags) { + properties().getClippingRectForFlags(clipFlags, &layerBounds); + clipFlags = 0; // all clipping done by savelayer + } + SaveLayerOp* op = new (handler.allocator()) SaveLayerOp( + layerBounds.left, layerBounds.top, + layerBounds.right, layerBounds.bottom, + (int) (properties().getAlpha() * 255), + SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag); + handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); + } if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) { - // pretend to cause savelayer to warn about performance problem affecting old versions + // pretend alpha always causes savelayer to warn about + // performance problem affecting old versions ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(), static_cast(getWidth()), static_cast(getHeight())); diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 07b8ce6d3320b..4f6ef4ef9e3d1 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -152,7 +152,24 @@ void RenderProperties::debugOutputProperties(const int level) const { clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer } - ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha); + if (CC_LIKELY(isLayer || !getHasOverlappingRendering())) { + // simply scale rendering content's alpha + ALOGD("%*sScaleAlpha %.2f", level * 2, "", mPrimitiveFields.mAlpha); + } else { + // savelayeralpha to create an offscreen buffer to apply alpha + Rect layerBounds(0, 0, getWidth(), getHeight()); + if (clipFlags) { + getClippingRectForFlags(clipFlags, &layerBounds); + clipFlags = 0; // all clipping done by savelayer + } + ALOGD("%*sSaveLayerAlpha %d, %d, %d, %d, %d, 0x%x", level * 2, "", + (int)layerBounds.left, (int)layerBounds.top, + (int)layerBounds.right, (int)layerBounds.bottom, + (int)(mPrimitiveFields.mAlpha * 255), + SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag); + } + + } if (clipFlags) { Rect clipRect; diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 98029a8c0f76d..65c1c4a174123 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -28,6 +28,7 @@ #include #include +#include "Caches.h" #include "Rect.h" #include "RevealClip.h" #include "Outline.h" @@ -577,10 +578,13 @@ public: } bool promotedToLayer() const { + const int maxTextureSize = Caches::getInstance().maxTextureSize; return mLayerProperties.mType == LayerType::None && !MathUtils::isZero(mPrimitiveFields.mAlpha) && mPrimitiveFields.mAlpha < 1 - && mPrimitiveFields.mHasOverlappingRendering; + && mPrimitiveFields.mHasOverlappingRendering + && mPrimitiveFields.mWidth <= maxTextureSize + && mPrimitiveFields.mHeight <= maxTextureSize; } LayerType effectiveLayerType() const {