Loading core/jni/android_graphics_drawable_VectorDrawable.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -92,14 +92,14 @@ static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCachi /** /** * Draw * Draw */ */ static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, static int draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) { jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) { VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); SkRect rect; SkRect rect; GraphicsJNI::jrect_to_rect(env, jrect, &rect); GraphicsJNI::jrect_to_rect(env, jrect, &rect); SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr); SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr); tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); return tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); } } /** /** Loading Loading @@ -349,7 +349,7 @@ static const JNINativeMethod gMethods[] = { {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha}, {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha}, {"nSetAllowCaching", "!(JZ)V", (void*)setAllowCaching}, {"nSetAllowCaching", "!(JZ)V", (void*)setAllowCaching}, {"nDraw", "(JJJLandroid/graphics/Rect;ZZ)V", (void*)draw}, {"nDraw", "(JJJLandroid/graphics/Rect;ZZ)I", (void*)draw}, {"nCreateFullPath", "!()J", (void*)createEmptyFullPath}, {"nCreateFullPath", "!()J", (void*)createEmptyFullPath}, {"nCreateFullPath", "!(J)J", (void*)createFullPath}, {"nCreateFullPath", "!(J)J", (void*)createFullPath}, {"nUpdateFullPathProperties", "!(JFIFIFFFFFIII)V", (void*)updateFullPathPropertiesAndStrokeStyles}, {"nUpdateFullPathProperties", "!(JFIFIFFFFFIII)V", (void*)updateFullPathPropertiesAndStrokeStyles}, Loading graphics/java/android/graphics/drawable/VectorDrawable.java +85 −2 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Stack; import java.util.Stack; import dalvik.system.VMRuntime; /** /** * This lets you create a drawable based on an XML vector graphic. * This lets you create a drawable based on an XML vector graphic. * <p/> * <p/> Loading Loading @@ -299,9 +301,33 @@ public class VectorDrawable extends Drawable { final long colorFilterNativeInstance = colorFilter == null ? 0 : final long colorFilterNativeInstance = colorFilter == null ? 0 : colorFilter.native_instance; colorFilter.native_instance; boolean canReuseCache = mVectorState.canReuseCache(); boolean canReuseCache = mVectorState.canReuseCache(); nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(), int pixelCount = nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(), colorFilterNativeInstance, mTmpBounds, needMirroring(), colorFilterNativeInstance, mTmpBounds, needMirroring(), canReuseCache); canReuseCache); if (pixelCount == 0) { // Invalid canvas matrix or drawable bounds. This would not affect existing bitmap // cache, if any. return; } int deltaInBytes; // Track different bitmap cache based whether the canvas is hw accelerated. By doing so, // we don't over count bitmap cache allocation: if the input canvas is always of the same // type, only one bitmap cache is allocated. if (canvas.isHardwareAccelerated()) { // Each pixel takes 4 bytes. deltaInBytes = (pixelCount - mVectorState.mLastHWCachePixelCount) * 4; mVectorState.mLastHWCachePixelCount = pixelCount; } else { // Each pixel takes 4 bytes. deltaInBytes = (pixelCount - mVectorState.mLastSWCachePixelCount) * 4; mVectorState.mLastSWCachePixelCount = pixelCount; } if (deltaInBytes > 0) { VMRuntime.getRuntime().registerNativeAllocation(deltaInBytes); } else if (deltaInBytes < 0) { VMRuntime.getRuntime().registerNativeFree(-deltaInBytes); } } } Loading Loading @@ -537,11 +563,16 @@ public class VectorDrawable extends Drawable { if (mVectorState.mRootGroup != null || mVectorState.mNativeTree != null) { if (mVectorState.mRootGroup != null || mVectorState.mNativeTree != null) { // This VD has been used to display other VD resource content, clean up. // This VD has been used to display other VD resource content, clean up. if (mVectorState.mRootGroup != null) { if (mVectorState.mRootGroup != null) { // Subtract the native allocation for all the nodes. VMRuntime.getRuntime().registerNativeFree(mVectorState.mRootGroup.getNativeSize()); // Remove child nodes' reference to tree // Remove child nodes' reference to tree mVectorState.mRootGroup.setTree(null); mVectorState.mRootGroup.setTree(null); } } mVectorState.mRootGroup = new VGroup(); mVectorState.mRootGroup = new VGroup(); if (mVectorState.mNativeTree != null) { if (mVectorState.mNativeTree != null) { // Subtract the native allocation for the tree wrapper, which contains root node // as well as rendering related data. VMRuntime.getRuntime().registerNativeFree(mVectorState.NATIVE_ALLOCATION_SIZE); mVectorState.mNativeTree.release(); mVectorState.mNativeTree.release(); } } mVectorState.createNativeTree(mVectorState.mRootGroup); mVectorState.createNativeTree(mVectorState.mRootGroup); Loading @@ -558,6 +589,7 @@ public class VectorDrawable extends Drawable { state.mCacheDirty = true; state.mCacheDirty = true; inflateChildElements(r, parser, attrs, theme); inflateChildElements(r, parser, attrs, theme); state.onTreeConstructionFinished(); // Update local properties. // Update local properties. updateLocalState(r); updateLocalState(r); } } Loading Loading @@ -750,6 +782,16 @@ public class VectorDrawable extends Drawable { boolean mCachedAutoMirrored; boolean mCachedAutoMirrored; boolean mCacheDirty; boolean mCacheDirty; // Since sw canvas and hw canvas uses different bitmap caches, we track the allocation of // these bitmaps separately. int mLastSWCachePixelCount = 0; int mLastHWCachePixelCount = 0; // This tracks the total native allocation for all the nodes. private int mAllocationOfAllNodes = 0; private static final int NATIVE_ALLOCATION_SIZE = 316; // Deep copy for mutate() or implicitly mutate. // Deep copy for mutate() or implicitly mutate. public VectorDrawableState(VectorDrawableState copy) { public VectorDrawableState(VectorDrawableState copy) { if (copy != null) { if (copy != null) { Loading @@ -771,12 +813,20 @@ public class VectorDrawable extends Drawable { if (copy.mRootName != null) { if (copy.mRootName != null) { mVGTargetsMap.put(copy.mRootName, this); mVGTargetsMap.put(copy.mRootName, this); } } onTreeConstructionFinished(); } } } } private void createNativeTree(VGroup rootGroup) { private void createNativeTree(VGroup rootGroup) { mNativeTree = new VirtualRefBasePtr(nCreateTree(rootGroup.mNativePtr)); mNativeTree = new VirtualRefBasePtr(nCreateTree(rootGroup.mNativePtr)); // Register tree size VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE); } void onTreeConstructionFinished() { mRootGroup.setTree(mNativeTree); mRootGroup.setTree(mNativeTree); mAllocationOfAllNodes = mRootGroup.getNativeSize(); VMRuntime.getRuntime().registerNativeAllocation(mAllocationOfAllNodes); } } long getNativeRenderer() { long getNativeRenderer() { Loading Loading @@ -881,6 +931,14 @@ public class VectorDrawable extends Drawable { return mRootGroup.onStateChange(stateSet); return mRootGroup.onStateChange(stateSet); } } @Override public void finalize() throws Throwable { super.finalize(); int bitmapCacheSize = mLastHWCachePixelCount * 4 + mLastSWCachePixelCount * 4; VMRuntime.getRuntime().registerNativeFree(NATIVE_ALLOCATION_SIZE + mAllocationOfAllNodes + bitmapCacheSize); } /** /** * setAlpha() and getAlpha() are used mostly for animation purpose. Return true if alpha * setAlpha() and getAlpha() are used mostly for animation purpose. Return true if alpha * has changed. * has changed. Loading @@ -905,6 +963,8 @@ public class VectorDrawable extends Drawable { private static final int TRANSLATE_Y_INDEX = 6; private static final int TRANSLATE_Y_INDEX = 6; private static final int TRANSFORM_PROPERTY_COUNT = 7; private static final int TRANSFORM_PROPERTY_COUNT = 7; private static final int NATIVE_ALLOCATION_SIZE = 100; private static final HashMap<String, Integer> sPropertyMap = private static final HashMap<String, Integer> sPropertyMap = new HashMap<String, Integer>() { new HashMap<String, Integer>() { { { Loading Loading @@ -1072,6 +1132,16 @@ public class VectorDrawable extends Drawable { return mIsStateful; return mIsStateful; } } @Override int getNativeSize() { // Return the native allocation needed for the subtree. int size = NATIVE_ALLOCATION_SIZE; for (int i = 0; i < mChildren.size(); i++) { size += mChildren.get(i).getNativeSize(); } return size; } @Override @Override public boolean canApplyTheme() { public boolean canApplyTheme() { if (mThemeAttrs != null) { if (mThemeAttrs != null) { Loading Loading @@ -1240,6 +1310,7 @@ public class VectorDrawable extends Drawable { */ */ private static class VClipPath extends VPath { private static class VClipPath extends VPath { private final long mNativePtr; private final long mNativePtr; private static final int NATIVE_ALLOCATION_SIZE = 120; public VClipPath() { public VClipPath() { mNativePtr = nCreateClipPath(); mNativePtr = nCreateClipPath(); Loading Loading @@ -1283,6 +1354,11 @@ public class VectorDrawable extends Drawable { return false; return false; } } @Override int getNativeSize() { return NATIVE_ALLOCATION_SIZE; } private void updateStateFromTypedArray(TypedArray a) { private void updateStateFromTypedArray(TypedArray a) { // Account for any configuration changes. // Account for any configuration changes. mChangingConfigurations |= a.getChangingConfigurations(); mChangingConfigurations |= a.getChangingConfigurations(); Loading Loading @@ -1319,6 +1395,7 @@ public class VectorDrawable extends Drawable { private static final int FILL_TYPE_INDEX = 11; private static final int FILL_TYPE_INDEX = 11; private static final int TOTAL_PROPERTY_COUNT = 12; private static final int TOTAL_PROPERTY_COUNT = 12; private static final int NATIVE_ALLOCATION_SIZE = 264; // Property map for animatable attributes. // Property map for animatable attributes. private final static HashMap<String, Integer> sPropertyMap private final static HashMap<String, Integer> sPropertyMap = new HashMap<String, Integer> () { = new HashMap<String, Integer> () { Loading Loading @@ -1395,6 +1472,11 @@ public class VectorDrawable extends Drawable { return mStrokeColors != null || mFillColors != null; return mStrokeColors != null || mFillColors != null; } } @Override int getNativeSize() { return NATIVE_ALLOCATION_SIZE; } @Override @Override public long getNativePtr() { public long getNativePtr() { return mNativePtr; return mNativePtr; Loading Loading @@ -1688,6 +1770,7 @@ public class VectorDrawable extends Drawable { abstract void applyTheme(Theme t); abstract void applyTheme(Theme t); abstract boolean onStateChange(int[] state); abstract boolean onStateChange(int[] state); abstract boolean isStateful(); abstract boolean isStateful(); abstract int getNativeSize(); } } private static native long nCreateTree(long rootGroupPtr); private static native long nCreateTree(long rootGroupPtr); Loading @@ -1697,7 +1780,7 @@ public class VectorDrawable extends Drawable { private static native float nGetRootAlpha(long rendererPtr); private static native float nGetRootAlpha(long rendererPtr); private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); private static native void nDraw(long rendererPtr, long canvasWrapperPtr, private static native int nDraw(long rendererPtr, long canvasWrapperPtr, long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); private static native long nCreateFullPath(); private static native long nCreateFullPath(); private static native long nCreateFullPath(long nativeFullPathPtr); private static native long nCreateFullPath(long nativeFullPathPtr); Loading libs/hwui/VectorDrawable.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -456,7 +456,7 @@ bool Group::GroupProperties::isValidProperty(int propertyId) { return propertyId >= 0 && propertyId < static_cast<int>(Property::count); return propertyId >= 0 && propertyId < static_cast<int>(Property::count); } } void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, int Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, const SkRect& bounds, bool needsMirroring, bool canReuseCache) { const SkRect& bounds, bool needsMirroring, bool canReuseCache) { // The imageView can scale the canvas in different ways, in order to // The imageView can scale the canvas in different ways, in order to // avoid blurry scaling, we have to draw into a bitmap with exact pixel // avoid blurry scaling, we have to draw into a bitmap with exact pixel Loading @@ -478,7 +478,7 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, scaledHeight = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledHeight); scaledHeight = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledHeight); if (scaledWidth <= 0 || scaledHeight <= 0) { if (scaledWidth <= 0 || scaledHeight <= 0) { return; return 0; } } mStagingProperties.setScaledSize(scaledWidth, scaledHeight); mStagingProperties.setScaledSize(scaledWidth, scaledHeight); Loading @@ -500,6 +500,7 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, mStagingProperties.setBounds(tmpBounds); mStagingProperties.setBounds(tmpBounds); outCanvas->drawVectorDrawable(this); outCanvas->drawVectorDrawable(this); outCanvas->restoreToCount(saveCount); outCanvas->restoreToCount(saveCount); return scaledWidth * scaledHeight; } } void Tree::drawStaging(Canvas* outCanvas) { void Tree::drawStaging(Canvas* outCanvas) { Loading libs/hwui/VectorDrawable.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -542,7 +542,9 @@ public: Tree(Group* rootNode) : mRootNode(rootNode) { Tree(Group* rootNode) : mRootNode(rootNode) { mRootNode->setPropertyChangedListener(&mPropertyChangedListener); mRootNode->setPropertyChangedListener(&mPropertyChangedListener); } } void draw(Canvas* outCanvas, SkColorFilter* colorFilter, // 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, const SkRect& bounds, bool needsMirroring, bool canReuseCache); const SkRect& bounds, bool needsMirroring, bool canReuseCache); void drawStaging(Canvas* canvas); void drawStaging(Canvas* canvas); Loading Loading
core/jni/android_graphics_drawable_VectorDrawable.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -92,14 +92,14 @@ static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCachi /** /** * Draw * Draw */ */ static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, static int draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) { jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) { VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); SkRect rect; SkRect rect; GraphicsJNI::jrect_to_rect(env, jrect, &rect); GraphicsJNI::jrect_to_rect(env, jrect, &rect); SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr); SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr); tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); return tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); } } /** /** Loading Loading @@ -349,7 +349,7 @@ static const JNINativeMethod gMethods[] = { {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha}, {"nGetRootAlpha", "!(J)F", (void*)getRootAlpha}, {"nSetAllowCaching", "!(JZ)V", (void*)setAllowCaching}, {"nSetAllowCaching", "!(JZ)V", (void*)setAllowCaching}, {"nDraw", "(JJJLandroid/graphics/Rect;ZZ)V", (void*)draw}, {"nDraw", "(JJJLandroid/graphics/Rect;ZZ)I", (void*)draw}, {"nCreateFullPath", "!()J", (void*)createEmptyFullPath}, {"nCreateFullPath", "!()J", (void*)createEmptyFullPath}, {"nCreateFullPath", "!(J)J", (void*)createFullPath}, {"nCreateFullPath", "!(J)J", (void*)createFullPath}, {"nUpdateFullPathProperties", "!(JFIFIFFFFFIII)V", (void*)updateFullPathPropertiesAndStrokeStyles}, {"nUpdateFullPathProperties", "!(JFIFIFFFFFIII)V", (void*)updateFullPathPropertiesAndStrokeStyles}, Loading
graphics/java/android/graphics/drawable/VectorDrawable.java +85 −2 Original line number Original line Diff line number Diff line Loading @@ -52,6 +52,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Stack; import java.util.Stack; import dalvik.system.VMRuntime; /** /** * This lets you create a drawable based on an XML vector graphic. * This lets you create a drawable based on an XML vector graphic. * <p/> * <p/> Loading Loading @@ -299,9 +301,33 @@ public class VectorDrawable extends Drawable { final long colorFilterNativeInstance = colorFilter == null ? 0 : final long colorFilterNativeInstance = colorFilter == null ? 0 : colorFilter.native_instance; colorFilter.native_instance; boolean canReuseCache = mVectorState.canReuseCache(); boolean canReuseCache = mVectorState.canReuseCache(); nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(), int pixelCount = nDraw(mVectorState.getNativeRenderer(), canvas.getNativeCanvasWrapper(), colorFilterNativeInstance, mTmpBounds, needMirroring(), colorFilterNativeInstance, mTmpBounds, needMirroring(), canReuseCache); canReuseCache); if (pixelCount == 0) { // Invalid canvas matrix or drawable bounds. This would not affect existing bitmap // cache, if any. return; } int deltaInBytes; // Track different bitmap cache based whether the canvas is hw accelerated. By doing so, // we don't over count bitmap cache allocation: if the input canvas is always of the same // type, only one bitmap cache is allocated. if (canvas.isHardwareAccelerated()) { // Each pixel takes 4 bytes. deltaInBytes = (pixelCount - mVectorState.mLastHWCachePixelCount) * 4; mVectorState.mLastHWCachePixelCount = pixelCount; } else { // Each pixel takes 4 bytes. deltaInBytes = (pixelCount - mVectorState.mLastSWCachePixelCount) * 4; mVectorState.mLastSWCachePixelCount = pixelCount; } if (deltaInBytes > 0) { VMRuntime.getRuntime().registerNativeAllocation(deltaInBytes); } else if (deltaInBytes < 0) { VMRuntime.getRuntime().registerNativeFree(-deltaInBytes); } } } Loading Loading @@ -537,11 +563,16 @@ public class VectorDrawable extends Drawable { if (mVectorState.mRootGroup != null || mVectorState.mNativeTree != null) { if (mVectorState.mRootGroup != null || mVectorState.mNativeTree != null) { // This VD has been used to display other VD resource content, clean up. // This VD has been used to display other VD resource content, clean up. if (mVectorState.mRootGroup != null) { if (mVectorState.mRootGroup != null) { // Subtract the native allocation for all the nodes. VMRuntime.getRuntime().registerNativeFree(mVectorState.mRootGroup.getNativeSize()); // Remove child nodes' reference to tree // Remove child nodes' reference to tree mVectorState.mRootGroup.setTree(null); mVectorState.mRootGroup.setTree(null); } } mVectorState.mRootGroup = new VGroup(); mVectorState.mRootGroup = new VGroup(); if (mVectorState.mNativeTree != null) { if (mVectorState.mNativeTree != null) { // Subtract the native allocation for the tree wrapper, which contains root node // as well as rendering related data. VMRuntime.getRuntime().registerNativeFree(mVectorState.NATIVE_ALLOCATION_SIZE); mVectorState.mNativeTree.release(); mVectorState.mNativeTree.release(); } } mVectorState.createNativeTree(mVectorState.mRootGroup); mVectorState.createNativeTree(mVectorState.mRootGroup); Loading @@ -558,6 +589,7 @@ public class VectorDrawable extends Drawable { state.mCacheDirty = true; state.mCacheDirty = true; inflateChildElements(r, parser, attrs, theme); inflateChildElements(r, parser, attrs, theme); state.onTreeConstructionFinished(); // Update local properties. // Update local properties. updateLocalState(r); updateLocalState(r); } } Loading Loading @@ -750,6 +782,16 @@ public class VectorDrawable extends Drawable { boolean mCachedAutoMirrored; boolean mCachedAutoMirrored; boolean mCacheDirty; boolean mCacheDirty; // Since sw canvas and hw canvas uses different bitmap caches, we track the allocation of // these bitmaps separately. int mLastSWCachePixelCount = 0; int mLastHWCachePixelCount = 0; // This tracks the total native allocation for all the nodes. private int mAllocationOfAllNodes = 0; private static final int NATIVE_ALLOCATION_SIZE = 316; // Deep copy for mutate() or implicitly mutate. // Deep copy for mutate() or implicitly mutate. public VectorDrawableState(VectorDrawableState copy) { public VectorDrawableState(VectorDrawableState copy) { if (copy != null) { if (copy != null) { Loading @@ -771,12 +813,20 @@ public class VectorDrawable extends Drawable { if (copy.mRootName != null) { if (copy.mRootName != null) { mVGTargetsMap.put(copy.mRootName, this); mVGTargetsMap.put(copy.mRootName, this); } } onTreeConstructionFinished(); } } } } private void createNativeTree(VGroup rootGroup) { private void createNativeTree(VGroup rootGroup) { mNativeTree = new VirtualRefBasePtr(nCreateTree(rootGroup.mNativePtr)); mNativeTree = new VirtualRefBasePtr(nCreateTree(rootGroup.mNativePtr)); // Register tree size VMRuntime.getRuntime().registerNativeAllocation(NATIVE_ALLOCATION_SIZE); } void onTreeConstructionFinished() { mRootGroup.setTree(mNativeTree); mRootGroup.setTree(mNativeTree); mAllocationOfAllNodes = mRootGroup.getNativeSize(); VMRuntime.getRuntime().registerNativeAllocation(mAllocationOfAllNodes); } } long getNativeRenderer() { long getNativeRenderer() { Loading Loading @@ -881,6 +931,14 @@ public class VectorDrawable extends Drawable { return mRootGroup.onStateChange(stateSet); return mRootGroup.onStateChange(stateSet); } } @Override public void finalize() throws Throwable { super.finalize(); int bitmapCacheSize = mLastHWCachePixelCount * 4 + mLastSWCachePixelCount * 4; VMRuntime.getRuntime().registerNativeFree(NATIVE_ALLOCATION_SIZE + mAllocationOfAllNodes + bitmapCacheSize); } /** /** * setAlpha() and getAlpha() are used mostly for animation purpose. Return true if alpha * setAlpha() and getAlpha() are used mostly for animation purpose. Return true if alpha * has changed. * has changed. Loading @@ -905,6 +963,8 @@ public class VectorDrawable extends Drawable { private static final int TRANSLATE_Y_INDEX = 6; private static final int TRANSLATE_Y_INDEX = 6; private static final int TRANSFORM_PROPERTY_COUNT = 7; private static final int TRANSFORM_PROPERTY_COUNT = 7; private static final int NATIVE_ALLOCATION_SIZE = 100; private static final HashMap<String, Integer> sPropertyMap = private static final HashMap<String, Integer> sPropertyMap = new HashMap<String, Integer>() { new HashMap<String, Integer>() { { { Loading Loading @@ -1072,6 +1132,16 @@ public class VectorDrawable extends Drawable { return mIsStateful; return mIsStateful; } } @Override int getNativeSize() { // Return the native allocation needed for the subtree. int size = NATIVE_ALLOCATION_SIZE; for (int i = 0; i < mChildren.size(); i++) { size += mChildren.get(i).getNativeSize(); } return size; } @Override @Override public boolean canApplyTheme() { public boolean canApplyTheme() { if (mThemeAttrs != null) { if (mThemeAttrs != null) { Loading Loading @@ -1240,6 +1310,7 @@ public class VectorDrawable extends Drawable { */ */ private static class VClipPath extends VPath { private static class VClipPath extends VPath { private final long mNativePtr; private final long mNativePtr; private static final int NATIVE_ALLOCATION_SIZE = 120; public VClipPath() { public VClipPath() { mNativePtr = nCreateClipPath(); mNativePtr = nCreateClipPath(); Loading Loading @@ -1283,6 +1354,11 @@ public class VectorDrawable extends Drawable { return false; return false; } } @Override int getNativeSize() { return NATIVE_ALLOCATION_SIZE; } private void updateStateFromTypedArray(TypedArray a) { private void updateStateFromTypedArray(TypedArray a) { // Account for any configuration changes. // Account for any configuration changes. mChangingConfigurations |= a.getChangingConfigurations(); mChangingConfigurations |= a.getChangingConfigurations(); Loading Loading @@ -1319,6 +1395,7 @@ public class VectorDrawable extends Drawable { private static final int FILL_TYPE_INDEX = 11; private static final int FILL_TYPE_INDEX = 11; private static final int TOTAL_PROPERTY_COUNT = 12; private static final int TOTAL_PROPERTY_COUNT = 12; private static final int NATIVE_ALLOCATION_SIZE = 264; // Property map for animatable attributes. // Property map for animatable attributes. private final static HashMap<String, Integer> sPropertyMap private final static HashMap<String, Integer> sPropertyMap = new HashMap<String, Integer> () { = new HashMap<String, Integer> () { Loading Loading @@ -1395,6 +1472,11 @@ public class VectorDrawable extends Drawable { return mStrokeColors != null || mFillColors != null; return mStrokeColors != null || mFillColors != null; } } @Override int getNativeSize() { return NATIVE_ALLOCATION_SIZE; } @Override @Override public long getNativePtr() { public long getNativePtr() { return mNativePtr; return mNativePtr; Loading Loading @@ -1688,6 +1770,7 @@ public class VectorDrawable extends Drawable { abstract void applyTheme(Theme t); abstract void applyTheme(Theme t); abstract boolean onStateChange(int[] state); abstract boolean onStateChange(int[] state); abstract boolean isStateful(); abstract boolean isStateful(); abstract int getNativeSize(); } } private static native long nCreateTree(long rootGroupPtr); private static native long nCreateTree(long rootGroupPtr); Loading @@ -1697,7 +1780,7 @@ public class VectorDrawable extends Drawable { private static native float nGetRootAlpha(long rendererPtr); private static native float nGetRootAlpha(long rendererPtr); private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); private static native void nSetAllowCaching(long rendererPtr, boolean allowCaching); private static native void nDraw(long rendererPtr, long canvasWrapperPtr, private static native int nDraw(long rendererPtr, long canvasWrapperPtr, long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache); private static native long nCreateFullPath(); private static native long nCreateFullPath(); private static native long nCreateFullPath(long nativeFullPathPtr); private static native long nCreateFullPath(long nativeFullPathPtr); Loading
libs/hwui/VectorDrawable.cpp +3 −2 Original line number Original line Diff line number Diff line Loading @@ -456,7 +456,7 @@ bool Group::GroupProperties::isValidProperty(int propertyId) { return propertyId >= 0 && propertyId < static_cast<int>(Property::count); return propertyId >= 0 && propertyId < static_cast<int>(Property::count); } } void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, int Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, const SkRect& bounds, bool needsMirroring, bool canReuseCache) { const SkRect& bounds, bool needsMirroring, bool canReuseCache) { // The imageView can scale the canvas in different ways, in order to // The imageView can scale the canvas in different ways, in order to // avoid blurry scaling, we have to draw into a bitmap with exact pixel // avoid blurry scaling, we have to draw into a bitmap with exact pixel Loading @@ -478,7 +478,7 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, scaledHeight = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledHeight); scaledHeight = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledHeight); if (scaledWidth <= 0 || scaledHeight <= 0) { if (scaledWidth <= 0 || scaledHeight <= 0) { return; return 0; } } mStagingProperties.setScaledSize(scaledWidth, scaledHeight); mStagingProperties.setScaledSize(scaledWidth, scaledHeight); Loading @@ -500,6 +500,7 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, mStagingProperties.setBounds(tmpBounds); mStagingProperties.setBounds(tmpBounds); outCanvas->drawVectorDrawable(this); outCanvas->drawVectorDrawable(this); outCanvas->restoreToCount(saveCount); outCanvas->restoreToCount(saveCount); return scaledWidth * scaledHeight; } } void Tree::drawStaging(Canvas* outCanvas) { void Tree::drawStaging(Canvas* outCanvas) { Loading
libs/hwui/VectorDrawable.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -542,7 +542,9 @@ public: Tree(Group* rootNode) : mRootNode(rootNode) { Tree(Group* rootNode) : mRootNode(rootNode) { mRootNode->setPropertyChangedListener(&mPropertyChangedListener); mRootNode->setPropertyChangedListener(&mPropertyChangedListener); } } void draw(Canvas* outCanvas, SkColorFilter* colorFilter, // 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, const SkRect& bounds, bool needsMirroring, bool canReuseCache); const SkRect& bounds, bool needsMirroring, bool canReuseCache); void drawStaging(Canvas* canvas); void drawStaging(Canvas* canvas); Loading