diff options
Diffstat (limited to 'libs/hwui/pipeline/skia/SkiaDisplayList.cpp')
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaDisplayList.cpp | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp index 29d5ef233338..41bcfc25f5c1 100644 --- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp +++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp @@ -22,6 +22,7 @@ #include "renderthread/CanvasContext.h" #include <SkImagePriv.h> +#include <SkPathOps.h> namespace android { namespace uirenderer { @@ -35,7 +36,7 @@ void SkiaDisplayList::syncContents(const WebViewSyncData& data) { animatedImage->syncProperties(); } for (auto& vectorDrawable : mVectorDrawables) { - vectorDrawable->syncProperties(); + vectorDrawable.first->syncProperties(); } } @@ -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) { @@ -107,15 +131,23 @@ 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()) { - isDirty = true; - static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline()) - ->getVectorDrawables() - ->push_back(vectorDrawable); + 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); + } } - vectorDrawable->setPropertyChangeWillBeConsumed(true); } return isDirty; } |