Loading libs/hwui/DamageAccumulator.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -121,7 +121,14 @@ void DamageAccumulator::popTransform() { static inline void mapRect(const Matrix4* matrix, const SkRect& in, SkRect* out) { if (in.isEmpty()) return; Rect temp(in); if (CC_LIKELY(!matrix->isPerspective())) { matrix->mapRect(temp); } else { // Don't attempt to calculate damage for a perspective transform // as the numbers this works with can break the perspective // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } out->join(RECT_ARGS(temp)); } Loading @@ -134,7 +141,14 @@ static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRe const SkMatrix* transform = props.getTransformMatrix(); SkRect temp(in); if (transform && !transform->isIdentity()) { if (CC_LIKELY(!transform->hasPerspective())) { transform->mapRect(&temp); } else { // Don't attempt to calculate damage for a perspective transform // as the numbers this works with can break the perspective // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } } temp.offset(props.getLeft(), props.getTop()); out->join(temp); Loading libs/hwui/DamageAccumulator.h +5 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ #include "utils/Macros.h" // Smaller than INT_MIN/INT_MAX because we offset these values // and thus don't want to be adding offsets to INT_MAX, that's bad #define DIRTY_MIN (-0x7ffffff-1) #define DIRTY_MAX (0x7ffffff) namespace android { namespace uirenderer { Loading libs/hwui/RenderNode.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,7 @@ void RenderNode::damageSelf(TreeInfo& info) { } else { // Hope this is big enough? // TODO: Get this from the display list ops or something info.damageAccumulator->dirty(INT_MIN, INT_MIN, INT_MAX, INT_MAX); info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } } } Loading libs/hwui/unit_tests/DamageAccumulatorTests.cpp +62 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> #include <utils/LinearAllocator.h> #include <SkRect.h> Loading @@ -35,10 +36,12 @@ TEST(DamageAccumulator, identity) { identity.loadIdentity(); da.pushTransform(&identity); da.dirty(50, 50, 100, 100); { da.pushTransform(&identity); da.peekAtDirty(&curDirty); ASSERT_EQ(SkRect(), curDirty); da.popTransform(); } da.peekAtDirty(&curDirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 100, 100), curDirty); da.popTransform(); Loading Loading @@ -69,13 +72,62 @@ TEST(DamageAccumulator, union) { SkRect curDirty; identity.loadIdentity(); da.pushTransform(&identity); { da.pushTransform(&identity); da.dirty(50, 50, 100, 100); da.popTransform(); da.pushTransform(&identity); da.dirty(150, 50, 200, 125); da.popTransform(); } da.popTransform(); da.finish(&curDirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 200, 125), curDirty); } TEST(DamageAccumulator, basicRenderNode) { DamageAccumulator da; RenderNode node1; node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500); node1.animatorProperties().updateMatrix(); da.pushTransform(&node1); { RenderNode node2; node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100); node2.animatorProperties().updateMatrix(); da.pushTransform(&node2); da.dirty(0, 0, 25, 25); da.popTransform(); } da.popTransform(); SkRect dirty; da.finish(&dirty); ASSERT_EQ(SkRect::MakeLTRB(100, 100, 125, 125), dirty); } TEST(DamageAccumulator, perspectiveTransform) { DamageAccumulator da; RenderNode node1; node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500); node1.animatorProperties().setClipToBounds(true); node1.animatorProperties().updateMatrix(); da.pushTransform(&node1); { RenderNode node2; node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100); node2.animatorProperties().setClipToBounds(false); node2.animatorProperties().setRotationX(1.0f); node2.animatorProperties().setRotationY(1.0f); node2.animatorProperties().setRotation(20.0f); node2.animatorProperties().setCameraDistance(500.0f); node2.animatorProperties().setTranslationZ(30.0f); node2.animatorProperties().updateMatrix(); da.pushTransform(&node2); da.dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); da.popTransform(); } da.popTransform(); SkRect dirty; da.finish(&dirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 500, 500), dirty); } Loading
libs/hwui/DamageAccumulator.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -121,7 +121,14 @@ void DamageAccumulator::popTransform() { static inline void mapRect(const Matrix4* matrix, const SkRect& in, SkRect* out) { if (in.isEmpty()) return; Rect temp(in); if (CC_LIKELY(!matrix->isPerspective())) { matrix->mapRect(temp); } else { // Don't attempt to calculate damage for a perspective transform // as the numbers this works with can break the perspective // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } out->join(RECT_ARGS(temp)); } Loading @@ -134,7 +141,14 @@ static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRe const SkMatrix* transform = props.getTransformMatrix(); SkRect temp(in); if (transform && !transform->isIdentity()) { if (CC_LIKELY(!transform->hasPerspective())) { transform->mapRect(&temp); } else { // Don't attempt to calculate damage for a perspective transform // as the numbers this works with can break the perspective // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } } temp.offset(props.getLeft(), props.getTop()); out->join(temp); Loading
libs/hwui/DamageAccumulator.h +5 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,11 @@ #include "utils/Macros.h" // Smaller than INT_MIN/INT_MAX because we offset these values // and thus don't want to be adding offsets to INT_MAX, that's bad #define DIRTY_MIN (-0x7ffffff-1) #define DIRTY_MAX (0x7ffffff) namespace android { namespace uirenderer { Loading
libs/hwui/RenderNode.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,7 @@ void RenderNode::damageSelf(TreeInfo& info) { } else { // Hope this is big enough? // TODO: Get this from the display list ops or something info.damageAccumulator->dirty(INT_MIN, INT_MIN, INT_MAX, INT_MAX); info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); } } } Loading
libs/hwui/unit_tests/DamageAccumulatorTests.cpp +62 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> #include <utils/LinearAllocator.h> #include <SkRect.h> Loading @@ -35,10 +36,12 @@ TEST(DamageAccumulator, identity) { identity.loadIdentity(); da.pushTransform(&identity); da.dirty(50, 50, 100, 100); { da.pushTransform(&identity); da.peekAtDirty(&curDirty); ASSERT_EQ(SkRect(), curDirty); da.popTransform(); } da.peekAtDirty(&curDirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 100, 100), curDirty); da.popTransform(); Loading Loading @@ -69,13 +72,62 @@ TEST(DamageAccumulator, union) { SkRect curDirty; identity.loadIdentity(); da.pushTransform(&identity); { da.pushTransform(&identity); da.dirty(50, 50, 100, 100); da.popTransform(); da.pushTransform(&identity); da.dirty(150, 50, 200, 125); da.popTransform(); } da.popTransform(); da.finish(&curDirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 200, 125), curDirty); } TEST(DamageAccumulator, basicRenderNode) { DamageAccumulator da; RenderNode node1; node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500); node1.animatorProperties().updateMatrix(); da.pushTransform(&node1); { RenderNode node2; node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100); node2.animatorProperties().updateMatrix(); da.pushTransform(&node2); da.dirty(0, 0, 25, 25); da.popTransform(); } da.popTransform(); SkRect dirty; da.finish(&dirty); ASSERT_EQ(SkRect::MakeLTRB(100, 100, 125, 125), dirty); } TEST(DamageAccumulator, perspectiveTransform) { DamageAccumulator da; RenderNode node1; node1.animatorProperties().setLeftTopRightBottom(50, 50, 500, 500); node1.animatorProperties().setClipToBounds(true); node1.animatorProperties().updateMatrix(); da.pushTransform(&node1); { RenderNode node2; node2.animatorProperties().setLeftTopRightBottom(50, 50, 100, 100); node2.animatorProperties().setClipToBounds(false); node2.animatorProperties().setRotationX(1.0f); node2.animatorProperties().setRotationY(1.0f); node2.animatorProperties().setRotation(20.0f); node2.animatorProperties().setCameraDistance(500.0f); node2.animatorProperties().setTranslationZ(30.0f); node2.animatorProperties().updateMatrix(); da.pushTransform(&node2); da.dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); da.popTransform(); } da.popTransform(); SkRect dirty; da.finish(&dirty); ASSERT_EQ(SkRect::MakeLTRB(50, 50, 500, 500), dirty); }