diff --git a/include/GrallocModule.h b/include/GrallocModule.h index b8b2a98..1f1d78d 100644 --- a/include/GrallocModule.h +++ b/include/GrallocModule.h @@ -34,7 +34,6 @@ #ifdef USE_GRALLOC1 #include -#include #endif class GrallocModule { @@ -129,8 +128,7 @@ class GrallocModule { int32_t fenceFd = -1; int error = m_gralloc1_unlock(m_gralloc1_device, handle, &fenceFd); if (!error) { - sync_wait(fenceFd, -1); - close(fenceFd); + ALOGVV("m_gralloc1_unlock failed"); } return error; } @@ -145,6 +143,42 @@ class GrallocModule { } } + int importBuffer(buffer_handle_t handle, buffer_handle_t *outBuffer) { + switch (m_major_version) { + case 1: +#ifdef USE_GRALLOC1 + { + return m_gralloc1_importbuffer(m_gralloc1_device, handle, outBuffer); + } +#endif + default: { + ALOGE( + "[Gralloc] no gralloc module to import; unknown gralloc major " + "version (%d)", + m_major_version); + return -1; + } + } + } + + int release(buffer_handle_t handle) { + switch (m_major_version) { + case 1: +#ifdef USE_GRALLOC1 + { + return m_gralloc1_release(m_gralloc1_device, handle); + } +#endif + default: { + ALOGE( + "[Gralloc] no gralloc module to release; unknown gralloc major " + "version (%d)", + m_major_version); + return -1; + } + } + } + private: GrallocModule() { mModule = nullptr; @@ -171,6 +205,10 @@ class GrallocModule { m_gralloc1_getNumFlexPlanes = (GRALLOC1_PFN_GET_NUM_FLEX_PLANES)m_gralloc1_device->getFunction( m_gralloc1_device, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES); + m_gralloc1_importbuffer = (GRALLOC1_PFN_IMPORT_BUFFER)m_gralloc1_device->getFunction( + m_gralloc1_device, GRALLOC1_FUNCTION_IMPORT_BUFFER); + m_gralloc1_release = (GRALLOC1_PFN_RELEASE)m_gralloc1_device->getFunction( + m_gralloc1_device, GRALLOC1_FUNCTION_RELEASE); break; #endif default: @@ -187,6 +225,8 @@ class GrallocModule { GRALLOC1_PFN_UNLOCK m_gralloc1_unlock = nullptr; GRALLOC1_PFN_LOCK_FLEX m_gralloc1_lockflex = nullptr; GRALLOC1_PFN_GET_NUM_FLEX_PLANES m_gralloc1_getNumFlexPlanes = nullptr; + GRALLOC1_PFN_IMPORT_BUFFER m_gralloc1_importbuffer = nullptr; + GRALLOC1_PFN_RELEASE m_gralloc1_release = nullptr; #endif }; diff --git a/include/fake-pipeline2/Base.h b/include/fake-pipeline2/Base.h index fd6396c..7675a7c 100644 --- a/include/fake-pipeline2/Base.h +++ b/include/fake-pipeline2/Base.h @@ -38,6 +38,7 @@ struct StreamBuffer { uint32_t dataSpace; uint32_t stride; buffer_handle_t *buffer; + native_handle_t *rawHandle; uint8_t *img; }; typedef Vector Buffers; diff --git a/src/VirtualFakeCamera3.cpp b/src/VirtualFakeCamera3.cpp index f5a01b5..631ca79 100644 --- a/src/VirtualFakeCamera3.cpp +++ b/src/VirtualFakeCamera3.cpp @@ -1033,6 +1033,7 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ // Process all the buffers we got for output, constructing internal buffer // structures for them, and lock them for writing. + buffer_handle_t outBuffer = nullptr; for (size_t i = 0; i < request->num_output_buffers; i++) { const camera3_stream_buffer &srcBuf = request->output_buffers[i]; StreamBuffer destBuf; @@ -1079,6 +1080,7 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ ALOGE("%s: Request %d: Buffer %zu: Fence timed out after %d ms", __FUNCTION__, frameNumber, i, kFenceTimeoutMs); } + destBuf.rawHandle = native_handle_clone(*(destBuf.buffer)); if (res == OK) { // Lock buffer for writing if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888 || @@ -1086,7 +1088,13 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ if (destBuf.format == HAL_PIXEL_FORMAT_YCbCr_420_888 || destBuf.format == HAL_PIXEL_FORMAT_YCrCb_420_SP) { android_ycbcr ycbcr = android_ycbcr(); - res = GrallocModule::getInstance().lock_ycbcr(*(destBuf.buffer), + + res = GrallocModule::getInstance().importBuffer(destBuf.rawHandle, &outBuffer); + if (res != OK) { + ALOGE("%s:%d Gralloc importBuffer failed",__FUNCTION__, __LINE__); + res = INVALID_OPERATION; + } else { + res = GrallocModule::getInstance().lock_ycbcr(destBuf.rawHandle, #ifdef USE_GRALLOC1 GRALLOC1_PRODUCER_USAGE_CPU_WRITE, #else @@ -1094,13 +1102,19 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ #endif 0, 0, destBuf.width, destBuf.height, &ycbcr); - destBuf.img = static_cast(ycbcr.y); + destBuf.img = static_cast(ycbcr.y); + } } else { ALOGE("Unexpected private format for flexible YUV: 0x%x", destBuf.format); res = INVALID_OPERATION; } } else { - res = GrallocModule::getInstance().lock(*(destBuf.buffer), + res = GrallocModule::getInstance().importBuffer(destBuf.rawHandle, &outBuffer); + if (res != OK) { + ALOGE("%s:%d Gralloc importBuffer failed",__FUNCTION__, __LINE__); + res = INVALID_OPERATION; + } else { + res = GrallocModule::getInstance().lock(destBuf.rawHandle, #ifdef USE_GRALLOC1 GRALLOC1_PRODUCER_USAGE_CPU_WRITE, #else @@ -1108,6 +1122,7 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ #endif 0, 0, destBuf.width, destBuf.height, (void **)&(destBuf.img)); + } } if (res != OK) { ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer", __FUNCTION__, @@ -1122,8 +1137,10 @@ status_t VirtualFakeCamera3::processCaptureRequest(camera3_capture_request *requ if (res != OK) { // Either waiting or locking failed. Unlock locked buffers and bail // out. - for (size_t j = 0; j < i; j++) { - GrallocModule::getInstance().unlock(*(request->output_buffers[i].buffer)); + for (size_t j = 0; j < sensorBuffers->size(); j++) { + const StreamBuffer &b = (*sensorBuffers)[j]; + GrallocModule::getInstance().unlock(b.rawHandle); + GrallocModule::getInstance().release(b.rawHandle); } delete sensorBuffers; delete buffers; @@ -2720,7 +2737,6 @@ bool VirtualFakeCamera3::ReadoutThread::threadLoop() { res); // fallthrough for cleanup } - GrallocModule::getInstance().unlock(*(buf->buffer)); buf->status = goodBuffer ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR; buf->acquire_fence = -1; @@ -2775,6 +2791,13 @@ bool VirtualFakeCamera3::ReadoutThread::threadLoop() { // Send it off to the framework ALOGVV("%s: ReadoutThread: Send result to framework", __FUNCTION__); + if (mCurrentRequest.sensorBuffers != NULL) { + for (int i = 0; i < mCurrentRequest.sensorBuffers->size(); i++) { + const StreamBuffer &b = (*mCurrentRequest.sensorBuffers)[i]; + GrallocModule::getInstance().unlock(b.rawHandle); + GrallocModule::getInstance().release(b.rawHandle); + } + } mParent->sendCaptureResult(&result); // Clean up @@ -2794,7 +2817,8 @@ bool VirtualFakeCamera3::ReadoutThread::threadLoop() { void VirtualFakeCamera3::ReadoutThread::onJpegDone(const StreamBuffer &jpegBuffer, bool success) { Mutex::Autolock jl(mJpegLock); - GrallocModule::getInstance().unlock(*(jpegBuffer.buffer)); + GrallocModule::getInstance().unlock(jpegBuffer.rawHandle); + GrallocModule::getInstance().release(jpegBuffer.rawHandle); mJpegHalBuffer.status = success ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR; mJpegHalBuffer.acquire_fence = -1;