diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2012-05-07 17:45:44 -0700 |
---|---|---|
committer | Fabrice Di Meglio <fdimeglio@google.com> | 2012-05-07 20:17:38 -0700 |
commit | 30ca5cd11a23f06f2f8eeaa587685450826f800f (patch) | |
tree | 69cdc7dc7653340c0fb27daccf1f82af7a0e45ed | |
parent | 476b03b0c0d5cae4d1b114c6f80858d59ba36cad (diff) | |
download | frameworks_base-30ca5cd11a23f06f2f8eeaa587685450826f800f.zip frameworks_base-30ca5cd11a23f06f2f8eeaa587685450826f800f.tar.gz frameworks_base-30ca5cd11a23f06f2f8eeaa587685450826f800f.tar.bz2 |
Fix bug #6408393 Character corruption is caused when locale is changed
- free the TextLayoutCache on Locale change
- also free TextLayoutCache when memory is low
Change-Id: I39a37ac8ec3c292cfb1c0eea4bb41ff71897d089
-rw-r--r-- | core/java/android/app/ActivityThread.java | 22 | ||||
-rw-r--r-- | core/jni/android/graphics/Canvas.cpp | 10 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 7 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.h | 3 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 7 |
5 files changed, 47 insertions, 2 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b55ee26..e53438c 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2639,6 +2639,7 @@ public final class ActivityThread { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.newConfig); performConfigurationChanged(r.activity, r.newConfig); + freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); r.newConfig = null; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" @@ -2955,6 +2956,7 @@ public final class ActivityThread { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " + r.activityInfo.name + " with new config " + r.newConfig); performConfigurationChanged(r.activity, r.newConfig); + freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); r.newConfig = null; } } else { @@ -3669,6 +3671,7 @@ public final class ActivityThread { final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { ArrayList<ComponentCallbacks2> callbacks = null; + int configDiff = 0; synchronized (mPackages) { if (mPendingConfiguration != null) { @@ -3693,6 +3696,7 @@ public final class ActivityThread { if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { return; } + configDiff = mConfiguration.diff(config); mConfiguration.updateFrom(config); config = applyCompatConfiguration(); callbacks = collectComponentCallbacksLocked(false, config); @@ -3701,6 +3705,8 @@ public final class ActivityThread { // Cleanup hardware accelerated stuff WindowManagerImpl.getDefault().trimLocalMemory(); + freeTextLayoutCachesIfNeeded(configDiff); + if (callbacks != null) { final int N = callbacks.size(); for (int i=0; i<N; i++) { @@ -3709,6 +3715,17 @@ public final class ActivityThread { } } + final void freeTextLayoutCachesIfNeeded(int configDiff) { + if (configDiff != 0) { + // Ask text layout engine to free its caches if there is a locale change + boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); + if (hasLocaleConfigChange) { + Canvas.freeTextLayoutCaches(); + if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); + } + } + } + final void handleActivityConfigurationChanged(IBinder token) { ActivityClientRecord r = mActivities.get(token); if (r == null || r.activity == null) { @@ -3719,6 +3736,8 @@ public final class ActivityThread { + r.activityInfo.name); performConfigurationChanged(r.activity, mCompatConfiguration); + + freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); } final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { @@ -3821,6 +3840,9 @@ public final class ActivityThread { // Ask graphics to free up as much as possible (font/image caches) Canvas.freeCaches(); + // Ask text layout engine to free also as much as possible + Canvas.freeTextLayoutCaches(); + BinderInternal.forceGc("mem"); } diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp index ef6af74..6b74705 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -69,7 +69,11 @@ public: SkImageRef_GlobalPool::SetRAMUsed(0); SkGraphics::PurgeFontCache(); } - + + static void freeTextLayoutCaches(JNIEnv* env, jobject) { + TextLayoutEngine::getInstance().purgeCaches(); + } + static jboolean isOpaque(JNIEnv* env, jobject jcanvas) { NPE_CHECK_RETURN_ZERO(env, jcanvas); SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas); @@ -986,7 +990,9 @@ static JNINativeMethod gCanvasMethods[] = { (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint}, {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture}, - {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches} + {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}, + + {"freeTextLayoutCaches", "()V", (void*) SkCanvasGlue::freeTextLayoutCaches} }; /////////////////////////////////////////////////////////////////////////////// diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 2c38893..71c7ab0 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -991,4 +991,11 @@ sp<TextLayoutValue> TextLayoutEngine::getValue(const SkPaint* paint, const jchar return value; } +void TextLayoutEngine::purgeCaches() { +#if USE_TEXT_LAYOUT_CACHE + mTextLayoutCache->clear(); +#endif +} + + } // namespace android diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 7d7caac..7308367 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -309,6 +309,9 @@ public: sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start, jint count, jint contextCount, jint dirFlags); + + void purgeCaches(); + private: TextLayoutCache* mTextLayoutCache; TextLayoutShaper* mShaper; diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 7e92973..3949afd 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1617,6 +1617,13 @@ public class Canvas { */ public static native void freeCaches(); + /** + * Free up text layout caches + * + * @hide + */ + public static native void freeTextLayoutCaches(); + private static native int initRaster(int nativeBitmapOrZero); private static native void native_setBitmap(int nativeCanvas, int bitmap); private static native int native_saveLayer(int nativeCanvas, RectF bounds, |