diff options
Diffstat (limited to 'core/jni')
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp | 125 | ||||
-rw-r--r-- | core/jni/android_os_Debug.cpp | 116 |
3 files changed, 156 insertions, 87 deletions
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index a17b301..490d85c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -53,6 +53,7 @@ extern int register_android_graphics_Bitmap(JNIEnv*); extern int register_android_graphics_BitmapFactory(JNIEnv*); extern int register_android_graphics_BitmapRegionDecoder(JNIEnv*); extern int register_android_graphics_Camera(JNIEnv* env); +extern int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env); extern int register_android_graphics_Graphics(JNIEnv* env); extern int register_android_graphics_Interpolator(JNIEnv* env); extern int register_android_graphics_LayerRasterizer(JNIEnv*); @@ -1137,6 +1138,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_BitmapFactory), REG_JNI(register_android_graphics_BitmapRegionDecoder), REG_JNI(register_android_graphics_Camera), + REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor), REG_JNI(register_android_graphics_Canvas), REG_JNI(register_android_graphics_ColorFilter), REG_JNI(register_android_graphics_DrawFilter), diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp index d264392..2d06b68 100644 --- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp +++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp @@ -7,12 +7,6 @@ #include "Utils.h" #include <androidfw/Asset.h> -#define RETURN_NULL_IF_NULL(value) \ - do { if (!(value)) { SkASSERT(0); return NULL; } } while (false) - -#define RETURN_ZERO_IF_NULL(value) \ - do { if (!(value)) { SkASSERT(0); return 0; } } while (false) - static jmethodID gInputStream_resetMethodID; static jmethodID gInputStream_markMethodID; static jmethodID gInputStream_markSupportedMethodID; @@ -161,32 +155,6 @@ private: SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream, jbyteArray storage) { - static bool gInited; - - if (!gInited) { - jclass inputStream_Clazz = env->FindClass("java/io/InputStream"); - RETURN_NULL_IF_NULL(inputStream_Clazz); - - gInputStream_resetMethodID = env->GetMethodID(inputStream_Clazz, - "reset", "()V"); - gInputStream_markMethodID = env->GetMethodID(inputStream_Clazz, - "mark", "(I)V"); - gInputStream_markSupportedMethodID = env->GetMethodID(inputStream_Clazz, - "markSupported", "()Z"); - gInputStream_readMethodID = env->GetMethodID(inputStream_Clazz, - "read", "([BII)I"); - gInputStream_skipMethodID = env->GetMethodID(inputStream_Clazz, - "skip", "(J)J"); - - RETURN_NULL_IF_NULL(gInputStream_resetMethodID); - RETURN_NULL_IF_NULL(gInputStream_markMethodID); - RETURN_NULL_IF_NULL(gInputStream_markSupportedMethodID); - RETURN_NULL_IF_NULL(gInputStream_readMethodID); - RETURN_NULL_IF_NULL(gInputStream_skipMethodID); - - gInited = true; - } - return new JavaInputStreamAdaptor(env, stream, storage); } @@ -263,27 +231,19 @@ private: const size_t fLength; }; +static jclass gByteArrayInputStream_Clazz; +static jfieldID gCountField; +static jfieldID gPosField; + /** * If jstream is a ByteArrayInputStream, return its remaining length. Otherwise * return 0. */ static size_t get_length_from_byte_array_stream(JNIEnv* env, jobject jstream) { - static jclass byteArrayInputStream_Clazz; - static jfieldID countField; - static jfieldID posField; - - byteArrayInputStream_Clazz = env->FindClass("java/io/ByteArrayInputStream"); - RETURN_ZERO_IF_NULL(byteArrayInputStream_Clazz); - - countField = env->GetFieldID(byteArrayInputStream_Clazz, "count", "I"); - RETURN_ZERO_IF_NULL(byteArrayInputStream_Clazz); - posField = env->GetFieldID(byteArrayInputStream_Clazz, "pos", "I"); - RETURN_ZERO_IF_NULL(byteArrayInputStream_Clazz); - - if (env->IsInstanceOf(jstream, byteArrayInputStream_Clazz)) { + if (env->IsInstanceOf(jstream, gByteArrayInputStream_Clazz)) { // Return the remaining length, to keep the same behavior of using the rest of the // stream. - return env->GetIntField(jstream, countField) - env->GetIntField(jstream, posField); + return env->GetIntField(jstream, gCountField) - env->GetIntField(jstream, gPosField); } return 0; } @@ -321,21 +281,15 @@ SkStreamRewindable* GetRewindableStream(JNIEnv* env, jobject stream, return adaptor_to_mem_stream(adaptor.get()); } -android::AssetStreamAdaptor* CheckForAssetStream(JNIEnv* env, jobject jstream) { - static jclass assetInputStream_Clazz; - static jmethodID getAssetIntMethodID; - - assetInputStream_Clazz = env->FindClass("android/content/res/AssetManager$AssetInputStream"); - RETURN_NULL_IF_NULL(assetInputStream_Clazz); - - getAssetIntMethodID = env->GetMethodID(assetInputStream_Clazz, "getAssetInt", "()I"); - RETURN_NULL_IF_NULL(getAssetIntMethodID); +static jclass gAssetInputStream_Clazz; +static jmethodID gGetAssetIntMethodID; - if (!env->IsInstanceOf(jstream, assetInputStream_Clazz)) { +android::AssetStreamAdaptor* CheckForAssetStream(JNIEnv* env, jobject jstream) { + if (!env->IsInstanceOf(jstream, gAssetInputStream_Clazz)) { return NULL; } - jint jasset = env->CallIntMethod(jstream, getAssetIntMethodID); + jint jasset = env->CallIntMethod(jstream, gGetAssetIntMethodID); android::Asset* a = reinterpret_cast<android::Asset*>(jasset); if (NULL == a) { jniThrowNullPointerException(env, "NULL native asset"); @@ -406,18 +360,57 @@ SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream, static bool gInited; if (!gInited) { - jclass outputStream_Clazz = env->FindClass("java/io/OutputStream"); - RETURN_NULL_IF_NULL(outputStream_Clazz); - - gOutputStream_writeMethodID = env->GetMethodID(outputStream_Clazz, - "write", "([BII)V"); - RETURN_NULL_IF_NULL(gOutputStream_writeMethodID); - gOutputStream_flushMethodID = env->GetMethodID(outputStream_Clazz, - "flush", "()V"); - RETURN_NULL_IF_NULL(gOutputStream_flushMethodID); gInited = true; } return new SkJavaOutputStream(env, stream, storage); } + +static jclass findClassCheck(JNIEnv* env, const char classname[]) { + jclass clazz = env->FindClass(classname); + SkASSERT(!env->ExceptionCheck()); + return clazz; +} + +static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz, + const char fieldname[], const char type[]) { + jfieldID id = env->GetFieldID(clazz, fieldname, type); + SkASSERT(!env->ExceptionCheck()); + return id; +} + +static jmethodID getMethodIDCheck(JNIEnv* env, jclass clazz, + const char methodname[], const char type[]) { + jmethodID id = env->GetMethodID(clazz, methodname, type); + SkASSERT(!env->ExceptionCheck()); + return id; +} + +int register_android_graphics_CreateJavaOutputStreamAdaptor(JNIEnv* env) { + jclass inputStream_Clazz = findClassCheck(env, "java/io/InputStream"); + gInputStream_resetMethodID = getMethodIDCheck(env, inputStream_Clazz, "reset", "()V"); + gInputStream_markMethodID = getMethodIDCheck(env, inputStream_Clazz, "mark", "(I)V"); + gInputStream_markSupportedMethodID = getMethodIDCheck(env, inputStream_Clazz, "markSupported", "()Z"); + gInputStream_readMethodID = getMethodIDCheck(env, inputStream_Clazz, "read", "([BII)I"); + gInputStream_skipMethodID = getMethodIDCheck(env, inputStream_Clazz, "skip", "(J)J"); + + gByteArrayInputStream_Clazz = findClassCheck(env, "java/io/ByteArrayInputStream"); + // Ref gByteArrayInputStream_Clazz so we can continue to refer to it when + // calling IsInstance. + gByteArrayInputStream_Clazz = (jclass) env->NewGlobalRef(gByteArrayInputStream_Clazz); + gCountField = getFieldIDCheck(env, gByteArrayInputStream_Clazz, "count", "I"); + gPosField = getFieldIDCheck(env, gByteArrayInputStream_Clazz, "pos", "I"); + + gAssetInputStream_Clazz = findClassCheck(env, "android/content/res/AssetManager$AssetInputStream"); + // Ref gAssetInputStream_Clazz so we can continue to refer to it when + // calling IsInstance. + gAssetInputStream_Clazz = (jclass) env->NewGlobalRef(gAssetInputStream_Clazz); + gGetAssetIntMethodID = getMethodIDCheck(env, gAssetInputStream_Clazz, "getAssetInt", "()I"); + + jclass outputStream_Clazz = findClassCheck(env, "java/io/OutputStream"); + gOutputStream_writeMethodID = getMethodIDCheck(env, outputStream_Clazz, "write", "([BII)V"); + gOutputStream_flushMethodID = getMethodIDCheck(env, outputStream_Clazz, "flush", "()V"); + + return 0; +} diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index f5eb389..dd07c4f 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -56,6 +56,7 @@ enum { HEAP_OAT, HEAP_ART, HEAP_UNKNOWN_MAP, + HEAP_GPU, HEAP_DALVIK_NORMAL, HEAP_DALVIK_LARGE, @@ -64,7 +65,7 @@ enum { HEAP_DALVIK_CODE_CACHE, _NUM_HEAP, - _NUM_EXCLUSIVE_HEAP = HEAP_UNKNOWN_MAP+1, + _NUM_EXCLUSIVE_HEAP = HEAP_GPU+1, _NUM_CORE_HEAP = HEAP_NATIVE+1 }; @@ -137,6 +138,72 @@ static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) #endif } +// XXX Qualcom-specific! +static jlong read_gpu_mem(int pid) +{ + char line[1024]; + jlong uss = 0; + unsigned temp; + + char tmp[128]; + FILE *fp; + + sprintf(tmp, "/d/kgsl/proc/%d/mem", pid); + fp = fopen(tmp, "r"); + if (fp == 0) { + //ALOGI("Unable to open: %s", tmp); + return 0; + } + + while (true) { + if (fgets(line, 1024, fp) == NULL) { + break; + } + + //ALOGI("Read: %s", line); + + // Format is: + // gpuaddr useraddr size id flags type usage sglen + // 54676000 54676000 4096 1 ----p gpumem arraybuffer 1 + // + // If useraddr is 0, this is gpu mem not otherwise accounted + // against the process. + + // Make sure line is long enough. + int i = 0; + while (i < 9) { + if (line[i] == 0) { + break; + } + i++; + } + if (i < 9) { + //ALOGI("Early line term!"); + continue; + } + + // Look to see if useraddr is 00000000. + while (i < 17) { + if (line[i] != '0') { + break; + } + i++; + } + if (i < 17) { + //ALOGI("useraddr not 0!"); + continue; + } + + uss += atoi(line + i); + //ALOGI("Uss now: %ld", uss); + } + + fclose(fp); + + // Convert from bytes to KB. + return uss / 1024; +} + static void read_mapinfo(FILE *fp, stats_t* stats) { char line[1024]; @@ -340,6 +407,10 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, load_maps(pid, stats); + jlong gpu = read_gpu_mem(pid); + stats[HEAP_GPU].pss += gpu; + stats[HEAP_GPU].privateDirty += gpu; + for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; @@ -394,34 +465,37 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jl char tmp[128]; FILE *fp; + pss = uss = read_gpu_mem(pid); + sprintf(tmp, "/proc/%d/smaps", pid); fp = fopen(tmp, "r"); - if (fp == 0) return 0; - while (true) { - if (fgets(line, 1024, fp) == NULL) { - break; - } + if (fp != 0) { + while (true) { + if (fgets(line, 1024, fp) == NULL) { + break; + } - if (line[0] == 'P') { - if (strncmp(line, "Pss:", 4) == 0) { - char* c = line + 4; - while (*c != 0 && (*c < '0' || *c > '9')) { - c++; - } - pss += atoi(c); - } else if (strncmp(line, "Private_Clean:", 14) - || strncmp(line, "Private_Dirty:", 14)) { - char* c = line + 14; - while (*c != 0 && (*c < '0' || *c > '9')) { - c++; + if (line[0] == 'P') { + if (strncmp(line, "Pss:", 4) == 0) { + char* c = line + 4; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + pss += atoi(c); + } else if (strncmp(line, "Private_Clean:", 14) + || strncmp(line, "Private_Dirty:", 14)) { + char* c = line + 14; + while (*c != 0 && (*c < '0' || *c > '9')) { + c++; + } + uss += atoi(c); } - uss += atoi(c); } } - } - fclose(fp); + fclose(fp); + } if (outUss != NULL) { if (env->GetArrayLength(outUss) >= 1) { |