Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff2c36b7 authored by Stan Iliev's avatar Stan Iliev
Browse files

Fix VkFunctorDrawable crash

Fix WebView crash, which is specific for Vulkan pipeline
introduced by ag/8550137c.
VkFunctorDrawable expects SkDrawable::onSnapGpuDrawHandler
callback instead of SkDrawable::onDraw.
This CL invokes SkCanvas::drawDrawable/SkGpuDevice::drawDrawable,
which has the logic to invoke onSnapGpuDrawHandler.

Test: Don't crash WebView with Vulkan pipeline, pass CTS
Change-Id: Ia98f159511f4ad2dbdbe0d53f0aec2f8c6db263b
parent 0e2113b5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,3 +49,4 @@ X(DrawVertices)
X(DrawAtlas) 
X(DrawShadowRec)
X(DrawVectorDrawable)
X(DrawWebView)
+18 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#include "RecordingCanvas.h"

#include "pipeline/skia/FunctorDrawable.h"
#include "VectorDrawable.h"

#include "SkAndroidFrameworkUtils.h"
@@ -496,6 +497,16 @@ struct DrawVectorDrawable final : Op {
    SkPaint paint;
    BitmapPalette palette;
};
struct DrawWebView final : Op {
    static const auto kType = Type::DrawWebView;
    DrawWebView(skiapipeline::FunctorDrawable* drawable) : drawable(sk_ref_sp(drawable)) {}
    sk_sp<skiapipeline::FunctorDrawable> drawable;
    // We can't invoke SkDrawable::draw directly, because VkFunctorDrawable expects
    // SkDrawable::onSnapGpuDrawHandler callback instead of SkDrawable::onDraw.
    // SkCanvas::drawDrawable/SkGpuDevice::drawDrawable has the logic to invoke
    // onSnapGpuDrawHandler.
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get()); }
};
}

template <typename T, typename... Args>
@@ -680,6 +691,9 @@ void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& r
void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
    this->push<DrawVectorDrawable>(0, tree);
}
void DisplayListData::drawWebView(skiapipeline::FunctorDrawable* drawable) {
    this->push<DrawWebView>(0, drawable);
}

typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
typedef void (*void_fn)(const void*);
@@ -986,5 +1000,9 @@ void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
    fDL->drawVectorDrawable(tree);
}

void RecordingCanvas::drawWebView(skiapipeline::FunctorDrawable* drawable) {
    fDL->drawWebView(drawable);
}

}  // namespace uirenderer
}  // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@
namespace android {
namespace uirenderer {

namespace skiapipeline {
class FunctorDrawable;
}

enum class DisplayListOpType : uint8_t {
#define X(T) T,
#include "DisplayListOps.in"
@@ -119,6 +123,7 @@ private:
                   SkBlendMode, const SkRect*, const SkPaint*);
    void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
    void drawVectorDrawable(VectorDrawableRoot* tree);
    void drawWebView(skiapipeline::FunctorDrawable*);

    template <typename T, typename... Args>
    void* push(size_t, Args&&...);
@@ -203,6 +208,7 @@ public:
    void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;

    void drawVectorDrawable(VectorDrawableRoot* tree);
    void drawWebView(skiapipeline::FunctorDrawable*);

    /**
     * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
+1 −1
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
        functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
    }
    mDisplayList->mChildFunctors.push_back(functorDrawable);
    drawDrawable(functorDrawable);
    mRecorder.drawWebView(functorDrawable);
#endif
}