diff options
Diffstat (limited to 'libs/surfaceflinger_client')
-rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 42 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 30 |
2 files changed, 51 insertions, 21 deletions
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 @@ int32_t SharedBufferBase::computeTail() const 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 @@ int32_t SharedBufferBase::computeTail() const 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 @@ bool SharedBufferClient::LockCondition::operator()() { 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 @@ int Surface::perform(android_native_window_t* window, // ---------------------------------------------------------------------------- -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 @@ int Surface::lockBuffer(android_native_buffer_t* buffer) 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 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) 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 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) // 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 @@ status_t Surface::unlockAndPost() 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 @@ void Surface::setSwapRectangle(const Rect& r) { 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); |