Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d518dcd authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Remove nSetLocales

nSetLocales needed to be done at the same time of addStyleRun.
So it is natural to be the arguments of addStyleRun.

Since locale change detection take longer time in native, check it
in Java and pass null if not changed.

Here is an example of StaticLayoutPerfTestResult.
Before (median):
 createRandom: 3,422,247
 createRandom(breakBalanced): 3,448,865
 create: 183,642

After:
 createRandom: 3,493,079
 createRandom(breakBalanced): 3,495,381
 create: 193,363

Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: bit CtsTextTestCases:android.text.cts.DynamicLayoutTest
Test: bit CtsTextTestCases:android.text.cts.StaticLayoutTest
Test: minikin_tests
Bug: 65175766
Bug: 65024629
Change-Id: I4586cef626f631d4736b0db59ba9f3f6abd3d4ff
parent a0a23c7f
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ public class StaticLayout extends Layout {
            b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
            b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
            b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
            b.mLocales = null;

            b.mMeasuredText = MeasuredText.obtain();
            return b;
@@ -117,6 +118,7 @@ public class StaticLayout extends Layout {
            b.mMeasuredText = null;
            b.mLeftIndents = null;
            b.mRightIndents = null;
            b.mLocales = null;
            nFinishBuilder(b.mNativePtr);
            sPool.release(b);
        }
@@ -401,7 +403,6 @@ public class StaticLayout extends Layout {
         * future).
         *
         * Then, for each run within the paragraph:
         *  - setLocales (this must be done at least for the first run, optional afterwards)
         *  - one of the following, depending on the type of run:
         *    + addStyleRun (a text run, to be measured in native code)
         *    + addMeasuredRun (a run already measured in Java, passed into native code)
@@ -413,16 +414,21 @@ public class StaticLayout extends Layout {
         * After all paragraphs, call finish() to release expensive buffers.
         */

        private void setLocales(LocaleList locales) {
        /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
            final LocaleList locales = paint.getTextLocales();
            final String languageTags;
            long[] hyphenators;
            if (!locales.equals(mLocales)) {
                nSetLocales(mNativePtr, locales.toLanguageTags(), getHyphenators(locales));
                mLocales = locales;
            }
                languageTags = locales.toLanguageTags();
                hyphenators = getHyphenators(locales);
            } else {
                // passing null means keep current locale.
                // TODO: move locale change detection to native.
                languageTags = null;
                hyphenators = null;
            }

        /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
            setLocales(paint.getTextLocales());
            return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl);
            return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl,
                    languageTags, hyphenators);
        }

        /* package */ void addMeasuredRun(int start, int end, float[] widths) {
@@ -662,7 +668,6 @@ public class StaticLayout extends Layout {
        // store fontMetrics per span range
        // must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range)
        int[] fmCache = new int[4 * 4];
        b.setLocales(paint.getTextLocales());

        mLineCount = 0;
        mEllipsized = false;
@@ -1494,20 +1499,19 @@ public class StaticLayout extends Layout {
    /* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset,
            int minPrefix, int minSuffix);

    private static native void nSetLocales(long nativePtr, String locales,
            long[] nativeHyphenators);

    // Set up paragraph text and settings; done as one big method to minimize jni crossings
    private static native void nSetupParagraph(
            @NonNull long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length,
            /* non zero */ long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length,
            @FloatRange(from = 0.0f) float firstWidth, @IntRange(from = 0) int firstWidthLineCount,
            @FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops,
            int defaultTabStop, @BreakStrategy int breakStrategy,
            @HyphenationFrequency int hyphenationFrequency, boolean isJustified,
            @Nullable int[] indents, @IntRange(from = 0) int indentsOffset);

    private static native float nAddStyleRun(long nativePtr, long nativePaint, int start, int end,
            boolean isRtl);
    private static native float nAddStyleRun(
            /* non zero */ long nativePtr, /* non zero */ long nativePaint,
            @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean isRtl,
            @Nullable String languageTags, @Nullable long[] hyphenators);

    private static native void nAddMeasuredRun(long nativePtr,
            int start, int end, float[] widths);
+24 −21
Original line number Diff line number Diff line
@@ -187,24 +187,9 @@ static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset,
    return reinterpret_cast<jlong>(hyphenator);
}

static void nSetLocales(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleNames,
        jlongArray nativeHyphenators) {
    minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);

    ScopedUtfChars localeNames(env, javaLocaleNames);
    ScopedLongArrayRO hyphArr(env, nativeHyphenators);
    const size_t numLocales = hyphArr.size();
    std::vector<minikin::Hyphenator*> hyphVec;
    hyphVec.reserve(numLocales);
    for (size_t i = 0; i < numLocales; i++) {
        hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
    }
    b->setLocales(localeNames.c_str(), hyphVec);
}

// Basically similar to Paint.getTextRunAdvances but with C++ interface
static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePaint, jint start,
        jint end, jboolean isRtl) {
        jint end, jboolean isRtl, jstring langTags, jlongArray hyphenators) {
    minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
    Paint* paint = reinterpret_cast<Paint*>(nativePaint);
    const Typeface* typeface = paint->getAndroidTypeface();
@@ -212,8 +197,26 @@ static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePai
    const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface);
    minikin::FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, paint,
            typeface);
    return b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start, end,
            isRtl);

    std::vector<minikin::Hyphenator*> hyphVec;
    const char* langTagStr;
    if (langTags == nullptr) {
        langTagStr = nullptr;  // nullptr languageTag means keeping current locale
    } else {
        ScopedLongArrayRO hyphArr(env, hyphenators);
        const size_t numLocales = hyphArr.size();
        hyphVec.reserve(numLocales);
        for (size_t i = 0; i < numLocales; i++) {
          hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
        }
        langTagStr = env->GetStringUTFChars(langTags, nullptr);
    }
    float result = b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start,
            end, isRtl, langTagStr, hyphVec);
    if (langTagStr != nullptr)  {
        env->ReleaseStringUTFChars(langTags, langTagStr);
    }
    return result;
}

// Accept width measurements for the run, passed in from Java
@@ -221,7 +224,8 @@ static void nAddMeasuredRun(JNIEnv* env, jclass, jlong nativePtr,
        jint start, jint end, jfloatArray widths) {
    minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
    env->GetFloatArrayRegion(widths, start, end - start, b->charWidths() + start);
    b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false);
    b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false,
            nullptr /* keep current locale */, std::vector<minikin::Hyphenator*>());
}

static void nAddReplacementRun(JNIEnv* env, jclass, jlong nativePtr,
@@ -241,9 +245,8 @@ static const JNINativeMethod gMethods[] = {
    {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
    {"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
    {"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator},
    {"nSetLocales", "(JLjava/lang/String;[J)V", (void*) nSetLocales},
    {"nSetupParagraph", "(J[CIFIF[IIIIZ[II)V", (void*) nSetupParagraph},
    {"nAddStyleRun", "(JJIIZ)F", (void*) nAddStyleRun},
    {"nAddStyleRun", "(JJIIZLjava/lang/String;[J)F", (void*) nAddStyleRun},
    {"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
    {"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun},
    {"nGetWidths", "(J[F)V", (void*) nGetWidths},