Loading libs/hwui/VectorDrawable.cpp +3 −5 Original line number Diff line number Diff line Loading @@ -557,13 +557,12 @@ void Tree::Cache::clear() { mAtlasKey = INVALID_ATLAS_KEY; } void Tree::draw(SkCanvas* canvas) { void Tree::draw(SkCanvas* canvas, const SkRect& bounds) { SkRect src; sk_sp<SkSurface> vdSurface = mCache.getSurface(&src); if (vdSurface) { canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint); bounds, getPaint(), SkCanvas::kFast_SrcRectConstraint); } else { // Handle the case when VectorDrawableAtlas has been destroyed, because of memory pressure. // We render the VD into a temporary standalone buffer and mark the frame as dirty. Next Loading @@ -575,8 +574,7 @@ void Tree::draw(SkCanvas* canvas) { int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint); bounds, getPaint(), SkCanvas::kFast_SrcRectConstraint); mCache.clear(); markDirty(); } Loading libs/hwui/VectorDrawable.h +1 −1 Original line number Diff line number Diff line Loading @@ -644,7 +644,7 @@ public: * Draws VD cache into a canvas. This should always be called from RT and it works with Skia * pipelines only. */ void draw(SkCanvas* canvas); void draw(SkCanvas* canvas, const SkRect& bounds); /** * Draws VD into a GPU backed surface. Loading libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +8 −3 Original line number Diff line number Diff line Loading @@ -124,14 +124,19 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, class VectorDrawable : public SkDrawable { public: VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) {} VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) , mBounds(tree->stagingProperties()->getBounds()) {} protected: virtual SkRect onGetBounds() override { return SkRect::MakeLargest(); } virtual void onDraw(SkCanvas* canvas) override { mRoot->draw(canvas); } virtual SkRect onGetBounds() override { return mBounds; } virtual void onDraw(SkCanvas* canvas) override { mRoot->draw(canvas, mBounds); } private: sp<VectorDrawableRoot> mRoot; SkRect mBounds; }; void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { Loading libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +44 −1 Original line number Diff line number Diff line Loading @@ -1144,3 +1144,46 @@ TEST(ReorderBarrierDrawable, testShadowMatrix) { canvas.drawDrawable(&drawable); EXPECT_EQ(6, canvas.getIndex()); } // Draw a vector drawable twice but with different bounds and verify correct bounds are used. RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaRecordingCanvas, drawVectorDrawable) { static const int CANVAS_WIDTH = 100; static const int CANVAS_HEIGHT = 200; class VectorDrawableTestCanvas : public TestCanvasBase { public: VectorDrawableTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {} void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) override { const int index = mDrawCounter++; switch (index) { case 0: EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT)); break; case 1: EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH/2, CANVAS_HEIGHT)); break; default: ADD_FAILURE(); } } }; VectorDrawable::Group* group = new VectorDrawable::Group(); sp<VectorDrawableRoot> vectorDrawable(new VectorDrawableRoot(group)); vectorDrawable->mutateStagingProperties()->setScaledSize(CANVAS_WIDTH/10, CANVAS_HEIGHT/10); auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, [&](RenderProperties& props, SkiaRecordingCanvas& canvas) { vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT)); canvas.drawVectorDrawable(vectorDrawable.get()); vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH/2, CANVAS_HEIGHT)); canvas.drawVectorDrawable(vectorDrawable.get()); }); VectorDrawableTestCanvas canvas; RenderNodeDrawable drawable(node.get(), &canvas, true); canvas.drawDrawable(&drawable); EXPECT_EQ(2, canvas.mDrawCounter); } Loading
libs/hwui/VectorDrawable.cpp +3 −5 Original line number Diff line number Diff line Loading @@ -557,13 +557,12 @@ void Tree::Cache::clear() { mAtlasKey = INVALID_ATLAS_KEY; } void Tree::draw(SkCanvas* canvas) { void Tree::draw(SkCanvas* canvas, const SkRect& bounds) { SkRect src; sk_sp<SkSurface> vdSurface = mCache.getSurface(&src); if (vdSurface) { canvas->drawImageRect(vdSurface->makeImageSnapshot().get(), src, mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint); bounds, getPaint(), SkCanvas::kFast_SrcRectConstraint); } else { // Handle the case when VectorDrawableAtlas has been destroyed, because of memory pressure. // We render the VD into a temporary standalone buffer and mark the frame as dirty. Next Loading @@ -575,8 +574,7 @@ void Tree::draw(SkCanvas* canvas) { int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth()); int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight()); canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight), mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint); bounds, getPaint(), SkCanvas::kFast_SrcRectConstraint); mCache.clear(); markDirty(); } Loading
libs/hwui/VectorDrawable.h +1 −1 Original line number Diff line number Diff line Loading @@ -644,7 +644,7 @@ public: * Draws VD cache into a canvas. This should always be called from RT and it works with Skia * pipelines only. */ void draw(SkCanvas* canvas); void draw(SkCanvas* canvas, const SkRect& bounds); /** * Draws VD into a GPU backed surface. Loading
libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +8 −3 Original line number Diff line number Diff line Loading @@ -124,14 +124,19 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, class VectorDrawable : public SkDrawable { public: VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) {} VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) , mBounds(tree->stagingProperties()->getBounds()) {} protected: virtual SkRect onGetBounds() override { return SkRect::MakeLargest(); } virtual void onDraw(SkCanvas* canvas) override { mRoot->draw(canvas); } virtual SkRect onGetBounds() override { return mBounds; } virtual void onDraw(SkCanvas* canvas) override { mRoot->draw(canvas, mBounds); } private: sp<VectorDrawableRoot> mRoot; SkRect mBounds; }; void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { Loading
libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +44 −1 Original line number Diff line number Diff line Loading @@ -1144,3 +1144,46 @@ TEST(ReorderBarrierDrawable, testShadowMatrix) { canvas.drawDrawable(&drawable); EXPECT_EQ(6, canvas.getIndex()); } // Draw a vector drawable twice but with different bounds and verify correct bounds are used. RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaRecordingCanvas, drawVectorDrawable) { static const int CANVAS_WIDTH = 100; static const int CANVAS_HEIGHT = 200; class VectorDrawableTestCanvas : public TestCanvasBase { public: VectorDrawableTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {} void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) override { const int index = mDrawCounter++; switch (index) { case 0: EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT)); break; case 1: EXPECT_EQ(dst, SkRect::MakeWH(CANVAS_WIDTH/2, CANVAS_HEIGHT)); break; default: ADD_FAILURE(); } } }; VectorDrawable::Group* group = new VectorDrawable::Group(); sp<VectorDrawableRoot> vectorDrawable(new VectorDrawableRoot(group)); vectorDrawable->mutateStagingProperties()->setScaledSize(CANVAS_WIDTH/10, CANVAS_HEIGHT/10); auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, [&](RenderProperties& props, SkiaRecordingCanvas& canvas) { vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT)); canvas.drawVectorDrawable(vectorDrawable.get()); vectorDrawable->mutateStagingProperties()->setBounds(SkRect::MakeWH(CANVAS_WIDTH/2, CANVAS_HEIGHT)); canvas.drawVectorDrawable(vectorDrawable.get()); }); VectorDrawableTestCanvas canvas; RenderNodeDrawable drawable(node.get(), &canvas, true); canvas.drawDrawable(&drawable); EXPECT_EQ(2, canvas.mDrawCounter); }