Use NativeAllocationRegistry instead.
Verified this doesn't cause performance regressions:
StaticLayout creation time:
MeasuredText Balanced Hyphenation : 721,055 -> 723,812: (+0.4%)
MeasuredText Balanced NoHyphenation: 527,880 -> 505,843: (-4.2%)
MeasuredText Greedy Hyphenation : 476,982 -> 460,241: (-3.5%)
MeasuredText Greedy NoHyphenation : 471,074 -> 459,013: (-2.6%)
RandomText Balanced Hyphenation : 18,566,915 -> 18,514,633: (-0.3%)
RandomText Balanced NoHyphenation : 7,697,772 -> 7,658,458: (-0.5%)
RandomText Greedy Hyphenation : 7,648,606 -> 7,602,026: (-0.6%)
RandomText Greedy NoHyphenation : 7,643,946 -> 7,618,898: (-0.3%)
MeasuredText creation time:
NoStyled Hyphenation : 18,377,293 -> 18,521,296: (+0.8%)
NoStyled Hyphenation WidthOnly : 17,852,099 -> 17,889,073: (+0.2%)
NoStyled NoHyphenation : 7,608,972 -> 7,614,311: (+0.1%)
NoStyled NoHyphenation WidthOnly : 7,194,461 -> 7,192,043: (-0.0%)
Styled Hyphenation : 15,396,698 -> 15,352,501: (-0.3%)
Styled Hyphenation WidthOnly : 14,356,020 -> 14,379,205: (+0.2%)
Styled NoHyphenation : 14,926,657 -> 14,971,723: (+0.3%)
Styled NoHyphenation WidthOnly : 13,964,537 -> 13,874,324: (-0.6%)
StaticLayout draw time:
MeasuredText NoStyled : 644,795 -> 635,241: (-1.5%)
MeasuredText NoStyled WithoutCache : 637,943 -> 616,369: (-3.4%)
MeasuredText Styled : 866,664 -> 860,322: (-0.7%)
MeasuredText Styled WithoutCache : 917,795 -> 897,164: (-2.2%)
RandomText NoStyled : 538,196 -> 533,253: (-0.9%)
RandomText NoStyled WithoutCache : 7,012,076 -> 7,047,498: (+0.5%)
RandomText Styled : 3,011,941 -> 2,999,661: (-0.4%)
RandomText Styled WithoutCache : 3,486,225 -> 3,462,493: (-0.7%)
Bug:
70185027
Test: atest CtsWidgetTestCases:EditTextTest
CtsWidgetTestCases:TextViewFadingEdgeTest
FrameworksCoreTests:TextViewFallbackLineSpacingTest
FrameworksCoreTests:TextViewTest FrameworksCoreTests:TypefaceTest
CtsGraphicsTestCases:TypefaceTest CtsWidgetTestCases:TextViewTest
CtsTextTestCases
Change-Id: I7ebb8a219a8eb07c8ad9fa432e8454e4e06be386
std::vector<minikin::FontVariation> axes;
};
+static inline NativeFamilyBuilder* toNativeBuilder(jlong ptr) {
+ return reinterpret_cast<NativeFamilyBuilder*>(ptr);
+}
+
+static inline FontFamilyWrapper* toFamily(jlong ptr) {
+ return reinterpret_cast<FontFamilyWrapper*>(ptr);
+}
+
+template<typename Ptr> static inline jlong toJLong(Ptr ptr) {
+ return reinterpret_cast<jlong>(ptr);
+}
+
static jlong FontFamily_initBuilder(JNIEnv* env, jobject clazz, jstring langs, jint variant) {
NativeFamilyBuilder* builder;
if (langs != nullptr) {
} else {
builder = new NativeFamilyBuilder(minikin::registerLocaleList(""), variant);
}
- return reinterpret_cast<jlong>(builder);
+ return toJLong(builder);
}
static jlong FontFamily_create(jlong builderPtr) {
if (builderPtr == 0) {
return 0;
}
- std::unique_ptr<NativeFamilyBuilder> builder(
- reinterpret_cast<NativeFamilyBuilder*>(builderPtr));
+ NativeFamilyBuilder* builder = toNativeBuilder(builderPtr);
if (builder->fonts.empty()) {
return 0;
}
if (family->getCoverage().length() == 0) {
return 0;
}
- return reinterpret_cast<jlong>(new FontFamilyWrapper(std::move(family)));
+ return toJLong(new FontFamilyWrapper(std::move(family)));
}
-static void FontFamily_abort(jlong builderPtr) {
- NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
- delete builder;
+static void releaseBuilder(jlong builderPtr) {
+ delete toNativeBuilder(builderPtr);
}
-static void FontFamily_unref(jlong familyPtr) {
- FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(familyPtr);
- delete family;
+static jlong FontFamily_getBuilderReleaseFunc() {
+ return toJLong(&releaseBuilder);
+}
+
+static void releaseFamily(jlong familyPtr) {
+ delete toFamily(familyPtr);
+}
+
+static jlong FontFamily_getFamilyReleaseFunc() {
+ return toJLong(&releaseFamily);
}
static bool addSkTypeface(NativeFamilyBuilder* builder, sk_sp<SkData>&& data, int ttcIndex,
static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong builderPtr,
jobject font, jint ttcIndex, jint weight, jint isItalic) {
NPE_CHECK_RETURN_ZERO(env, font);
- NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
+ NativeFamilyBuilder* builder = toNativeBuilder(builderPtr);
const void* fontPtr = env->GetDirectBufferAddress(font);
if (fontPtr == NULL) {
ALOGE("addFont failed to create font, buffer invalid");
NPE_CHECK_RETURN_ZERO(env, jassetMgr);
NPE_CHECK_RETURN_ZERO(env, jpath);
- NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
-
+ NativeFamilyBuilder* builder = toNativeBuilder(builderPtr);
Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, jassetMgr);
if (NULL == mgr) {
builder->axes.clear();
}
static void FontFamily_addAxisValue(jlong builderPtr, jint tag, jfloat value) {
- NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
+ NativeFamilyBuilder* builder = toNativeBuilder(builderPtr);
builder->axes.push_back({static_cast<minikin::AxisTag>(tag), value});
}
///////////////////////////////////////////////////////////////////////////////
static const JNINativeMethod gFontFamilyMethods[] = {
- { "nInitBuilder", "(Ljava/lang/String;I)J", (void*)FontFamily_initBuilder },
- { "nCreateFamily", "(J)J", (void*)FontFamily_create },
- { "nAbort", "(J)V", (void*)FontFamily_abort },
- { "nUnrefFamily", "(J)V", (void*)FontFamily_unref },
- { "nAddFont", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFont },
- { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;III)Z",
+ { "nInitBuilder", "(Ljava/lang/String;I)J", (void*)FontFamily_initBuilder },
+ { "nCreateFamily", "(J)J", (void*)FontFamily_create },
+ { "nGetBuilderReleaseFunc", "()J", (void*)FontFamily_getBuilderReleaseFunc },
+ { "nGetFamilyReleaseFunc", "()J", (void*)FontFamily_getFamilyReleaseFunc },
+ { "nAddFont", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFont },
+ { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;III)Z",
(void*)FontFamily_addFontWeightStyle },
{ "nAddFontFromAssetManager", "(JLandroid/content/res/AssetManager;Ljava/lang/String;IZIII)Z",
(void*)FontFamily_addFontFromAssetManager },
using namespace android;
+static inline Typeface* toTypeface(jlong ptr) {
+ return reinterpret_cast<Typeface*>(ptr);
+}
+
+template<typename Ptr> static inline jlong toJLong(Ptr ptr) {
+ return reinterpret_cast<jlong>(ptr);
+}
+
static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
- Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
+ Typeface* family = toTypeface(familyHandle);
Typeface* face = Typeface::createRelative(family, (Typeface::Style)style);
// TODO: the following logic shouldn't be necessary, the above should always succeed.
// Try to find the closest matching font, using the standard heuristic
for (int i = 0; NULL == face && i < 4; i++) {
face = Typeface::createRelative(family, (Typeface::Style)i);
}
- return reinterpret_cast<jlong>(face);
+ return toJLong(face);
}
static jlong Typeface_createFromTypefaceWithExactStyle(JNIEnv* env, jobject, jlong nativeInstance,
jint weight, jboolean italic) {
- Typeface* baseTypeface = reinterpret_cast<Typeface*>(nativeInstance);
- return reinterpret_cast<jlong>(Typeface::createAbsolute(baseTypeface, weight, italic));
+ return toJLong(Typeface::createAbsolute(toTypeface(nativeInstance), weight, italic));
}
static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlong familyHandle,
AxisHelper axis(env, axisObject);
variations.push_back(minikin::FontVariation(axis.getTag(), axis.getStyleValue()));
}
- Typeface* baseTypeface = reinterpret_cast<Typeface*>(familyHandle);
- Typeface* result = Typeface::createFromTypefaceWithVariation(baseTypeface, variations);
- return reinterpret_cast<jlong>(result);
+ return toJLong(Typeface::createFromTypefaceWithVariation(toTypeface(familyHandle), variations));
}
static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle, jint weight) {
- Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
- Typeface* face = Typeface::createWithDifferentBaseWeight(family, weight);
- return reinterpret_cast<jlong>(face);
+ return toJLong(Typeface::createWithDifferentBaseWeight(toTypeface(familyHandle), weight));
+}
+
+static void releaseFunc(jlong ptr) {
+ delete toTypeface(ptr);
}
-static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) {
- Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
- delete face;
+// CriticalNative
+static jlong Typeface_getReleaseFunc() {
+ return toJLong(&releaseFunc);
}
-static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
- Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
- return face->fAPIStyle;
+// CriticalNative
+static jint Typeface_getStyle(jlong faceHandle) {
+ return toTypeface(faceHandle)->fAPIStyle;
}
-static jint Typeface_getWeight(JNIEnv* env, jobject obj, jlong faceHandle) {
- Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
- return face->fStyle.weight();
+// CriticalNative
+static jint Typeface_getWeight(jlong faceHandle) {
+ return toTypeface(faceHandle)->fStyle.weight();
}
static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray,
FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]);
familyVec.emplace_back(family->family);
}
- return reinterpret_cast<jlong>(
- Typeface::createFromFamilies(std::move(familyVec), weight, italic));
+ return toJLong(Typeface::createFromFamilies(std::move(familyVec), weight, italic));
}
-static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
- Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
- Typeface::setDefault(face);
+// CriticalNative
+static void Typeface_setDefault(jlong faceHandle) {
+ Typeface::setDefault(toTypeface(faceHandle));
}
static jobject Typeface_getSupportedAxes(JNIEnv *env, jobject, jlong faceHandle) {
- Typeface* face = reinterpret_cast<Typeface*>(faceHandle);
+ Typeface* face = toTypeface(faceHandle);
const std::unordered_set<minikin::AxisTag>& tagSet = face->fFontCollection->getSupportedTags();
const size_t length = tagSet.size();
if (length == 0) {
{ "nativeCreateFromTypefaceWithVariation", "(JLjava/util/List;)J",
(void*)Typeface_createFromTypefaceWithVariation },
{ "nativeCreateWeightAlias", "(JI)J", (void*)Typeface_createWeightAlias },
- { "nativeUnref", "(J)V", (void*)Typeface_unref },
+ { "nativeGetReleaseFunc", "()J", (void*)Typeface_getReleaseFunc },
{ "nativeGetStyle", "(J)I", (void*)Typeface_getStyle },
{ "nativeGetWeight", "(J)I", (void*)Typeface_getWeight },
{ "nativeCreateFromArray", "([JII)J",
import dalvik.annotation.optimization.CriticalNative;
+import libcore.util.NativeAllocationRegistry;
+
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
private static String TAG = "FontFamily";
+ private static final NativeAllocationRegistry sBuilderRegistry = new NativeAllocationRegistry(
+ FontFamily.class.getClassLoader(), nGetBuilderReleaseFunc(), 64);
+
+ private @Nullable Runnable mNativeBuilderCleaner;
+
+ private static final NativeAllocationRegistry sFamilyRegistry = new NativeAllocationRegistry(
+ FontFamily.class.getClassLoader(), nGetFamilyReleaseFunc(), 64);
+
/**
* @hide
*/
public FontFamily() {
mBuilderPtr = nInitBuilder(null, 0);
+ mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
public FontFamily(@Nullable String[] langs, int variant) {
langsString = TextUtils.join(",", langs);
}
mBuilderPtr = nInitBuilder(langsString, variant);
+ mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
/**
throw new IllegalStateException("This FontFamily is already frozen");
}
mNativePtr = nCreateFamily(mBuilderPtr);
+ mNativeBuilderCleaner.run();
mBuilderPtr = 0;
+ if (mNativePtr != 0) {
+ sFamilyRegistry.registerNativeAllocation(this, mNativePtr);
+ }
return mNativePtr != 0;
}
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen or abandoned");
}
- nAbort(mBuilderPtr);
+ mNativeBuilderCleaner.run();
mBuilderPtr = 0;
}
- @Override
- protected void finalize() throws Throwable {
- try {
- if (mNativePtr != 0) {
- nUnrefFamily(mNativePtr);
- }
- if (mBuilderPtr != 0) {
- nAbort(mBuilderPtr);
- }
- } finally {
- super.finalize();
- }
- }
-
public boolean addFont(String path, int ttcIndex, FontVariationAxis[] axes, int weight,
int italic) {
if (mBuilderPtr == 0) {
private static native long nCreateFamily(long mBuilderPtr);
@CriticalNative
- private static native void nAbort(long mBuilderPtr);
+ private static native long nGetBuilderReleaseFunc();
@CriticalNative
- private static native void nUnrefFamily(long nativePtr);
+ private static native long nGetFamilyReleaseFunc();
// By passing -1 to weigth argument, the weight value is resolved by OS/2 table in the font.
// By passing -1 to italic argument, the italic value is resolved by OS/2 table in the font.
private static native boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex,
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
+import dalvik.annotation.optimization.CriticalNative;
+
+import libcore.util.NativeAllocationRegistry;
+
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
private static String TAG = "Typeface";
+ private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+ Typeface.class.getClassLoader(), nativeGetReleaseFunc(), 64);
+
/** The default NORMAL typeface object */
public static final Typeface DEFAULT;
/**
}
native_instance = ni;
+ sRegistry.registerNativeAllocation(this, native_instance);
mStyle = nativeGetStyle(ni);
mWeight = nativeGetWeight(ni);
}
}
@Override
- protected void finalize() throws Throwable {
- try {
- nativeUnref(native_instance);
- native_instance = 0; // Other finalizers can still call us.
- } finally {
- super.finalize();
- }
- }
-
- @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
private static native long nativeCreateFromTypefaceWithVariation(
long native_instance, List<FontVariationAxis> axes);
private static native long nativeCreateWeightAlias(long native_instance, int weight);
- private static native void nativeUnref(long native_instance);
- private static native int nativeGetStyle(long native_instance);
- private static native int nativeGetWeight(long native_instance);
private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic);
- private static native void nativeSetDefault(long native_instance);
private static native int[] nativeGetSupportedAxes(long native_instance);
+
+ @CriticalNative
+ private static native void nativeSetDefault(long nativePtr);
+
+ @CriticalNative
+ private static native int nativeGetStyle(long nativePtr);
+
+ @CriticalNative
+ private static native int nativeGetWeight(long nativePtr);
+
+ @CriticalNative
+ private static native long nativeGetReleaseFunc();
}