Loading libs/hwui/TreeInfo.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ TreeInfo::TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContex , prepareTextures(mode == MODE_FULL) , canvasContext(canvasContext) , damageGenerationId(canvasContext.getFrameNumber()) , disableForceDark(canvasContext.useForceDark() ? 0 : 1) {} , disableForceDark(canvasContext.useForceDark() ? 0 : 1) , screenSize(canvasContext.getNextFrameSize()) {} } // namespace android::uirenderer libs/hwui/TreeInfo.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "utils/Macros.h" #include <utils/Timers.h> #include "SkSize.h" #include <string> Loading Loading @@ -96,6 +97,8 @@ public: int disableForceDark; const SkISize screenSize; struct Out { bool hasFunctors = false; // This is only updated if evaluateAnimations is true Loading libs/hwui/VectorDrawable.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,11 @@ void Tree::Cache::clear() { } void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) { if (canvas->quickReject(bounds)) { // The RenderNode is on screen, but the AVD is not. return; } // Update the paint for any animatable properties SkPaint paint = inPaint; paint.setAlpha(mProperties.getRootAlpha() * 255); Loading libs/hwui/pipeline/skia/SkiaDisplayList.cpp +39 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "renderthread/CanvasContext.h" #include <SkImagePriv.h> #include <SkPathOps.h> namespace android { namespace uirenderer { Loading @@ -35,7 +36,7 @@ void SkiaDisplayList::syncContents(const WebViewSyncData& data) { animatedImage->syncProperties(); } for (auto& vectorDrawable : mVectorDrawables) { vectorDrawable->syncProperties(); vectorDrawable.first->syncProperties(); } } Loading @@ -51,6 +52,29 @@ void SkiaDisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) } } static bool intersects(const SkISize screenSize, const Matrix4& mat, const SkRect& bounds) { Vector3 points[] = { Vector3 {bounds.fLeft, bounds.fTop, 0}, Vector3 {bounds.fRight, bounds.fTop, 0}, Vector3 {bounds.fRight, bounds.fBottom, 0}, Vector3 {bounds.fLeft, bounds.fBottom, 0}}; float minX, minY, maxX, maxY; bool first = true; for (auto& point : points) { mat.mapPoint3d(point); if (first) { minX = maxX = point.x; minY = maxY = point.y; first = false; } else { minX = std::min(minX, point.x); minY = std::min(minY, point.y); maxX = std::max(maxX, point.x); maxY = std::max(maxY, point.y); } } return SkRect::Make(screenSize).intersects(SkRect::MakeLTRB(minX, minY, maxX, maxY)); } bool SkiaDisplayList::prepareListAndChildren( TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) { Loading Loading @@ -107,16 +131,24 @@ bool SkiaDisplayList::prepareListAndChildren( } } for (auto& vectorDrawable : mVectorDrawables) { for (auto& vectorDrawablePair : mVectorDrawables) { // If any vector drawable in the display list needs update, damage the node. auto& vectorDrawable = vectorDrawablePair.first; if (vectorDrawable->isDirty()) { Matrix4 totalMatrix; info.damageAccumulator->computeCurrentTransform(&totalMatrix); Matrix4 canvasMatrix(vectorDrawablePair.second); totalMatrix.multiply(canvasMatrix); const SkRect& bounds = vectorDrawable->properties().getBounds(); if (intersects(info.screenSize, totalMatrix, bounds)) { isDirty = true; static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) ->getVectorDrawables() ->push_back(vectorDrawable); } vectorDrawable->setPropertyChangeWillBeConsumed(true); } } } return isDirty; } Loading libs/hwui/pipeline/skia/SkiaDisplayList.h +12 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "TreeInfo.h" #include "hwui/AnimatedImageDrawable.h" #include "utils/LinearAllocator.h" #include "utils/Pair.h" #include <deque> Loading @@ -41,12 +42,6 @@ typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; namespace skiapipeline { /** * This class is intended to be self contained, but still subclasses from * DisplayList to make it easier to support switching between the two at * runtime. The downside of this inheritance is that we pay for the overhead * of the parent class construction/destruction without any real benefit. */ class SkiaDisplayList { public: size_t getUsedSize() { return allocator.usedSize() + mDisplayList.usedSize(); } Loading Loading @@ -156,7 +151,17 @@ public: std::deque<RenderNodeDrawable> mChildNodes; std::deque<FunctorDrawable*> mChildFunctors; std::vector<SkImage*> mMutableImages; std::vector<VectorDrawableRoot*> mVectorDrawables; private: std::vector<Pair<VectorDrawableRoot*, SkMatrix>> mVectorDrawables; public: void appendVD(VectorDrawableRoot* r) { appendVD(r, SkMatrix::I()); } void appendVD(VectorDrawableRoot* r, const SkMatrix& mat) { mVectorDrawables.push_back(Pair<VectorDrawableRoot*, SkMatrix>(r, mat)); } std::vector<AnimatedImageDrawable*> mAnimatedImages; DisplayListData mDisplayList; Loading Loading
libs/hwui/TreeInfo.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ TreeInfo::TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContex , prepareTextures(mode == MODE_FULL) , canvasContext(canvasContext) , damageGenerationId(canvasContext.getFrameNumber()) , disableForceDark(canvasContext.useForceDark() ? 0 : 1) {} , disableForceDark(canvasContext.useForceDark() ? 0 : 1) , screenSize(canvasContext.getNextFrameSize()) {} } // namespace android::uirenderer
libs/hwui/TreeInfo.h +3 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "utils/Macros.h" #include <utils/Timers.h> #include "SkSize.h" #include <string> Loading Loading @@ -96,6 +97,8 @@ public: int disableForceDark; const SkISize screenSize; struct Out { bool hasFunctors = false; // This is only updated if evaluateAnimations is true Loading
libs/hwui/VectorDrawable.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,11 @@ void Tree::Cache::clear() { } void Tree::draw(SkCanvas* canvas, const SkRect& bounds, const SkPaint& inPaint) { if (canvas->quickReject(bounds)) { // The RenderNode is on screen, but the AVD is not. return; } // Update the paint for any animatable properties SkPaint paint = inPaint; paint.setAlpha(mProperties.getRootAlpha() * 255); Loading
libs/hwui/pipeline/skia/SkiaDisplayList.cpp +39 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "renderthread/CanvasContext.h" #include <SkImagePriv.h> #include <SkPathOps.h> namespace android { namespace uirenderer { Loading @@ -35,7 +36,7 @@ void SkiaDisplayList::syncContents(const WebViewSyncData& data) { animatedImage->syncProperties(); } for (auto& vectorDrawable : mVectorDrawables) { vectorDrawable->syncProperties(); vectorDrawable.first->syncProperties(); } } Loading @@ -51,6 +52,29 @@ void SkiaDisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) } } static bool intersects(const SkISize screenSize, const Matrix4& mat, const SkRect& bounds) { Vector3 points[] = { Vector3 {bounds.fLeft, bounds.fTop, 0}, Vector3 {bounds.fRight, bounds.fTop, 0}, Vector3 {bounds.fRight, bounds.fBottom, 0}, Vector3 {bounds.fLeft, bounds.fBottom, 0}}; float minX, minY, maxX, maxY; bool first = true; for (auto& point : points) { mat.mapPoint3d(point); if (first) { minX = maxX = point.x; minY = maxY = point.y; first = false; } else { minX = std::min(minX, point.x); minY = std::min(minY, point.y); maxX = std::max(maxX, point.x); maxY = std::max(maxY, point.y); } } return SkRect::Make(screenSize).intersects(SkRect::MakeLTRB(minX, minY, maxX, maxY)); } bool SkiaDisplayList::prepareListAndChildren( TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer, std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) { Loading Loading @@ -107,16 +131,24 @@ bool SkiaDisplayList::prepareListAndChildren( } } for (auto& vectorDrawable : mVectorDrawables) { for (auto& vectorDrawablePair : mVectorDrawables) { // If any vector drawable in the display list needs update, damage the node. auto& vectorDrawable = vectorDrawablePair.first; if (vectorDrawable->isDirty()) { Matrix4 totalMatrix; info.damageAccumulator->computeCurrentTransform(&totalMatrix); Matrix4 canvasMatrix(vectorDrawablePair.second); totalMatrix.multiply(canvasMatrix); const SkRect& bounds = vectorDrawable->properties().getBounds(); if (intersects(info.screenSize, totalMatrix, bounds)) { isDirty = true; static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) ->getVectorDrawables() ->push_back(vectorDrawable); } vectorDrawable->setPropertyChangeWillBeConsumed(true); } } } return isDirty; } Loading
libs/hwui/pipeline/skia/SkiaDisplayList.h +12 −7 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "TreeInfo.h" #include "hwui/AnimatedImageDrawable.h" #include "utils/LinearAllocator.h" #include "utils/Pair.h" #include <deque> Loading @@ -41,12 +42,6 @@ typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot; namespace skiapipeline { /** * This class is intended to be self contained, but still subclasses from * DisplayList to make it easier to support switching between the two at * runtime. The downside of this inheritance is that we pay for the overhead * of the parent class construction/destruction without any real benefit. */ class SkiaDisplayList { public: size_t getUsedSize() { return allocator.usedSize() + mDisplayList.usedSize(); } Loading Loading @@ -156,7 +151,17 @@ public: std::deque<RenderNodeDrawable> mChildNodes; std::deque<FunctorDrawable*> mChildFunctors; std::vector<SkImage*> mMutableImages; std::vector<VectorDrawableRoot*> mVectorDrawables; private: std::vector<Pair<VectorDrawableRoot*, SkMatrix>> mVectorDrawables; public: void appendVD(VectorDrawableRoot* r) { appendVD(r, SkMatrix::I()); } void appendVD(VectorDrawableRoot* r, const SkMatrix& mat) { mVectorDrawables.push_back(Pair<VectorDrawableRoot*, SkMatrix>(r, mat)); } std::vector<AnimatedImageDrawable*> mAnimatedImages; DisplayListData mDisplayList; Loading