summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chris Craik <ccraik@google.com> 2015-04-02 15:28:08 -0700
committer Chris Craik <ccraik@google.com> 2015-04-02 15:30:32 -0700
commit3891f3ad598561d5a82c07795e1fee7f1d3612d1 (patch)
tree7672d25f02d022ba08453a8fee6c9be02d92ef6b
parent095d99904579a5231d974a2447661c10a8eb621b (diff)
Add compat path for restore underflow
bug:19829784 Change-Id: Ia761664208ab80c055ca11174db3ddc74457b92b
-rw-r--r--core/java/android/view/DisplayListCanvas.java1
-rw-r--r--core/java/android/view/RenderNode.java7
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/jni/android_graphics_Canvas.cpp22
-rw-r--r--graphics/java/android/graphics/Canvas.java13
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,