Camera: Handle onBuffersDiscarded callback

Use onBuffersDiscarded callback from buffer queue to invalidate the
buffer caches in cameraserver process.

Test: Run testDiscardFreeBuffers, and use trace to profile memory
Bug: 136677409
Bug: 145617243
Change-Id: Ifac5e852e2a1ac50f5c3f2e047966c59eeb5f1ba
Merged-In: Ifac5e852e2a1ac50f5c3f2e047966c59eeb5f1ba
(cherry picked from commit 0160ddd149)
gugelfrei
Shuzhen Wang 5 years ago
parent 960bbfab7b
commit d65084c86d

@ -54,9 +54,8 @@ Camera3OutputStream::Camera3OutputStream(int id,
mState = STATE_ERROR; mState = STATE_ERROR;
} }
if (setId > CAMERA3_STREAM_SET_ID_INVALID) { bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
mBufferReleasedListener = new BufferReleasedListener(this); mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
}
} }
Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id,
@ -87,9 +86,8 @@ Camera3OutputStream::Camera3OutputStream(int id,
mState = STATE_ERROR; mState = STATE_ERROR;
} }
if (setId > CAMERA3_STREAM_SET_ID_INVALID) { bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
mBufferReleasedListener = new BufferReleasedListener(this); mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
}
} }
Camera3OutputStream::Camera3OutputStream(int id, Camera3OutputStream::Camera3OutputStream(int id,
@ -124,10 +122,8 @@ Camera3OutputStream::Camera3OutputStream(int id,
} }
mConsumerName = String8("Deferred"); mConsumerName = String8("Deferred");
if (setId > CAMERA3_STREAM_SET_ID_INVALID) { bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
mBufferReleasedListener = new BufferReleasedListener(this); mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
}
} }
Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type, Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
@ -151,9 +147,8 @@ Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
mDropBuffers(false), mDropBuffers(false),
mDequeueBufferLatency(kDequeueLatencyBinSize) { mDequeueBufferLatency(kDequeueLatencyBinSize) {
if (setId > CAMERA3_STREAM_SET_ID_INVALID) { bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
mBufferReleasedListener = new BufferReleasedListener(this); mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
}
// Subclasses expected to initialize mConsumer themselves // Subclasses expected to initialize mConsumer themselves
} }
@ -261,7 +256,7 @@ status_t Camera3OutputStream::returnBufferCheckedLocked(
notifyBufferReleased(anwBuffer); notifyBufferReleased(anwBuffer);
if (mUseBufferManager) { if (mUseBufferManager) {
// Return this buffer back to buffer manager. // Return this buffer back to buffer manager.
mBufferReleasedListener->onBufferReleased(); mBufferProducerListener->onBufferReleased();
} }
} else { } else {
if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) { if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) {
@ -387,8 +382,8 @@ status_t Camera3OutputStream::configureConsumerQueueLocked() {
// Configure consumer-side ANativeWindow interface. The listener may be used // Configure consumer-side ANativeWindow interface. The listener may be used
// to notify buffer manager (if it is used) of the returned buffers. // to notify buffer manager (if it is used) of the returned buffers.
res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA,
/*listener*/mBufferReleasedListener, /*reportBufferRemoval*/true,
/*reportBufferRemoval*/true); /*listener*/mBufferProducerListener);
if (res != OK) { if (res != OK) {
ALOGE("%s: Unable to connect to native window for stream %d", ALOGE("%s: Unable to connect to native window for stream %d",
__FUNCTION__, mId); __FUNCTION__, mId);
@ -790,7 +785,7 @@ status_t Camera3OutputStream::updateStream(const std::vector<sp<Surface>> &/*out
return INVALID_OPERATION; return INVALID_OPERATION;
} }
void Camera3OutputStream::BufferReleasedListener::onBufferReleased() { void Camera3OutputStream::BufferProducerListener::onBufferReleased() {
sp<Camera3OutputStream> stream = mParent.promote(); sp<Camera3OutputStream> stream = mParent.promote();
if (stream == nullptr) { if (stream == nullptr) {
ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__); ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
@ -823,6 +818,25 @@ void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
} }
} }
void Camera3OutputStream::BufferProducerListener::onBuffersDiscarded(
const std::vector<sp<GraphicBuffer>>& buffers) {
sp<Camera3OutputStream> stream = mParent.promote();
if (stream == nullptr) {
ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
return;
}
if (buffers.size() > 0) {
Mutex::Autolock l(stream->mLock);
stream->onBuffersRemovedLocked(buffers);
if (stream->mUseBufferManager) {
stream->mBufferManager->onBuffersRemoved(stream->getId(),
stream->getStreamSetId(), buffers.size());
}
ALOGV("Stream %d: %zu Buffers discarded.", stream->getId(), buffers.size());
}
}
void Camera3OutputStream::onBuffersRemovedLocked( void Camera3OutputStream::onBuffersRemovedLocked(
const std::vector<sp<GraphicBuffer>>& removedBuffers) { const std::vector<sp<GraphicBuffer>>& removedBuffers) {
sp<Camera3StreamBufferFreedListener> callback = mBufferFreedListener.promote(); sp<Camera3StreamBufferFreedListener> callback = mBufferFreedListener.promote();

@ -146,18 +146,22 @@ class Camera3OutputStream :
*/ */
virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers); virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
class BufferReleasedListener : public BnProducerListener { class BufferProducerListener : public SurfaceListener {
public: public:
BufferReleasedListener(wp<Camera3OutputStream> parent) : mParent(parent) {} BufferProducerListener(wp<Camera3OutputStream> parent, bool needsReleaseNotify)
: mParent(parent), mNeedsReleaseNotify(needsReleaseNotify) {}
/** /**
* Implementation of IProducerListener, used to notify this stream that the consumer * Implementation of IProducerListener, used to notify this stream that the consumer
* has returned a buffer and it is ready to return to Camera3BufferManager for reuse. * has returned a buffer and it is ready to return to Camera3BufferManager for reuse.
*/ */
virtual void onBufferReleased(); virtual void onBufferReleased();
virtual bool needsReleaseNotify() { return mNeedsReleaseNotify; }
virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers);
private: private:
wp<Camera3OutputStream> mParent; wp<Camera3OutputStream> mParent;
bool mNeedsReleaseNotify;
}; };
virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd); virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd);
@ -262,10 +266,10 @@ class Camera3OutputStream :
sp<Camera3BufferManager> mBufferManager; sp<Camera3BufferManager> mBufferManager;
/** /**
* Buffer released listener, used to notify the buffer manager that a buffer is released * Buffer producer listener, used to handle notification when a buffer is released
* from consumer side. * from consumer side, or a set of buffers are discarded by the consumer.
*/ */
sp<BufferReleasedListener> mBufferReleasedListener; sp<BufferProducerListener> mBufferProducerListener;
/** /**
* Flag indicating if the buffer manager is used to allocate the stream buffers * Flag indicating if the buffer manager is used to allocate the stream buffers

Loading…
Cancel
Save