diff options
| author | Jamie Gennis <jgennis@google.com> | 2010-11-11 15:26:21 -0800 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-11-11 15:26:21 -0800 |
| commit | 7ab17a3426d3565f72c6832bb650d1709cbf52cf (patch) | |
| tree | 90e188808e39d3447b880ca20cac6b2fad137921 /libs/surfaceflinger_client/SharedBufferStack.cpp | |
| parent | e1ccfb7f6e63f639988d9b50f060612f96c49c3f (diff) | |
| parent | 6c925d00e131e40811897e0ddc332d6f5bc83178 (diff) | |
| download | frameworks_base-7ab17a3426d3565f72c6832bb650d1709cbf52cf.zip frameworks_base-7ab17a3426d3565f72c6832bb650d1709cbf52cf.tar.gz frameworks_base-7ab17a3426d3565f72c6832bb650d1709cbf52cf.tar.bz2 | |
Merge "Implement reducing the buffer count of a Surface."
Diffstat (limited to 'libs/surfaceflinger_client/SharedBufferStack.cpp')
| -rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index 8f583f0..3b2ef84 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -265,6 +265,14 @@ bool SharedBufferClient::LockCondition::operator()() const { (stack.queued > 0 && stack.inUse != buf)); } +SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition( + SharedBufferServer* sbs, int numBuffers) : ConditionBase(sbs), + mNumBuffers(numBuffers) { +} +bool SharedBufferServer::BuffersAvailableCondition::operator()() const { + return stack.available == mNumBuffers; +} + // ---------------------------------------------------------------------------- SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb) @@ -448,6 +456,7 @@ status_t SharedBufferClient::queue(int buf) const nsecs_t now = systemTime(SYSTEM_TIME_THREAD); stack.stats.totalTime = ns2us(now - mDequeueTime[buf]); + return err; } @@ -492,6 +501,7 @@ status_t SharedBufferClient::setBufferCount( if (err == NO_ERROR) { mNumBuffers = bufferCount; queued_head = (stack.head + stack.queued) % mNumBuffers; + tail = computeTail(); } return err; } @@ -606,17 +616,24 @@ uint32_t SharedBufferServer::getTransform(int buf) const */ status_t SharedBufferServer::resize(int newNumBuffers) { - if (uint32_t(newNumBuffers) >= SharedBufferStack::NUM_BUFFER_MAX) + if ((unsigned int)(newNumBuffers) < SharedBufferStack::NUM_BUFFER_MIN || + (unsigned int)(newNumBuffers) > SharedBufferStack::NUM_BUFFER_MAX) { return BAD_VALUE; + } RWLock::AutoWLock _l(mLock); - // for now we're not supporting shrinking - const int numBuffers = mNumBuffers; - if (newNumBuffers < numBuffers) - return BAD_VALUE; + if (newNumBuffers < mNumBuffers) { + return shrink(newNumBuffers); + } else { + return grow(newNumBuffers); + } +} +status_t SharedBufferServer::grow(int newNumBuffers) +{ SharedBufferStack& stack( *mSharedStack ); + const int numBuffers = mNumBuffers; const int extra = newNumBuffers - numBuffers; // read the head, make sure it's valid @@ -650,6 +667,54 @@ status_t SharedBufferServer::resize(int newNumBuffers) return NO_ERROR; } +status_t SharedBufferServer::shrink(int newNumBuffers) +{ + SharedBufferStack& stack( *mSharedStack ); + + // Shrinking is only supported if there are no buffers currently dequeued. + int32_t avail = stack.available; + int32_t queued = stack.queued; + if (avail + queued != mNumBuffers) { + return INVALID_OPERATION; + } + + // Wait for any queued buffers to be displayed. + BuffersAvailableCondition condition(this, mNumBuffers); + status_t err = waitForCondition(condition); + if (err < 0) { + return err; + } + + // Reset head to index 0 and make it refer to buffer 0. The same renaming + // (head -> 0) is done in the BufferManager. + int32_t head = stack.head; + int8_t* index = const_cast<int8_t*>(stack.index); + for (int8_t i = 0; i < newNumBuffers; i++) { + index[i] = i; + } + stack.head = 0; + stack.headBuf = 0; + + // If one of the buffers is in use it must be the head buffer, which we are + // renaming to buffer 0. + if (stack.inUse > 0) { + stack.inUse = 0; + } + + // Free the buffers from the end of the list that are no longer needed. + for (int i = newNumBuffers; i < mNumBuffers; i++) { + mBufferList.remove(i); + } + + // Tell the client to reallocate all the buffers. + reallocateAll(); + + mNumBuffers = newNumBuffers; + stack.available = newNumBuffers; + + return NO_ERROR; +} + SharedBufferStack::Statistics SharedBufferServer::getStats() const { SharedBufferStack& stack( *mSharedStack ); |
