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 10 static jclass gNIOAccess_classID; 11 static jmethodID gNIOAccess_getBasePointer; 12 static jmethodID gNIOAccess_getBaseArray; 13 static jmethodID gNIOAccess_getBaseArrayOffset; 14 static jmethodID gNIOAccess_getRemainingBytes; 15 16 void 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 44 NIOBuffer::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 53 NIOBuffer::~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 61 void 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 77 void* 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 128 void 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