1#include "NIOBuffer.h" 2#include "GraphicsJNI.h" 3 4// enable this to dump each time we ref/unref a global java object (buffer) 5// 6//#define TRACE_GLOBAL_REFS 7 8//#define TRACE_ARRAY_LOCKS 9 10static jclass gNIOAccess_classID; 11static jmethodID gNIOAccess_getBasePointer; 12static jmethodID gNIOAccess_getBaseArray; 13static jmethodID gNIOAccess_getBaseArrayOffset; 14static jmethodID gNIOAccess_getRemainingBytes; 15 16void NIOBuffer::RegisterJNI(JNIEnv* env) { 17 if (0 != gNIOAccess_classID) { 18 return; // already called 19 } 20 21 jclass c = env->FindClass("java/nio/NIOAccess"); 22 gNIOAccess_classID = (jclass)env->NewGlobalRef(c); 23 24 gNIOAccess_getBasePointer = env->GetStaticMethodID(gNIOAccess_classID, 25 "getBasePointer", "(Ljava/nio/Buffer;)J"); 26 gNIOAccess_getBaseArray = env->GetStaticMethodID(gNIOAccess_classID, 27 "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;"); 28 gNIOAccess_getBaseArrayOffset = env->GetStaticMethodID(gNIOAccess_classID, 29 "getBaseArrayOffset", "(Ljava/nio/Buffer;)I"); 30 gNIOAccess_getRemainingBytes = env->GetStaticMethodID(gNIOAccess_classID, 31 "getRemainingBytes", "(Ljava/nio/Buffer;)I"); 32} 33 34/////////////////////////////////////////////////////////////////////////////// 35 36#ifdef TRACE_GLOBAL_REFS 37 static int gGlobalRefs; 38#endif 39 40#ifdef TRACE_ARRAY_LOCKS 41 static int gLockCount; 42#endif 43 44NIOBuffer::NIOBuffer(JNIEnv* env, jobject buffer) { 45 fBuffer = env->NewGlobalRef(buffer); 46#ifdef TRACE_GLOBAL_REFS 47 SkDebugf("------------ newglobalref bbuffer %X %d\n", buffer, gGlobalRefs++); 48#endif 49 fLockedPtr = NULL; 50 fLockedArray = NULL; 51} 52 53NIOBuffer::~NIOBuffer() { 54 // free() needs to have already been called 55 if (NULL != fBuffer) { 56 SkDebugf("----- leaked fBuffer in NIOBuffer"); 57 sk_throw(); 58 } 59} 60 61void NIOBuffer::free(JNIEnv* env) { 62 63 if (NULL != fLockedPtr) { 64 SkDebugf("======= free: array still locked %x %p\n", fLockedArray, fLockedPtr); 65 } 66 67 68 if (NULL != fBuffer) { 69#ifdef TRACE_GLOBAL_REFS 70 SkDebugf("----------- deleteglobalref buffer %X %d\n", fBuffer, --gGlobalRefs); 71#endif 72 env->DeleteGlobalRef(fBuffer); 73 fBuffer = NULL; 74 } 75} 76 77void* NIOBuffer::lock(JNIEnv* env, int* remaining) { 78 if (NULL != fLockedPtr) { 79 SkDebugf("======= lock: array still locked %x %p\n", fLockedArray, fLockedPtr); 80 } 81 82 fLockedPtr = NULL; 83 fLockedArray = NULL; 84 85 if (NULL != remaining) { 86 *remaining = env->CallStaticIntMethod(gNIOAccess_classID, 87 gNIOAccess_getRemainingBytes, 88 fBuffer); 89 if (GraphicsJNI::hasException(env)) { 90 return NULL; 91 } 92 } 93 94 jlong pointer = env->CallStaticLongMethod(gNIOAccess_classID, 95 gNIOAccess_getBasePointer, 96 fBuffer); 97 if (GraphicsJNI::hasException(env)) { 98 return NULL; 99 } 100 if (0 != pointer) { 101 return reinterpret_cast<void*>(pointer); 102 } 103 104 fLockedArray = (jbyteArray)env->CallStaticObjectMethod(gNIOAccess_classID, 105 gNIOAccess_getBaseArray, 106 fBuffer); 107 if (GraphicsJNI::hasException(env) || NULL == fLockedArray) { 108 return NULL; 109 } 110 jint offset = env->CallStaticIntMethod(gNIOAccess_classID, 111 gNIOAccess_getBaseArrayOffset, 112 fBuffer); 113 fLockedPtr = env->GetByteArrayElements(fLockedArray, NULL); 114 if (GraphicsJNI::hasException(env)) { 115 SkDebugf("------------ failed to lockarray %x\n", fLockedArray); 116 return NULL; 117 } 118#ifdef TRACE_ARRAY_LOCKS 119 SkDebugf("------------ lockarray %x %p %d\n", 120 fLockedArray, fLockedPtr, gLockCount++); 121#endif 122 if (NULL == fLockedPtr) { 123 offset = 0; 124 } 125 return (char*)fLockedPtr + offset; 126} 127 128void NIOBuffer::unlock(JNIEnv* env, bool dataChanged) { 129 if (NULL != fLockedPtr) { 130#ifdef TRACE_ARRAY_LOCKS 131 SkDebugf("------------ unlockarray %x %p %d\n", 132 fLockedArray, fLockedPtr, --gLockCount); 133#endif 134 env->ReleaseByteArrayElements(fLockedArray, (jbyte*)fLockedPtr, 135 dataChanged ? 0 : JNI_ABORT); 136 137 fLockedPtr = NULL; 138 fLockedArray = NULL; 139 } else { 140 SkDebugf("============= unlock called with null ptr %x\n", fLockedArray); 141 } 142} 143 144