static void Image_unlockIfLocked(JNIEnv* env, jobject thiz) { ALOGV("%s", __FUNCTION__); GraphicBuffer* buffer; Image_getNativeContext(env, thiz, &buffer, NULL); if (buffer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Image is not initialized"); return; } // Is locked? bool isLocked = false; jobject planes = NULL; if (!isFormatOpaque(buffer->getPixelFormat())) { planes = env->GetObjectField(thiz, gSurfaceImageClassInfo.mPlanes); } isLocked = (planes != NULL); if (isLocked) { // no need to use fence here, as we it will be consumed by either cancel or queue buffer. status_t res = buffer->unlock(); if (res != OK) { jniThrowRuntimeException(env, "unlock buffer failed"); } ALOGV("Successfully unlocked the image"); } }
static jint Image_getFormat(JNIEnv* env, jobject thiz) { ALOGV("%s", __FUNCTION__); GraphicBuffer* buffer; Image_getNativeContext(env, thiz, &buffer, NULL); if (buffer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Image is not initialized"); return 0; } return Image_getPixelFormat(env, buffer->getPixelFormat()); }
sp<CameraBuffer> allocateGraphicBuffer(int w, int h, int gfxFmt, int cameraId, int usage) { LOG1("@%s", __FUNCTION__); UNUSED(usage); status_t status = OK; void * mapperPointer = NULL; int lockMode = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_NEVER | GRALLOC_USAGE_HW_CAMERA_READ | GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_COMPOSER; LOG1("%s with these properties: (%dx%d) gfx format %d", __FUNCTION__, w, h, gfxFmt); GraphicBuffer *gfxBuffer = new GraphicBuffer (w, h, gfxFmt, GraphicBuffer::USAGE_HW_RENDER | GraphicBuffer::USAGE_SW_WRITE_OFTEN | \ GraphicBuffer::USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE); if (!gfxBuffer) { LOGE("No memory to allocate graphic buffer"); return NULL; } ANativeWindowBuffer *nativeWinBuffer = gfxBuffer->getNativeBuffer(); status = gfxBuffer->lock(lockMode, &mapperPointer); if (status != NO_ERROR) { LOGE("@%s: Failed to lock GraphicBuffer! %d", __FUNCTION__, status); return NULL; } if (w != nativeWinBuffer->stride) { LOG1("%s: potential bpl problem requested %d, Gfx requries %d", __FUNCTION__, w, nativeWinBuffer->stride); } else { LOG1("%s bpl from Gfx is %d", __FUNCTION__, nativeWinBuffer->stride); } CameraBuffer * buf = new CameraBuffer(w, h, nativeWinBuffer->stride, gfxFmt, gfxBuffer, mapperPointer, cameraId); gfxBuffer->incStrong(buf); return buf; }
static void Image_setNativeContext(JNIEnv* env, jobject thiz, sp<GraphicBuffer> buffer, int fenceFd) { ALOGV("%s:", __FUNCTION__); GraphicBuffer* p = NULL; Image_getNativeContext(env, thiz, &p, /*fenceFd*/NULL); if (buffer != 0) { buffer->incStrong((void*)Image_setNativeContext); } if (p) { p->decStrong((void*)Image_setNativeContext); } env->SetLongField(thiz, gSurfaceImageClassInfo.mNativeBuffer, reinterpret_cast<jlong>(buffer.get())); env->SetIntField(thiz, gSurfaceImageClassInfo.mNativeFenceFd, reinterpret_cast<jint>(fenceFd)); }
static void Image_getLockedImage(JNIEnv* env, jobject thiz, LockedImage *image) { ALOGV("%s", __FUNCTION__); GraphicBuffer* buffer; int fenceFd = -1; Image_getNativeContext(env, thiz, &buffer, &fenceFd); if (buffer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Image is not initialized"); return; } void* pData = NULL; android_ycbcr ycbcr = android_ycbcr(); status_t res; int format = Image_getFormat(env, thiz); int flexFormat = format; if (isPossiblyYUV(format)) { // ImageWriter doesn't use crop by itself, app sets it, use the no crop version. res = buffer->lockAsyncYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr, fenceFd); // Clear the fenceFd as it is already consumed by lock call. Image_setFenceFd(env, thiz, /*fenceFd*/-1); if (res != OK) { jniThrowRuntimeException(env, "lockAsyncYCbCr failed for YUV buffer"); return; } pData = ycbcr.y; flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; } // lockAsyncYCbCr for YUV is unsuccessful. if (pData == NULL) { res = buffer->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, &pData, fenceFd); if (res != OK) { jniThrowRuntimeException(env, "lockAsync failed"); return; } } image->data = reinterpret_cast<uint8_t*>(pData); image->width = buffer->getWidth(); image->height = buffer->getHeight(); image->format = format; image->flexFormat = flexFormat; image->stride = (ycbcr.y != NULL) ? static_cast<uint32_t>(ycbcr.ystride) : buffer->getStride(); image->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb); image->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr); image->chromaStride = static_cast<uint32_t>(ycbcr.cstride); image->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step); ALOGV("Successfully locked the image"); // crop, transform, scalingMode, timestamp, and frameNumber should be set by producer, // and we don't set them here. }
static GraphicBuffer* create_composible_buffer(int width, int height) { uint32_t bufferFlags = GraphicBuffer::USAGE_SW_WRITE_RARELY | GraphicBuffer::USAGE_HW_COMPOSER; GraphicBuffer* buffer = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, bufferFlags); status_t err = buffer->initCheck(); if (err) { LOGE("error creating GraphicBuffer: %s", strerror(-err)); return NULL; } Rect rect = buffer->getBounds(); LOGE("GraphicBuffer information"); LOGE("width : %d", buffer->getWidth()); LOGE("height: %d", buffer->getHeight()); LOGE("stride: %d", buffer->getStride()); LOGE("usage : 0x%08x", buffer->getUsage()); LOGE("format: %d", buffer->getPixelFormat()); LOGE("bounds: (%d,%d) - (%d,%d)", rect.left, rect.top, rect.right, rect.bottom); return buffer; }
static jlong android_hardware_HardwareBuffer_getUsage(JNIEnv* env, jobject clazz, jlong nativeObject) { GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject); return AHardwareBuffer_convertFromGrallocUsageBits(buffer->getUsage()); }
static jint android_hardware_HardwareBuffer_getLayers(JNIEnv* env, jobject clazz, jlong nativeObject) { GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject); return static_cast<jint>(buffer->getLayerCount()); }
static jint android_hardware_HardwareBuffer_getFormat(JNIEnv* env, jobject clazz, jlong nativeObject) { GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject); return static_cast<jint>(android_hardware_HardwareBuffer_convertFromPixelFormat( buffer->getPixelFormat())); }