diff options
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 92125ead1f..21a7f7817a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -565,11 +565,13 @@ public: return NO_ERROR; } - uint64_t cache(const sp<GraphicBuffer>& buffer) { + uint64_t cache(const sp<GraphicBuffer>& buffer, + std::optional<client_cache_t>& outUncacheBuffer) { std::lock_guard<std::mutex> lock(mMutex); if (mBuffers.size() >= BUFFER_CACHE_MAX_SIZE) { - evictLeastRecentlyUsedBuffer(); + outUncacheBuffer = findLeastRecentlyUsedBuffer(); + mBuffers.erase(outUncacheBuffer->id); } buffer->addDeathCallback(removeDeadBufferCallback, nullptr); @@ -580,16 +582,13 @@ public: void uncache(uint64_t cacheId) { std::lock_guard<std::mutex> lock(mMutex); - uncacheLocked(cacheId); - } - - void uncacheLocked(uint64_t cacheId) REQUIRES(mMutex) { - mBuffers.erase(cacheId); - SurfaceComposerClient::doUncacheBufferTransaction(cacheId); + if (mBuffers.erase(cacheId)) { + SurfaceComposerClient::doUncacheBufferTransaction(cacheId); + } } private: - void evictLeastRecentlyUsedBuffer() REQUIRES(mMutex) { + client_cache_t findLeastRecentlyUsedBuffer() REQUIRES(mMutex) { auto itr = mBuffers.begin(); uint64_t minCounter = itr->second; auto minBuffer = itr; @@ -603,7 +602,8 @@ private: } itr++; } - uncacheLocked(minBuffer->first); + + return {.token = getToken(), .id = minBuffer->first}; } uint64_t getCounter() REQUIRES(mMutex) { @@ -741,6 +741,18 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel InputWindowCommands inputWindowCommands; inputWindowCommands.read(*parcel); + count = static_cast<size_t>(parcel->readUint32()); + if (count > parcel->dataSize()) { + return BAD_VALUE; + } + std::vector<client_cache_t> uncacheBuffers(count); + for (size_t i = 0; i < count; i++) { + sp<IBinder> tmpBinder; + SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder); + uncacheBuffers[i].token = tmpBinder; + SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id); + } + // Parsing was successful. Update the object. mId = transactionId; mTransactionNestCount = transactionNestCount; @@ -755,6 +767,7 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel mComposerStates = composerStates; mInputWindowCommands = inputWindowCommands; mApplyToken = applyToken; + mUncacheBuffers = std::move(uncacheBuffers); return NO_ERROR; } @@ -806,6 +819,13 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const } mInputWindowCommands.write(*parcel); + + SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size())); + for (const client_cache_t& uncacheBuffer : mUncacheBuffers) { + SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote()); + SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id); + } + return NO_ERROR; } @@ -873,6 +893,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr } } + for (const auto& cacheId : other.mUncacheBuffers) { + mUncacheBuffers.push_back(cacheId); + } + mInputWindowCommands.merge(other.mInputWindowCommands); mMayContainBuffer |= other.mMayContainBuffer; @@ -891,6 +915,7 @@ void SurfaceComposerClient::Transaction::clear() { mDisplayStates.clear(); mListenerCallbacks.clear(); mInputWindowCommands.clear(); + mUncacheBuffers.clear(); mMayContainBuffer = false; mTransactionNestCount = 0; mAnimation = false; @@ -913,10 +938,10 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { uncacheBuffer.token = BufferCache::getInstance().getToken(); uncacheBuffer.id = cacheId; Vector<ComposerState> composerStates; - status_t status = - sf->setTransactionState(FrameTimelineInfo{}, composerStates, {}, - ISurfaceComposer::eOneWay, Transaction::getDefaultApplyToken(), - {}, systemTime(), true, uncacheBuffer, false, {}, generateId()); + status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, {}, + ISurfaceComposer::eOneWay, + Transaction::getDefaultApplyToken(), {}, systemTime(), + true, {uncacheBuffer}, false, {}, generateId()); if (status != NO_ERROR) { ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s", strerror(-status)); @@ -954,7 +979,11 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { s->bufferData->buffer = nullptr; } else { // Cache-miss. Include the buffer and send the new cacheId. - cacheId = BufferCache::getInstance().cache(s->bufferData->buffer); + std::optional<client_cache_t> uncacheBuffer; + cacheId = BufferCache::getInstance().cache(s->bufferData->buffer, uncacheBuffer); + if (uncacheBuffer) { + mUncacheBuffers.push_back(*uncacheBuffer); + } } s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged; s->bufferData->cachedBuffer.token = BufferCache::getInstance().getToken(); @@ -1087,8 +1116,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay sp<ISurfaceComposer> sf(ComposerService::getComposerService()); sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, - {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/, - hasListenerCallbacks, listenerCallbacks, mId); + mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId); mId = generateId(); // Clear the current states and flags |