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
This commit is contained in:
Nader Jawad
2021-11-09 15:35:11 -08:00
parent b13cde5c9c
commit 2d25d69236
2 changed files with 17 additions and 1 deletions

View File

@@ -34,6 +34,8 @@ namespace skiapipeline {
*/ */
class FunctorDrawable : public SkDrawable { class FunctorDrawable : public SkDrawable {
public: public:
constexpr static const char* const TYPE_NAME = "FunctorDrawable";
FunctorDrawable(int functor, SkCanvas* canvas) FunctorDrawable(int functor, SkCanvas* canvas)
: mBounds(canvas->getLocalClipBounds()) : mBounds(canvas->getLocalClipBounds())
, mWebViewHandle(WebViewFunctorManager::instance().handleFor(functor)) {} , mWebViewHandle(WebViewFunctorManager::instance().handleFor(functor)) {}
@@ -48,6 +50,8 @@ public:
mWebViewHandle->onRemovedFromTree(); mWebViewHandle->onRemovedFromTree();
} }
const char* getTypeName() const override { return TYPE_NAME; }
protected: protected:
virtual SkRect onGetBounds() override { return mBounds; } virtual SkRect onGetBounds() override { return mBounds; }

View File

@@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#include "TransformCanvas.h" #include "TransformCanvas.h"
#include "FunctorDrawable.h"
#include "HolePunch.h" #include "HolePunch.h"
#include "SkData.h" #include "SkData.h"
#include "SkDrawable.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) { 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 { bool TransformCanvas::onFilter(SkPaint& paint) const {