cleanup. waitForCondition() now uses polymorphsim instead of templtes
the reason for the above change is that waitForCondition() had become
large over time, mainly to handle error cases, using inlines to
evaluate the condition doesn't buys us much anymore while it increases
code size.
Change-Id: I2595d850832628954b900ab8bb1796c863447bc7
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 6745704..21a40db 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -195,6 +195,42 @@
return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
}
+status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
+{
+ const SharedBufferStack& stack( *mSharedStack );
+ SharedClient& client( *mSharedClient );
+ const nsecs_t TIMEOUT = s2ns(1);
+ const int identity = mIdentity;
+
+ Mutex::Autolock _l(client.lock);
+ while ((condition()==false) &&
+ (stack.identity == identity) &&
+ (stack.status == NO_ERROR))
+ {
+ status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
+ // handle errors and timeouts
+ if (CC_UNLIKELY(err != NO_ERROR)) {
+ if (err == TIMED_OUT) {
+ if (condition()) {
+ LOGE("waitForCondition(%s) timed out (identity=%d), "
+ "but condition is true! We recovered but it "
+ "shouldn't happen." , condition.name(), stack.identity);
+ break;
+ } else {
+ LOGW("waitForCondition(%s) timed out "
+ "(identity=%d, status=%d). "
+ "CPU may be pegged. trying again.", condition.name(),
+ stack.identity, stack.status);
+ }
+ } else {
+ LOGE("waitForCondition(%s) error (%s) ",
+ condition.name(), strerror(-err));
+ return err;
+ }
+ }
+ }
+ return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
+}
// ============================================================================
// conditions and updates
// ============================================================================
@@ -202,14 +238,14 @@
SharedBufferClient::DequeueCondition::DequeueCondition(
SharedBufferClient* sbc) : ConditionBase(sbc) {
}
-bool SharedBufferClient::DequeueCondition::operator()() {
+bool SharedBufferClient::DequeueCondition::operator()() const {
return stack.available > 0;
}
SharedBufferClient::LockCondition::LockCondition(
SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) {
}
-bool SharedBufferClient::LockCondition::operator()() {
+bool SharedBufferClient::LockCondition::operator()() const {
return (buf != stack.head ||
(stack.queued > 0 && stack.inUse != buf));
}
@@ -217,7 +253,7 @@
SharedBufferServer::ReallocateCondition::ReallocateCondition(
SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) {
}
-bool SharedBufferServer::ReallocateCondition::operator()() {
+bool SharedBufferServer::ReallocateCondition::operator()() const {
// TODO: we should also check that buf has been dequeued
return (buf != stack.head);
}
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 057d211..eee4dae 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -463,18 +463,6 @@
// ----------------------------------------------------------------------------
-status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
- android_native_buffer_t* out;
- status_t err = dequeueBuffer(&out);
- if (err == NO_ERROR) {
- *buffer = GraphicBuffer::getSelf(out);
- }
- return err;
-}
-
-// ----------------------------------------------------------------------------
-
-
int Surface::dequeueBuffer(android_native_buffer_t** buffer)
{
sp<SurfaceComposerClient> client(getClient());
@@ -530,7 +518,7 @@
if (err != NO_ERROR)
return err;
- int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+ int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
err = mSharedBufferClient->lock(bufIdx);
LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
return err;
@@ -547,7 +535,7 @@
mDirtyRegion.set(mSwapRectangle);
}
- int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+ int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
err = mSharedBufferClient->queue(bufIdx);
@@ -722,13 +710,14 @@
// we're intending to do software rendering from this point
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
- sp<GraphicBuffer> backBuffer;
- status_t err = dequeueBuffer(&backBuffer);
+ android_native_buffer_t* out;
+ status_t err = dequeueBuffer(&out);
LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
if (err == NO_ERROR) {
+ sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
err = lockBuffer(backBuffer.get());
LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
- backBuffer->getIndex(), strerror(-err));
+ getBufferIndex(backBuffer), strerror(-err));
if (err == NO_ERROR) {
const Rect bounds(backBuffer->width, backBuffer->height);
const Region boundsRegion(bounds);
@@ -797,7 +786,7 @@
err = queueBuffer(mLockedBuffer.get());
LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
- mLockedBuffer->getIndex(), strerror(-err));
+ getBufferIndex(mLockedBuffer), strerror(-err));
mPostedBuffer = mLockedBuffer;
mLockedBuffer = 0;
@@ -809,6 +798,11 @@
mSwapRectangle = r;
}
+int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
+{
+ return buffer->getIndex();
+}
+
status_t Surface::getBufferLocked(int index, int usage)
{
sp<ISurface> s(mSurface);