diff options
| author | 2015-04-02 15:28:08 -0700 | |
|---|---|---|
| committer | 2015-04-02 15:30:32 -0700 | |
| commit | 3891f3ad598561d5a82c07795e1fee7f1d3612d1 (patch) | |
| tree | 7672d25f02d022ba08453a8fee6c9be02d92ef6b | |
| parent | 095d99904579a5231d974a2447661c10a8eb621b (diff) | |
Add compat path for restore underflow
bug:19829784
Change-Id: Ia761664208ab80c055ca11174db3ddc74457b92b
| -rw-r--r-- | core/java/android/view/DisplayListCanvas.java | 1 | ||||
| -rw-r--r-- | core/java/android/view/RenderNode.java | 7 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 2 | ||||
| -rw-r--r-- | core/jni/android_graphics_Canvas.cpp | 22 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Canvas.java | 13 |
5 files changed, 26 insertions, 19 deletions
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java index 3caf6f07c891..ec8f802a179f 100644 --- a/core/java/android/view/DisplayListCanvas.java +++ b/core/java/android/view/DisplayListCanvas.java @@ -48,7 +48,6 @@ public class DisplayListCanvas extends Canvas { private int mWidth; private int mHeight; - static DisplayListCanvas obtain(@NonNull RenderNode node) { if (node == null) throw new IllegalArgumentException("node cannot be null"); DisplayListCanvas canvas = sPool.acquire(); diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index ef98bbcd35f4..236cfefd9718 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -240,12 +240,7 @@ public class RenderNode { * @see #start(int, int) * @see #isValid() */ - public void end(DisplayListCanvas endCanvas) { - if (!(endCanvas instanceof DisplayListCanvas)) { - throw new IllegalArgumentException("Passed an invalid canvas to end!"); - } - - DisplayListCanvas canvas = (DisplayListCanvas) endCanvas; + public void end(DisplayListCanvas canvas) { canvas.onPostDraw(); long renderNodeData = canvas.finishRecording(); nSetDisplayListData(mNativeRenderNode, renderNodeData); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index a69384af8d91..386362353f22 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3582,6 +3582,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // of whether a layout was requested on that View. sIgnoreMeasureCache = targetSdkVersion < KITKAT; + Canvas.sCompatibilityRestore = targetSdkVersion < MNC; + sCompatibilityDone = true; } } diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 4c08b4b056fe..a2c16097b2bf 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -86,20 +86,26 @@ static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, j return static_cast<jint>(get_canvas(canvasHandle)->saveLayerAlpha(l, t, r, b, alpha, flags)); } -static void restore(JNIEnv* env, jobject, jlong canvasHandle) { +static void restore(JNIEnv* env, jobject, jlong canvasHandle, jboolean throwOnUnderflow) { Canvas* canvas = get_canvas(canvasHandle); if (canvas->getSaveCount() <= 1) { // cannot restore anymore - doThrowISE(env, "Underflow in restore - more restores than saves"); - return; + if (throwOnUnderflow) { + doThrowISE(env, "Underflow in restore - more restores than saves"); + } + return; // compat behavior - return without throwing } canvas->restore(); } -static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount) { +static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount, + jboolean throwOnUnderflow) { Canvas* canvas = get_canvas(canvasHandle); if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) { - doThrowIAE(env, "Underflow in restoreToCount - more restores than saves"); - return; + if (throwOnUnderflow) { + doThrowIAE(env, "Underflow in restoreToCount - more restores than saves"); + return; + } + restoreCount = 1; // compat behavior - restore as far as possible } canvas->restoreToCount(restoreCount); } @@ -661,8 +667,8 @@ static JNINativeMethod gMethods[] = { {"native_saveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer}, {"native_saveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha}, {"native_getSaveCount","(J)I", (void*) CanvasJNI::getSaveCount}, - {"native_restore","(J)V", (void*) CanvasJNI::restore}, - {"native_restoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount}, + {"native_restore","(JZ)V", (void*) CanvasJNI::restore}, + {"native_restoreToCount","(JIZ)V", (void*) CanvasJNI::restoreToCount}, {"native_getCTM", "(JJ)V", (void*)CanvasJNI::getCTM}, {"native_setMatrix","(JJ)V", (void*) CanvasJNI::setMatrix}, {"native_concat","(JJ)V", (void*) CanvasJNI::concat}, diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 150f1950a81f..48afcbfde5d0 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -45,6 +45,8 @@ import javax.microedition.khronos.opengles.GL; * Canvas and Drawables</a> developer guide.</p></div> */ public class Canvas { + /** @hide */ + public static boolean sCompatibilityRestore = false; /** * Should only be assigned in constructors (or setBitmap if software canvas), @@ -557,7 +559,8 @@ public class Canvas { * an error to call restore() more times than save() was called. */ public void restore() { - native_restore(mNativeCanvasWrapper); + boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated(); + native_restore(mNativeCanvasWrapper, throwOnUnderflow); } /** @@ -582,7 +585,8 @@ public class Canvas { * @param saveCount The save level to restore to. */ public void restoreToCount(int saveCount) { - native_restoreToCount(mNativeCanvasWrapper, saveCount); + boolean throwOnUnderflow = !sCompatibilityRestore || !isHardwareAccelerated(); + native_restoreToCount(mNativeCanvasWrapper, saveCount, throwOnUnderflow); } /** @@ -1988,9 +1992,10 @@ public class Canvas { private static native int native_saveLayerAlpha(long nativeCanvas, float l, float t, float r, float b, int alpha, int layerFlags); - private static native void native_restore(long canvasHandle); + private static native void native_restore(long canvasHandle, boolean tolerateUnderflow); private static native void native_restoreToCount(long canvasHandle, - int saveCount); + int saveCount, + boolean tolerateUnderflow); private static native int native_getSaveCount(long canvasHandle); private static native void native_translate(long canvasHandle, |