Add sanity check to RenderNodeAnimator to avoid crashing Launcher3.
mNativePtr = new VirtualRefBasePtr(ptr);
}
- private void checkMutable() {
+ private boolean checkMutable() {
if (mState != STATE_PREPARE) {
throw new IllegalStateException("Animator has already started, cannot change it now!");
}
- if (mNativePtr == null) {
- throw new IllegalStateException("Animator's target has been destroyed "
- + "(trying to modify an animation after activity destroy?)");
- }
+ return (mNativePtr != null);
}
static boolean isNativeInterpolator(TimeInterpolator interpolator) {
if (isNativeInterpolator(mInterpolator)) {
ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
} else {
+ if (mNativePtr == null) return;
long duration = nGetDuration(mNativePtr.get());
ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
}
}
private void setTarget(RenderNode node) {
- checkMutable();
+ if (!checkMutable()) return;
if (mTarget != null) {
throw new IllegalStateException("Target already set!");
}
}
public void setStartValue(float startValue) {
- checkMutable();
+ if (!checkMutable()) return;
nSetStartValue(mNativePtr.get(), startValue);
}
@Override
public void setStartDelay(long startDelay) {
- checkMutable();
+ if (!checkMutable()) return;
if (startDelay < 0) {
throw new IllegalArgumentException("startDelay must be positive; " + startDelay);
}
@Override
public RenderNodeAnimator setDuration(long duration) {
- checkMutable();
+ if (!checkMutable()) return this;
if (duration < 0) {
throw new IllegalArgumentException("duration must be positive; " + duration);
}
@Override
public void setInterpolator(TimeInterpolator interpolator) {
- checkMutable();
+ if (!checkMutable()) return;
mInterpolator = interpolator;
}
@Override
public void setAllowRunningAsynchronously(boolean mayRunAsync) {
- checkMutable();
+ if (!checkMutable()) return;
nSetAllowRunningAsync(mNativePtr.get(), mayRunAsync);
}
static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
#ifdef USE_OPENGL_RENDERER
- if (android::uirenderer::ResourceCache::hasInstance()) {
+ if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::ResourceCache::hasInstance()) {
android::uirenderer::ResourceCache::getInstance().destructor(bitmap);
return;
}
static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
#ifdef USE_OPENGL_RENDERER
- if (android::uirenderer::ResourceCache::hasInstance()) {
+ if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::ResourceCache::hasInstance()) {
bool result;
result = android::uirenderer::ResourceCache::getInstance().recycle(bitmap);
return result ? JNI_TRUE : JNI_FALSE;
#include "SkMath.h"
#include "SkPicture.h"
#include "SkRegion.h"
+#include <cutils/properties.h>
#include <android_runtime/AndroidRuntime.h>
void doThrowNPE(JNIEnv* env) {
jniThrowException(env, "java/io/IOException", msg);
}
+static bool checkOpenglRenderer() {
+ char prop[PROPERTY_VALUE_MAX];
+ property_get("debug.egl.hw", prop, "1");
+ return atoi(prop) == 1;
+}
+
+bool GraphicsJNI::useOpenglRenderer() {
+ static bool use_opengl_renderer = checkOpenglRenderer();
+ return use_opengl_renderer;
+}
+
bool GraphicsJNI::hasException(JNIEnv *env) {
if (env->ExceptionCheck() != 0) {
ALOGE("*** Uncaught exception returned from Java call!\n");
kBitmapCreateFlag_Premultiplied = 0x2,
};
+ static bool useOpenglRenderer();
+
// returns true if an exception is set (and dumps it out to the Log)
static bool hasException(JNIEnv*);
static void finalize(JNIEnv* env, jobject, jlong patchHandle) {
int8_t* patch = reinterpret_cast<int8_t*>(patchHandle);
#ifdef USE_OPENGL_RENDERER
- if (android::uirenderer::ResourceCache::hasInstance()) {
+ if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::ResourceCache::hasInstance()) {
Res_png_9patch* p = (Res_png_9patch*) patch;
android::uirenderer::ResourceCache::getInstance().destructor(p);
return;
static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
#ifdef USE_OPENGL_RENDERER
- if (android::uirenderer::ResourceCache::hasInstance()) {
+ if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::ResourceCache::hasInstance()) {
android::uirenderer::ResourceCache::getInstance().destructor(obj);
return;
}
char prop[PROPERTY_VALUE_MAX];
if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
// not in the emulator
- return JNI_TRUE;
+ return GraphicsJNI::useOpenglRenderer() ? JNI_TRUE : JNI_FALSE;
}
// In the emulator this property will be set to 1 when hardware GLES is
// enabled, 0 otherwise. On old emulator versions it will be undefined.
static void
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
#ifdef USE_OPENGL_RENDERER
+ if (!GraphicsJNI::useOpenglRenderer()) return;
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
android::uirenderer::renderthread::RenderProxy::outputLogBuffer(fd);
#endif // USE_OPENGL_RENDERER
int register_android_view_GLES20Canvas(JNIEnv* env) {
jclass clazz;
- FIND_CLASS(clazz, "android/graphics/Rect");
- GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
+ if (GraphicsJNI::useOpenglRenderer()) {
+ FIND_CLASS(clazz, "android/graphics/Rect");
+ GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
+ }
return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}