Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gralloc4 support #25

Open
wants to merge 1 commit into
base: r/ics3a/main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions include/GrallocModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

#ifdef USE_GRALLOC1
#include <hardware/gralloc1.h>
#include <sync/sync.h>
#endif

class GrallocModule {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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:
Expand All @@ -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
};

Expand Down
1 change: 1 addition & 0 deletions include/fake-pipeline2/Base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<StreamBuffer> Buffers;
Expand Down
38 changes: 31 additions & 7 deletions src/VirtualFakeCamera3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1079,35 +1080,49 @@ 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));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we call native_handle_clone, but we didn't release the handle, will there be memory leak?

if (res == OK) {
// Lock buffer for writing
if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888 ||
srcBuf.stream->format == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
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
GRALLOC_USAGE_HW_CAMERA_WRITE,
#endif
0, 0, destBuf.width,
destBuf.height, &ycbcr);
destBuf.img = static_cast<uint8_t *>(ycbcr.y);
destBuf.img = static_cast<uint8_t *>(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
GRALLOC_USAGE_HW_CAMERA_WRITE,
#endif
0, 0, destBuf.width, destBuf.height,
(void **)&(destBuf.img));
}
}
if (res != OK) {
ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer", __FUNCTION__,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down