OSDN Git Service

libandroid_runtime: determine whether to use OpenGL renderer at runtime
authorChih-Wei Huang <cwhuang@linux.org.tw>
Thu, 25 Jul 2013 20:34:26 +0000 (04:34 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Wed, 25 Sep 2013 02:46:36 +0000 (10:46 +0800)
core/jni/android/graphics/Bitmap.cpp
core/jni/android/graphics/ColorFilter.cpp
core/jni/android/graphics/Graphics.cpp
core/jni/android/graphics/GraphicsJNI.h
core/jni/android/graphics/Path.cpp
core/jni/android/graphics/Shader.cpp
core/jni/android_view_GLES20Canvas.cpp

index 63683b4..b0c8119 100644 (file)
@@ -253,7 +253,7 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
 \r
 static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {\r
 #ifdef USE_OPENGL_RENDERER\r
-    if (android::uirenderer::Caches::hasInstance()) {\r
+    if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::Caches::hasInstance()) {
         android::uirenderer::Caches::getInstance().resourceCache.destructor(bitmap);\r
         return;\r
     }\r
@@ -263,7 +263,7 @@ static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
 \r
 static jboolean Bitmap_recycle(JNIEnv* env, jobject, SkBitmap* bitmap) {\r
 #ifdef USE_OPENGL_RENDERER\r
-    if (android::uirenderer::Caches::hasInstance()) {\r
+    if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::Caches::hasInstance()) {
         return android::uirenderer::Caches::getInstance().resourceCache.recycle(bitmap);\r
     }\r
 #endif // USE_OPENGL_RENDERER\r
index dd1177b..cf0469c 100644 (file)
@@ -36,6 +36,7 @@ public:
         SkSafeUnref(obj);
         // f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
 #ifdef USE_OPENGL_RENDERER
+        if (!GraphicsJNI::useOpenglRenderer()) return;
         if (android::uirenderer::Caches::hasInstance()) {
             android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
         } else {
@@ -47,6 +48,7 @@ public:
     static SkiaColorFilter* glCreatePorterDuffFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
             jint srcColor, SkPorterDuff::Mode mode) {
 #ifdef USE_OPENGL_RENDERER
+        if (!GraphicsJNI::useOpenglRenderer()) return NULL;
         return new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode));
 #else
         return NULL;
@@ -56,6 +58,7 @@ public:
     static SkiaColorFilter* glCreateLightingFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
             jint mul, jint add) {
 #ifdef USE_OPENGL_RENDERER
+        if (!GraphicsJNI::useOpenglRenderer()) return NULL;
         return new SkiaLightingFilter(skFilter, mul, add);
 #else
         return NULL;
@@ -65,6 +68,7 @@ public:
     static SkiaColorFilter* glCreateColorMatrixFilter(JNIEnv* env, jobject, SkColorFilter *skFilter,
             jfloatArray jarray) {
 #ifdef USE_OPENGL_RENDERER
+        if (!GraphicsJNI::useOpenglRenderer()) return NULL;
         AutoJavaFloatArray autoArray(env, jarray, 20);
         const float* src = autoArray.ptr();
 
index d4c7600..2f9c124 100644 (file)
@@ -8,6 +8,7 @@
 #include "SkDevice.h"
 #include "SkPicture.h"
 #include "SkRegion.h"
+#include <cutils/properties.h>
 #include <android_runtime/AndroidRuntime.h>
 
 void doThrowNPE(JNIEnv* env) {
@@ -38,6 +39,17 @@ void doThrowIOE(JNIEnv* env, const char* msg) {
     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");
index c5b06f5..739939c 100644 (file)
@@ -17,6 +17,8 @@ class SkPicture;
 
 class GraphicsJNI {
 public:
+    static bool useOpenglRenderer();
+
     // returns true if an exception is set (and dumps it out to the Log)
     static bool hasException(JNIEnv*);
 
index eb9e004..583f5d9 100644 (file)
@@ -35,7 +35,7 @@ public:
 
     static void finalizer(JNIEnv* env, jobject clazz, SkPath* obj) {
 #ifdef USE_OPENGL_RENDERER
-        if (android::uirenderer::Caches::hasInstance()) {
+        if (GraphicsJNI::useOpenglRenderer() && android::uirenderer::Caches::hasInstance()) {
             android::uirenderer::Caches::getInstance().resourceCache.destructor(obj);
             return;
         }
index 6323ab3..61ce3e6 100644 (file)
@@ -56,6 +56,7 @@ static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShad
     SkSafeUnref(shader);
     // skiaShader == NULL when not !USE_OPENGL_RENDERER, so no need to delete it outside the ifdef
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return;
     if (android::uirenderer::Caches::hasInstance()) {
         android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader);
     } else {
@@ -75,6 +76,7 @@ static void Shader_setLocalMatrix(JNIEnv* env, jobject o, SkShader* shader, Skia
             shader->setLocalMatrix(*matrix);
         }
 #ifdef USE_OPENGL_RENDERER
+        if (!GraphicsJNI::useOpenglRenderer()) return;
         skiaShader->setMatrix(const_cast<SkMatrix*>(matrix));
 #endif
     }
@@ -96,6 +98,7 @@ static SkShader* BitmapShader_constructor(JNIEnv* env, jobject o, const SkBitmap
 static SkiaShader* BitmapShader_postConstructor(JNIEnv* env, jobject o, SkShader* shader,
         SkBitmap* bitmap, int tileModeX, int tileModeY) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader,
             static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY),
             NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
@@ -144,6 +147,7 @@ static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader*
         float x0, float y0, float x1, float y1, jintArray colorArray,
         jfloatArray posArray, int tileMode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     size_t count = env->GetArrayLength(colorArray);
     const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
 
@@ -215,6 +219,7 @@ static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader*
 static SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
         float x0, float y0, float x1, float y1, int color0, int color1, int tileMode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     float* storedBounds = new float[4];
     storedBounds[0] = x0; storedBounds[1] = y0;
     storedBounds[2] = x1; storedBounds[3] = y1;
@@ -306,6 +311,7 @@ static SkShader* RadialGradient_create2(JNIEnv* env, jobject, float x, float y,
 static SkiaShader* RadialGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
         float x, float y, float radius, jintArray colorArray, jfloatArray posArray, int tileMode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     size_t count = env->GetArrayLength(colorArray);
     const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
 
@@ -344,6 +350,7 @@ static SkiaShader* RadialGradient_postCreate1(JNIEnv* env, jobject o, SkShader*
 static SkiaShader* RadialGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
         float x, float y, float radius, int color0, int color1, int tileMode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     float* storedPositions = new float[2];
     storedPositions[0] = 0.0f;
     storedPositions[1] = 1.0f;
@@ -405,6 +412,7 @@ static SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y,
 static SkiaShader* SweepGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
         float x, float y, jintArray colorArray, jfloatArray posArray) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     size_t count = env->GetArrayLength(colorArray);
     const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
 
@@ -442,6 +450,7 @@ static SkiaShader* SweepGradient_postCreate1(JNIEnv* env, jobject o, SkShader* s
 static SkiaShader* SweepGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
         float x, float y, int color0, int color1) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     float* storedPositions = new float[2];
     storedPositions[0] = 0.0f;
     storedPositions[1] = 1.0f;
@@ -478,6 +487,7 @@ static SkShader* ComposeShader_create2(JNIEnv* env, jobject o,
 static SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
         SkiaShader* shaderA, SkiaShader* shaderB, SkPorterDuff::Mode porterDuffMode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     SkXfermode::Mode mode = SkPorterDuff::ToXfermodeMode(porterDuffMode);
     return new SkiaComposeShader(shaderA, shaderB, mode, shader);
 #else
@@ -488,6 +498,7 @@ static SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* s
 static SkiaShader* ComposeShader_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
         SkiaShader* shaderA, SkiaShader* shaderB, SkXfermode* mode) {
 #ifdef USE_OPENGL_RENDERER
+    if (!GraphicsJNI::useOpenglRenderer()) return NULL;
     SkXfermode::Mode skiaMode;
     if (!SkXfermode::IsMode(mode, &skiaMode)) {
         // TODO: Support other modes
index b87fe27..43b9818 100644 (file)
@@ -898,7 +898,7 @@ static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz
     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.
@@ -916,6 +916,7 @@ static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz
 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::DisplayList::outputLogBuffer(fd);
 #endif // USE_OPENGL_RENDERER
@@ -1084,8 +1085,10 @@ static JNINativeMethod gActivityThreadMethods[] = {
 
 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));
 }