From 335d7d174464ea3fc2d058dcff6e436df1cf0fd9 Mon Sep 17 00:00:00 2001 From: Doris Liu Date: Thu, 26 May 2016 15:19:15 -0700 Subject: [PATCH] Copy native tree's property when mutate vector drawable When mutating vector drawables, we need to not only copy over the VD tree structure, but also the properties of the VD tree, such as alpha. Bug: 28974071 Change-Id: If793f5f2b6e116472a1c6da0fb60d8278a78b03f --- .../android_graphics_drawable_VectorDrawable.cpp | 8 ++++++++ .../android/graphics/drawable/VectorDrawable.java | 13 ++++++++++++- libs/hwui/VectorDrawable.cpp | 2 +- libs/hwui/VectorDrawable.h | 8 +++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp index 9e69f79e4ffc0..045f127e830e0 100644 --- a/core/jni/android_graphics_drawable_VectorDrawable.cpp +++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp @@ -36,6 +36,13 @@ static jlong createTree(JNIEnv*, jobject, jlong groupPtr) { return reinterpret_cast(tree); } +static jlong createTreeFromCopy(JNIEnv*, jobject, jlong treePtr, jlong groupPtr) { + VectorDrawable::Group* rootGroup = reinterpret_cast(groupPtr); + VectorDrawable::Tree* treeToCopy = reinterpret_cast(treePtr); + VectorDrawable::Tree* tree = new VectorDrawable::Tree(treeToCopy, rootGroup); + return reinterpret_cast(tree); +} + static jlong createEmptyFullPath(JNIEnv*, jobject) { VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(); return reinterpret_cast(newPath); @@ -344,6 +351,7 @@ static void setTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPa static const JNINativeMethod gMethods[] = { {"nCreateTree", "!(J)J", (void*)createTree}, + {"nCreateTreeFromCopy", "!(JJ)J", (void*)createTreeFromCopy}, {"nSetRendererViewportSize", "!(JFF)V", (void*)setTreeViewportSize}, {"nSetRootAlpha", "!(JF)Z", (void*)setRootAlpha}, {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha}, diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 47bafe323a974..a8c87370e18bb 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -834,7 +834,7 @@ public class VectorDrawable extends Drawable { mTintMode = copy.mTintMode; mAutoMirrored = copy.mAutoMirrored; mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap); - createNativeTree(mRootGroup); + createNativeTreeFromCopy(copy, mRootGroup); mBaseWidth = copy.mBaseWidth; mBaseHeight = copy.mBaseHeight; @@ -856,6 +856,16 @@ public class VectorDrawable extends Drawable { VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE); } + // Create a new native tree with the given root group, and copy the properties from the + // given VectorDrawableState's native tree. + private void createNativeTreeFromCopy(VectorDrawableState copy, VGroup rootGroup) { + mNativeTree = new VirtualRefBasePtr(nCreateTreeFromCopy( + copy.mNativeTree.get(), rootGroup.mNativePtr)); + // Register tree size + VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE); + } + + void onTreeConstructionFinished() { mRootGroup.setTree(mNativeTree); mAllocationOfAllNodes = mRootGroup.getNativeSize(); @@ -2074,6 +2084,7 @@ public class VectorDrawable extends Drawable { } private static native long nCreateTree(long rootGroupPtr); + private static native long nCreateTreeFromCopy(long treeToCopy, long rootGroupPtr); private static native void nSetRendererViewportSize(long rendererPtr, float viewportWidth, float viewportHeight); private static native boolean nSetRootAlpha(long rendererPtr, float alpha); diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index f0348e4977ae8..2b79941396410 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -530,7 +530,7 @@ SkPaint* Tree::updatePaint(SkPaint* outPaint, TreeProperties* prop) { if (prop->getRootAlpha() == 1.0f && prop->getColorFilter() == nullptr) { return nullptr; } else { - outPaint->setColorFilter(mStagingProperties.getColorFilter()); + outPaint->setColorFilter(prop->getColorFilter()); outPaint->setFilterQuality(kLow_SkFilterQuality); outPaint->setAlpha(prop->getRootAlpha() * 255); return outPaint; diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h index 1a1f49f04cb92..940b1ca84dc1c 100644 --- a/libs/hwui/VectorDrawable.h +++ b/libs/hwui/VectorDrawable.h @@ -549,6 +549,12 @@ public: Tree(Group* rootNode) : mRootNode(rootNode) { mRootNode->setPropertyChangedListener(&mPropertyChangedListener); } + + // Copy properties from the tree and use the give node as the root node + Tree(const Tree* copy, Group* rootNode) : Tree(rootNode) { + mStagingProperties.syncAnimatableProperties(*copy->stagingProperties()); + mStagingProperties.syncNonAnimatableProperties(*copy->stagingProperties()); + } // Draws the VD onto a bitmap cache, then the bitmap cache will be rendered onto the input // canvas. Returns the number of pixels needed for the bitmap cache. int draw(Canvas* outCanvas, SkColorFilter* colorFilter, @@ -673,7 +679,7 @@ public: }; void onPropertyChanged(TreeProperties* prop); TreeProperties* mutateStagingProperties() { return &mStagingProperties; } - const TreeProperties* stagingProperties() { return &mStagingProperties; } + const TreeProperties* stagingProperties() const { return &mStagingProperties; } // This should only be called from animations on RT TreeProperties* mutateProperties() { return &mProperties; }