mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-02 13:49:45 +00:00
Merge "Camera: fix release fence FD leaks" into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6e7ca4e166
@@ -341,7 +341,7 @@ void CameraDeviceSession::ResultBatcher::registerBatch(
|
|||||||
batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
|
batch->mLastFrame = batch->mFirstFrame + batch->mBatchSize - 1;
|
||||||
batch->mNumPartialResults = mNumPartialResults;
|
batch->mNumPartialResults = mNumPartialResults;
|
||||||
for (int id : mStreamsToBatch) {
|
for (int id : mStreamsToBatch) {
|
||||||
batch->mBatchBufs[id] = InflightBatch::BufferBatch();
|
batch->mBatchBufs.emplace(id, batch->mBatchSize);
|
||||||
}
|
}
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
mInflightBatches.push_back(batch);
|
mInflightBatches.push_back(batch);
|
||||||
@@ -418,6 +418,29 @@ void CameraDeviceSession::ResultBatcher::freeReleaseFences(hidl_vec<CaptureResul
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CameraDeviceSession::ResultBatcher::moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst) {
|
||||||
|
// Only dealing with releaseFence here. Assume buffer/acquireFence are null
|
||||||
|
const native_handle_t* handle = src.releaseFence.getNativeHandle();
|
||||||
|
src.releaseFence = nullptr;
|
||||||
|
dst = src;
|
||||||
|
dst.releaseFence = handle;
|
||||||
|
if (handle != dst.releaseFence.getNativeHandle()) {
|
||||||
|
ALOGE("%s: native handle cloned!", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraDeviceSession::ResultBatcher::pushStreamBuffer(
|
||||||
|
StreamBuffer&& src, std::vector<StreamBuffer>& dst) {
|
||||||
|
// Only dealing with releaseFence here. Assume buffer/acquireFence are null
|
||||||
|
const native_handle_t* handle = src.releaseFence.getNativeHandle();
|
||||||
|
src.releaseFence = nullptr;
|
||||||
|
dst.push_back(src);
|
||||||
|
dst.back().releaseFence = handle;
|
||||||
|
if (handle != dst.back().releaseFence.getNativeHandle()) {
|
||||||
|
ALOGE("%s: native handle cloned!", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
|
void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch) {
|
||||||
sendBatchBuffersLocked(batch, mStreamsToBatch);
|
sendBatchBuffersLocked(batch, mStreamsToBatch);
|
||||||
}
|
}
|
||||||
@@ -444,7 +467,12 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
|
|||||||
if (batchSize == 0) {
|
if (batchSize == 0) {
|
||||||
ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
|
ALOGW("%s: there is no buffer to be delivered for this batch.", __FUNCTION__);
|
||||||
for (int streamId : streams) {
|
for (int streamId : streams) {
|
||||||
InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
|
auto it = batch->mBatchBufs.find(streamId);
|
||||||
|
if (it == batch->mBatchBufs.end()) {
|
||||||
|
ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InflightBatch::BufferBatch& bb = it->second;
|
||||||
bb.mDelivered = true;
|
bb.mDelivered = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -460,21 +488,35 @@ void CameraDeviceSession::ResultBatcher::sendBatchBuffersLocked(
|
|||||||
results[i].inputBuffer.bufferId = 0;
|
results[i].inputBuffer.bufferId = 0;
|
||||||
results[i].inputBuffer.buffer = nullptr;
|
results[i].inputBuffer.buffer = nullptr;
|
||||||
std::vector<StreamBuffer> outBufs;
|
std::vector<StreamBuffer> outBufs;
|
||||||
|
outBufs.reserve(streams.size());
|
||||||
for (int streamId : streams) {
|
for (int streamId : streams) {
|
||||||
InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
|
auto it = batch->mBatchBufs.find(streamId);
|
||||||
|
if (it == batch->mBatchBufs.end()) {
|
||||||
|
ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InflightBatch::BufferBatch& bb = it->second;
|
||||||
if (bb.mDelivered) {
|
if (bb.mDelivered) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i < bb.mBuffers.size()) {
|
if (i < bb.mBuffers.size()) {
|
||||||
outBufs.push_back(bb.mBuffers[i]);
|
pushStreamBuffer(std::move(bb.mBuffers[i]), outBufs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results[i].outputBuffers = outBufs;
|
results[i].outputBuffers.resize(outBufs.size());
|
||||||
|
for (size_t j = 0; j < outBufs.size(); j++) {
|
||||||
|
moveStreamBuffer(std::move(outBufs[j]), results[i].outputBuffers[j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false);
|
invokeProcessCaptureResultCallback(results, /* tryWriteFmq */false);
|
||||||
freeReleaseFences(results);
|
freeReleaseFences(results);
|
||||||
for (int streamId : streams) {
|
for (int streamId : streams) {
|
||||||
InflightBatch::BufferBatch& bb = batch->mBatchBufs[streamId];
|
auto it = batch->mBatchBufs.find(streamId);
|
||||||
|
if (it == batch->mBatchBufs.end()) {
|
||||||
|
ALOGE("%s: cannot find stream %d in batched buffers!", __FUNCTION__, streamId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
InflightBatch::BufferBatch& bb = it->second;
|
||||||
bb.mDelivered = true;
|
bb.mDelivered = true;
|
||||||
bb.mBuffers.clear();
|
bb.mBuffers.clear();
|
||||||
}
|
}
|
||||||
@@ -613,7 +655,9 @@ void CameraDeviceSession::ResultBatcher::invokeProcessCaptureResultCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
|
void CameraDeviceSession::ResultBatcher::processOneCaptureResult(CaptureResult& result) {
|
||||||
hidl_vec<CaptureResult> results = {result};
|
hidl_vec<CaptureResult> results;
|
||||||
|
results.resize(1);
|
||||||
|
results[0] = std::move(result);
|
||||||
invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true);
|
invokeProcessCaptureResultCallback(results, /* tryWriteFmq */true);
|
||||||
freeReleaseFences(results);
|
freeReleaseFences(results);
|
||||||
return;
|
return;
|
||||||
@@ -650,10 +694,10 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res
|
|||||||
auto it = batch->mBatchBufs.find(buffer.streamId);
|
auto it = batch->mBatchBufs.find(buffer.streamId);
|
||||||
if (it != batch->mBatchBufs.end()) {
|
if (it != batch->mBatchBufs.end()) {
|
||||||
InflightBatch::BufferBatch& bb = it->second;
|
InflightBatch::BufferBatch& bb = it->second;
|
||||||
bb.mBuffers.push_back(buffer);
|
pushStreamBuffer(std::move(buffer), bb.mBuffers);
|
||||||
filledStreams.push_back(buffer.streamId);
|
filledStreams.push_back(buffer.streamId);
|
||||||
} else {
|
} else {
|
||||||
nonBatchedBuffers.push_back(buffer);
|
pushStreamBuffer(std::move(buffer), nonBatchedBuffers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,8 +706,12 @@ void CameraDeviceSession::ResultBatcher::processCaptureResult(CaptureResult& res
|
|||||||
CaptureResult nonBatchedResult;
|
CaptureResult nonBatchedResult;
|
||||||
nonBatchedResult.frameNumber = result.frameNumber;
|
nonBatchedResult.frameNumber = result.frameNumber;
|
||||||
nonBatchedResult.fmqResultSize = 0;
|
nonBatchedResult.fmqResultSize = 0;
|
||||||
nonBatchedResult.outputBuffers = nonBatchedBuffers;
|
nonBatchedResult.outputBuffers.resize(nonBatchedBuffers.size());
|
||||||
nonBatchedResult.inputBuffer = result.inputBuffer;
|
for (size_t i = 0; i < nonBatchedBuffers.size(); i++) {
|
||||||
|
moveStreamBuffer(
|
||||||
|
std::move(nonBatchedBuffers[i]), nonBatchedResult.outputBuffers[i]);
|
||||||
|
}
|
||||||
|
moveStreamBuffer(std::move(result.inputBuffer), nonBatchedResult.inputBuffer);
|
||||||
nonBatchedResult.partialResult = 0; // 0 for buffer only results
|
nonBatchedResult.partialResult = 0; // 0 for buffer only results
|
||||||
processOneCaptureResult(nonBatchedResult);
|
processOneCaptureResult(nonBatchedResult);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,9 @@ private:
|
|||||||
std::vector<NotifyMsg> mShutterMsgs;
|
std::vector<NotifyMsg> mShutterMsgs;
|
||||||
|
|
||||||
struct BufferBatch {
|
struct BufferBatch {
|
||||||
|
BufferBatch(uint32_t batchSize) {
|
||||||
|
mBuffers.reserve(batchSize);
|
||||||
|
}
|
||||||
bool mDelivered = false;
|
bool mDelivered = false;
|
||||||
// This currently assumes every batched request will output to the batched stream
|
// This currently assumes every batched request will output to the batched stream
|
||||||
// and since HAL must always send buffers in order, no frameNumber tracking is
|
// and since HAL must always send buffers in order, no frameNumber tracking is
|
||||||
@@ -241,6 +244,11 @@ private:
|
|||||||
void processOneCaptureResult(CaptureResult& result);
|
void processOneCaptureResult(CaptureResult& result);
|
||||||
void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
|
void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
|
||||||
|
|
||||||
|
// move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
|
||||||
|
// handle
|
||||||
|
void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
|
||||||
|
void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
|
||||||
|
|
||||||
// Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
|
// Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
|
||||||
// processCaptureRequest, processCaptureResult, notify will compete for this lock
|
// processCaptureRequest, processCaptureResult, notify will compete for this lock
|
||||||
// Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
|
// Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
|
||||||
|
|||||||
Reference in New Issue
Block a user