diff options
author | Nader Jawad <njawad@google.com> | 2021-11-09 15:35:11 -0800 |
---|---|---|
committer | Nader Jawad <njawad@google.com> | 2021-11-10 20:16:54 +0000 |
commit | 2d25d692367d0135bbdf7a4a54caec389ac4b0e5 (patch) | |
tree | 9d23fde128321483f6618a860a392b75d3549d96 | |
parent | b13cde5c9ca7dacea63a1da84e1a14a49e1bba83 (diff) |
Skip TransformCanvas calls for FunctorDrawables
Fix issue where attempts to render overscroll content
into the alpha 8 mask would crash if there are WebView
related Functors in the scene.
Provide implementations for getTypeName in SkDrawable instances
of FunctorDrawable.
Fixes: 203960959
Test: manual
Change-Id: Idf321d9bfcbe2b8ba1eb205eadcec95e55865305
-rw-r--r-- | libs/hwui/pipeline/skia/FunctorDrawable.h | 4 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/TransformCanvas.cpp | 14 |
2 files changed, 17 insertions, 1 deletions
diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h index 9bbd0a92600b..29ef2b82919d 100644 --- a/libs/hwui/pipeline/skia/FunctorDrawable.h +++ b/libs/hwui/pipeline/skia/FunctorDrawable.h @@ -34,6 +34,8 @@ namespace skiapipeline { */ class FunctorDrawable : public SkDrawable { public: + constexpr static const char* const TYPE_NAME = "FunctorDrawable"; + FunctorDrawable(int functor, SkCanvas* canvas) : mBounds(canvas->getLocalClipBounds()) , mWebViewHandle(WebViewFunctorManager::instance().handleFor(functor)) {} @@ -48,6 +50,8 @@ public: mWebViewHandle->onRemovedFromTree(); } + const char* getTypeName() const override { return TYPE_NAME; } + protected: virtual SkRect onGetBounds() override { return mBounds; } diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp index 6777c00c4655..41e36874b862 100644 --- a/libs/hwui/pipeline/skia/TransformCanvas.cpp +++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ #include "TransformCanvas.h" + +#include "FunctorDrawable.h" #include "HolePunch.h" #include "SkData.h" #include "SkDrawable.h" @@ -35,7 +37,17 @@ void TransformCanvas::onDrawAnnotation(const SkRect& rect, const char* key, SkDa } void TransformCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { - drawable->draw(this, matrix); + // TransformCanvas filters all drawing commands while maintaining the current + // clip stack and transformation. We need to draw most SkDrawables, since their + // draw calls may call methods that affect the clip stack and transformation. (Any + // actual draw commands will then be filtered out.) But FunctorDrawables are used + // as leaf nodes which issue self-contained OpenGL/Vulkan commands. These won't + // affect the clip stack + transformation, and in some cases cause problems (e.g. if + // the surface only has an alpha channel). See b/203960959 + const auto* drawableName = drawable->getTypeName(); + if (drawableName == nullptr || strcmp(drawableName, FunctorDrawable::TYPE_NAME) != 0) { + drawable->draw(this, matrix); + } } bool TransformCanvas::onFilter(SkPaint& paint) const { |