diff options
author | 2022-08-16 19:08:21 +0000 | |
---|---|---|
committer | 2022-08-16 19:08:21 +0000 | |
commit | 44732cde9e19a005def5e110140963a5c2e2f5ae (patch) | |
tree | 9a4deff758bed03ccc5ff838dc55f467c303d762 /libs/gui/SurfaceComposerClient.cpp | |
parent | 896cdca96956b6f14e262380b34a0b04e1214b50 (diff) | |
parent | 91192c8103e78895c57d9da1fc04c8695898580f (diff) |
Merge "DO NOT MERGE - Merge Android 13"
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 511 |
1 files changed, 392 insertions, 119 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 4bcc9d56c8..47d801a78d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> +#include <android/gui/DisplayState.h> #include <android/gui/IWindowInfosListener.h> #include <utils/Errors.h> #include <utils/Log.h> @@ -43,16 +44,20 @@ #include <gui/WindowInfo.h> #include <private/gui/ParcelUtils.h> #include <ui/DisplayMode.h> +#include <ui/DisplayState.h> #include <ui/DynamicDisplayInfo.h> #include <private/gui/ComposerService.h> +#include <private/gui/ComposerServiceAIDL.h> // This server size should always be smaller than the server cache size #define BUFFER_CACHE_MAX_SIZE 64 namespace android { +using aidl::android::hardware::graphics::common::DisplayDecorationSupport; using gui::FocusRequest; +using gui::IRegionSamplingListener; using gui::WindowInfo; using gui::WindowInfoHandle; using gui::WindowInfosListener; @@ -60,6 +65,15 @@ using ui::ColorMode; // --------------------------------------------------------------------------- ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); +ANDROID_SINGLETON_STATIC_INSTANCE(ComposerServiceAIDL); + +namespace { +// Initialize transaction id counter used to generate transaction ids +std::atomic<uint32_t> idCounter = 0; +int64_t generateId() { + return (((int64_t)getpid()) << 32) | ++idCounter; +} +} // namespace ComposerService::ComposerService() : Singleton<ComposerService>() { @@ -110,6 +124,52 @@ void ComposerService::composerServiceDied() mDeathObserver = nullptr; } +ComposerServiceAIDL::ComposerServiceAIDL() : Singleton<ComposerServiceAIDL>() { + std::scoped_lock lock(mMutex); + connectLocked(); +} + +bool ComposerServiceAIDL::connectLocked() { + const String16 name("SurfaceFlingerAIDL"); + mComposerService = waitForService<gui::ISurfaceComposer>(name); + if (mComposerService == nullptr) { + return false; // fatal error or permission problem + } + + // Create the death listener. + class DeathObserver : public IBinder::DeathRecipient { + ComposerServiceAIDL& mComposerService; + virtual void binderDied(const wp<IBinder>& who) { + ALOGW("ComposerService aidl remote (surfaceflinger) died [%p]", who.unsafe_get()); + mComposerService.composerServiceDied(); + } + + public: + explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {} + }; + + mDeathObserver = new DeathObserver(*const_cast<ComposerServiceAIDL*>(this)); + IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); + return true; +} + +/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() { + ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance(); + std::scoped_lock lock(instance.mMutex); + if (instance.mComposerService == nullptr) { + if (ComposerServiceAIDL::getInstance().connectLocked()) { + ALOGD("ComposerServiceAIDL reconnected"); + } + } + return instance.mComposerService; +} + +void ComposerServiceAIDL::composerServiceDied() { + std::scoped_lock lock(mMutex); + mComposerService = nullptr; + mDeathObserver = nullptr; +} + class DefaultComposerClient: public Singleton<DefaultComposerClient> { Mutex mLock; sp<SurfaceComposerClient> mClient; @@ -148,12 +208,14 @@ int64_t TransactionCompletedListener::getNextIdLocked() { } sp<TransactionCompletedListener> TransactionCompletedListener::sInstance = nullptr; +static std::mutex sListenerInstanceMutex; void TransactionCompletedListener::setInstance(const sp<TransactionCompletedListener>& listener) { sInstance = listener; } sp<TransactionCompletedListener> TransactionCompletedListener::getInstance() { + std::lock_guard<std::mutex> lock(sListenerInstanceMutex); if (sInstance == nullptr) { sInstance = new TransactionCompletedListener; } @@ -214,12 +276,6 @@ void TransactionCompletedListener::setReleaseBufferCallback(const ReleaseCallbac mReleaseBufferCallbacks[callbackId] = listener; } -void TransactionCompletedListener::removeReleaseBufferCallback( - const ReleaseCallbackId& callbackId) { - std::scoped_lock<std::mutex> lock(mMutex); - mReleaseBufferCallbacks.erase(callbackId); -} - void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener) { std::scoped_lock<std::recursive_mutex> lock(mSurfaceStatsListenerMutex); @@ -293,10 +349,10 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceControlStats .emplace_back(callbacksMap[callbackId] .surfaceControls[surfaceStats.surfaceControl], - transactionStats.latchTime, surfaceStats.acquireTime, + transactionStats.latchTime, surfaceStats.acquireTimeOrFence, transactionStats.presentFence, surfaceStats.previousReleaseFence, surfaceStats.transformHint, - surfaceStats.eventStats, surfaceStats.currentMaxAcquiredBufferCount); + surfaceStats.eventStats); } callbackFunction(transactionStats.latchTime, transactionStats.presentFence, @@ -318,10 +374,10 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceControlStats .emplace_back(callbacksMap[callbackId] .surfaceControls[surfaceStats.surfaceControl], - transactionStats.latchTime, surfaceStats.acquireTime, + transactionStats.latchTime, surfaceStats.acquireTimeOrFence, transactionStats.presentFence, surfaceStats.previousReleaseFence, surfaceStats.transformHint, - surfaceStats.eventStats, surfaceStats.currentMaxAcquiredBufferCount); + surfaceStats.eventStats); if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl]) { callbacksMap[callbackId] .surfaceControls[surfaceStats.surfaceControl] @@ -343,7 +399,6 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceStats.previousReleaseFence ? surfaceStats.previousReleaseFence : Fence::NO_FENCE, - surfaceStats.transformHint, surfaceStats.currentMaxAcquiredBufferCount); } } @@ -359,6 +414,10 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener // through all until the SC is found. int32_t layerId = -1; for (auto callbackId : transactionStats.callbackIds) { + if (callbackId.type != CallbackId::Type::ON_COMPLETE) { + // We only want to run the stats callback for ON_COMPLETE + continue; + } sp<SurfaceControl> sc = callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl]; if (sc != nullptr) { @@ -367,7 +426,7 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } - { + if (layerId != -1) { // Acquire surface stats listener lock such that we guarantee that after calling // unregister, there won't be any further callback. std::scoped_lock<std::recursive_mutex> lock(mSurfaceStatsListenerMutex); @@ -388,8 +447,29 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener } } +void TransactionCompletedListener::onTransactionQueueStalled() { + std::unordered_map<void*, std::function<void()>> callbackCopy; + { + std::scoped_lock<std::mutex> lock(mMutex); + callbackCopy = mQueueStallListeners; + } + for (auto const& it : callbackCopy) { + it.second(); + } +} + +void TransactionCompletedListener::addQueueStallListener(std::function<void()> stallListener, + void* id) { + std::scoped_lock<std::mutex> lock(mMutex); + mQueueStallListeners[id] = stallListener; +} +void TransactionCompletedListener::removeQueueStallListener(void *id) { + std::scoped_lock<std::mutex> lock(mMutex); + mQueueStallListeners.erase(id); +} + void TransactionCompletedListener::onReleaseBuffer(ReleaseCallbackId callbackId, - sp<Fence> releaseFence, uint32_t transformHint, + sp<Fence> releaseFence, uint32_t currentMaxAcquiredBufferCount) { ReleaseBufferCallback callback; { @@ -401,7 +481,11 @@ void TransactionCompletedListener::onReleaseBuffer(ReleaseCallbackId callbackId, callbackId.to_string().c_str()); return; } - callback(callbackId, releaseFence, transformHint, currentMaxAcquiredBufferCount); + std::optional<uint32_t> optionalMaxAcquiredBufferCount = + currentMaxAcquiredBufferCount == UINT_MAX + ? std::nullopt + : std::make_optional<uint32_t>(currentMaxAcquiredBufferCount); + callback(callbackId, releaseFence, optionalMaxAcquiredBufferCount); } ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked( @@ -416,6 +500,14 @@ ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLock return callback; } +void TransactionCompletedListener::removeReleaseBufferCallback( + const ReleaseCallbackId& callbackId) { + { + std::scoped_lock<std::mutex> lock(mMutex); + popReleaseBufferCallbackLocked(callbackId); + } +} + // --------------------------------------------------------------------------- void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId); @@ -525,10 +617,6 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) { // --------------------------------------------------------------------------- -// Initialize transaction id counter used to generate transaction ids -// Transactions will start counting at 1, 0 is used for invalid transactions -std::atomic<uint32_t> SurfaceComposerClient::Transaction::idCounter = 1; - SurfaceComposerClient::Transaction::Transaction() { mId = generateId(); } @@ -567,9 +655,6 @@ SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) { return nullptr; } -int64_t SurfaceComposerClient::Transaction::generateId() { - return (((int64_t)getpid()) << 32) | idCounter++; -} status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel) { const uint32_t forceSynchronous = parcel->readUint32(); @@ -718,11 +803,34 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const return NO_ERROR; } +void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_state_t& state) { + if (!(state.what & layer_state_t::eBufferChanged)) { + return; + } + + auto listener = state.bufferData->releaseBufferListener; + sp<Fence> fence = + state.bufferData->acquireFence ? state.bufferData->acquireFence : Fence::NO_FENCE; + if (state.bufferData->releaseBufferEndpoint == + IInterface::asBinder(TransactionCompletedListener::getIInstance())) { + // if the callback is in process, run on a different thread to avoid any lock contigency + // issues in the client. + SurfaceComposerClient::getDefault() + ->mReleaseCallbackThread + .addReleaseCallback(state.bufferData->generateReleaseCallbackId(), fence); + } else { + listener->onReleaseBuffer(state.bufferData->generateReleaseCallbackId(), fence, UINT_MAX); + } +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { for (auto const& [handle, composerState] : other.mComposerStates) { if (mComposerStates.count(handle) == 0) { mComposerStates[handle] = composerState; } else { + if (composerState.state.what & layer_state_t::eBufferChanged) { + releaseBufferIfOverwriting(mComposerStates[handle].state); + } mComposerStates[handle].state.merge(composerState.state); } } @@ -798,7 +906,7 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); sf->setTransactionState(FrameTimelineInfo{}, {}, {}, 0, applyToken, {}, systemTime(), true, - uncacheBuffer, false, {}, 0 /* Undefined transactionId */); + uncacheBuffer, false, {}, generateId()); } void SurfaceComposerClient::Transaction::cacheBuffers() { @@ -811,7 +919,8 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { layer_state_t* s = &(mComposerStates[handle].state); if (!(s->what & layer_state_t::eBufferChanged)) { continue; - } else if (s->what & layer_state_t::eCachedBufferChanged) { + } else if (s->bufferData && + s->bufferData->flags.test(BufferData::BufferDataChange::cachedBufferChanged)) { // If eBufferChanged and eCachedBufferChanged are both trued then that means // we already cached the buffer in a previous call to cacheBuffers, perhaps // from writeToParcel on a Transaction that was merged in to this one. @@ -820,23 +929,22 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { // Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste // time trying to cache them. - if (!s->buffer) { + if (!s->bufferData || !s->bufferData->buffer) { continue; } uint64_t cacheId = 0; - status_t ret = BufferCache::getInstance().getCacheId(s->buffer, &cacheId); + status_t ret = BufferCache::getInstance().getCacheId(s->bufferData->buffer, &cacheId); if (ret == NO_ERROR) { // Cache-hit. Strip the buffer and send only the id. - s->what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged); - s->buffer = nullptr; + s->bufferData->buffer = nullptr; } else { // Cache-miss. Include the buffer and send the new cacheId. - cacheId = BufferCache::getInstance().cache(s->buffer); + cacheId = BufferCache::getInstance().cache(s->bufferData->buffer); } - s->what |= layer_state_t::eCachedBufferChanged; - s->cachedBuffer.token = BufferCache::getInstance().getToken(); - s->cachedBuffer.id = cacheId; + s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged; + s->bufferData->cachedBuffer.token = BufferCache::getInstance().getToken(); + s->bufferData->cachedBuffer.id = cacheId; // If we have more buffers than the size of the cache, we should stop caching so we don't // evict other buffers in this transaction @@ -847,7 +955,7 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { } } -status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { +status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) { if (mStatus != NO_ERROR) { return mStatus; } @@ -901,6 +1009,14 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { if (mAnimation) { flags |= ISurfaceComposer::eAnimation; } + if (oneWay) { + if (mForceSynchronous) { + ALOGE("Transaction attempted to set synchronous and one way at the same time" + " this is an invalid request. Synchronous will win for safety"); + } else { + flags |= ISurfaceComposer::eOneWay; + } + } // If both mEarlyWakeupStart and mEarlyWakeupEnd are set // it is equivalent for none @@ -931,32 +1047,59 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { // --------------------------------------------------------------------------- sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, bool secure) { - return ComposerService::getComposerService()->createDisplay(displayName, - secure); + sp<IBinder> display = nullptr; + binder::Status status = + ComposerServiceAIDL::getComposerService()->createDisplay(std::string( + displayName.string()), + secure, &display); + return status.isOk() ? display : nullptr; } void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) { - return ComposerService::getComposerService()->destroyDisplay(display); + ComposerServiceAIDL::getComposerService()->destroyDisplay(display); } std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() { - return ComposerService::getComposerService()->getPhysicalDisplayIds(); + std::vector<int64_t> displayIds; + std::vector<PhysicalDisplayId> physicalDisplayIds; + binder::Status status = + ComposerServiceAIDL::getComposerService()->getPhysicalDisplayIds(&displayIds); + if (status.isOk()) { + physicalDisplayIds.reserve(displayIds.size()); + for (auto item : displayIds) { + auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(item)); + physicalDisplayIds.push_back(*id); + } + } + return physicalDisplayIds; } status_t SurfaceComposerClient::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) { - return ComposerService::getComposerService()->getPrimaryPhysicalDisplayId(id); + int64_t displayId; + binder::Status status = + ComposerServiceAIDL::getComposerService()->getPrimaryPhysicalDisplayId(&displayId); + if (status.isOk()) { + *id = *DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId)); + } + return status.transactionError(); } std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() { - return ComposerService::getComposerService()->getInternalDisplayId(); + ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance(); + return instance.getInternalDisplayId(); } sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) { - return ComposerService::getComposerService()->getPhysicalDisplayToken(displayId); + sp<IBinder> display = nullptr; + binder::Status status = + ComposerServiceAIDL::getComposerService()->getPhysicalDisplayToken(displayId.value, + &display); + return status.isOk() ? display : nullptr; } sp<IBinder> SurfaceComposerClient::getInternalDisplayToken() { - return ComposerService::getComposerService()->getInternalDisplayToken(); + ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance(); + return instance.getInternalDisplayToken(); } void SurfaceComposerClient::Transaction::setAnimationTransaction() { @@ -1077,7 +1220,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags } if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) || (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) || - (mask & layer_state_t::eEnableBackpressure)) { + (mask & layer_state_t::eEnableBackpressure) || + (mask & layer_state_t::eLayerIsDisplayDecoration)) { s->what |= layer_state_t::eFlagsChanged; } s->flags &= ~mask; @@ -1103,6 +1247,20 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDimmingEnabled( + const sp<SurfaceControl>& sc, bool dimmingEnabled) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eDimmingEnabledChanged; + s->dimmingEnabled = dimmingEnabled; + + registerSurfaceControlForCallback(sc); + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha( const sp<SurfaceControl>& sc, float alpha) { layer_state_t* s = getLayerState(sc); @@ -1118,7 +1276,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayerStack( - const sp<SurfaceControl>& sc, uint32_t layerStack) { + const sp<SurfaceControl>& sc, ui::LayerStack layerStack) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; @@ -1294,73 +1452,108 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp<Surfac return *this; } +std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffer( + const sp<SurfaceControl>& sc) { + layer_state_t* s = getLayerState(sc); + if (!s) { + return nullptr; + } + if (!(s->what & layer_state_t::eBufferChanged)) { + return nullptr; + } + + std::shared_ptr<BufferData> bufferData = std::move(s->bufferData); + + TransactionCompletedListener::getInstance()->removeReleaseBufferCallback( + bufferData->generateReleaseCallbackId()); + s->what &= ~layer_state_t::eBufferChanged; + s->bufferData = nullptr; + + mContainsBuffer = false; + return bufferData; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBufferHasBarrier( + const sp<SurfaceControl>& sc, uint64_t barrierFrameNumber) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->bufferData->hasBarrier = true; + s->bufferData->barrierFrameNumber = barrierFrameNumber; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( - const sp<SurfaceControl>& sc, const sp<GraphicBuffer>& buffer, const ReleaseCallbackId& id, + const sp<SurfaceControl>& sc, const sp<GraphicBuffer>& buffer, + const std::optional<sp<Fence>>& fence, const std::optional<uint64_t>& optFrameNumber, ReleaseBufferCallback callback) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - removeReleaseBufferCallback(s); - s->what |= layer_state_t::eBufferChanged; - s->buffer = buffer; - s->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); + + releaseBufferIfOverwriting(*s); + + if (buffer == nullptr) { + s->what &= ~layer_state_t::eBufferChanged; + s->bufferData = nullptr; + mContainsBuffer = false; + return *this; + } + + std::shared_ptr<BufferData> bufferData = std::make_shared<BufferData>(); + bufferData->buffer = buffer; + uint64_t frameNumber = sc->resolveFrameNumber(optFrameNumber); + bufferData->frameNumber = frameNumber; + bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged; + if (fence) { + bufferData->acquireFence = *fence; + bufferData->flags |= BufferData::BufferDataChange::fenceChanged; + } + bufferData->releaseBufferEndpoint = + IInterface::asBinder(TransactionCompletedListener::getIInstance()); if (mIsAutoTimestamp) { mDesiredPresentTime = systemTime(); } - setReleaseBufferCallback(s, id, callback); - + setReleaseBufferCallback(bufferData.get(), callback); + s->what |= layer_state_t::eBufferChanged; + s->bufferData = std::move(bufferData); registerSurfaceControlForCallback(sc); + // With the current infrastructure, a release callback will not be invoked if there's no + // transaction callback in the case when a buffer is latched and not released early. This is + // because the legacy implementation didn't have a release callback and sent releases in the + // transaction callback. Because of this, we need to make sure to have a transaction callback + // set up when a buffer is sent in a transaction to ensure the caller gets the release + // callback, regardless if they set up a transaction callback. + // + // TODO (b/230380821): Remove when release callbacks are separated from transaction callbacks + addTransactionCompletedCallback([](void*, nsecs_t, const sp<Fence>&, + const std::vector<SurfaceControlStats>&) {}, + nullptr); + mContainsBuffer = true; return *this; } -void SurfaceComposerClient::Transaction::removeReleaseBufferCallback(layer_state_t* s) { - if (!s->releaseBufferListener) { - return; - } - - s->what &= ~static_cast<uint64_t>(layer_state_t::eReleaseBufferListenerChanged); - s->releaseBufferListener = nullptr; - auto listener = TransactionCompletedListener::getInstance(); - listener->removeReleaseBufferCallback(s->releaseCallbackId); - s->releaseCallbackId = ReleaseCallbackId::INVALID_ID; -} - -void SurfaceComposerClient::Transaction::setReleaseBufferCallback(layer_state_t* s, - const ReleaseCallbackId& id, +void SurfaceComposerClient::Transaction::setReleaseBufferCallback(BufferData* bufferData, ReleaseBufferCallback callback) { if (!callback) { return; } - if (!s->buffer) { + if (!bufferData->buffer) { ALOGW("Transaction::setReleaseBufferCallback" "ignored trying to set a callback on a null buffer."); return; } - s->what |= layer_state_t::eReleaseBufferListenerChanged; - s->releaseBufferListener = TransactionCompletedListener::getIInstance(); - s->releaseCallbackId = id; + bufferData->releaseBufferListener = TransactionCompletedListener::getIInstance(); auto listener = TransactionCompletedListener::getInstance(); - listener->setReleaseBufferCallback(id, callback); -} - -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAcquireFence( - const sp<SurfaceControl>& sc, const sp<Fence>& fence) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eAcquireFenceChanged; - s->acquireFence = fence; - - registerSurfaceControlForCallback(sc); - return *this; + listener->setReleaseBufferCallback(bufferData->generateReleaseCallbackId(), callback); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDataspace( @@ -1512,20 +1705,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::notifyPr return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameNumber( - const sp<SurfaceControl>& sc, uint64_t frameNumber) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - - s->what |= layer_state_t::eFrameNumberChanged; - s->frameNumber = frameNumber; - - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo( const sp<SurfaceControl>& sc, const WindowInfo& info) { layer_state_t* s = getLayerState(sc); @@ -1798,7 +1977,7 @@ status_t SurfaceComposerClient::Transaction::setDisplaySurface(const sp<IBinder> } void SurfaceComposerClient::Transaction::setDisplayLayerStack(const sp<IBinder>& token, - uint32_t layerStack) { + ui::LayerStack layerStack) { DisplayState& s(getDisplayState(token)); s.layerStack = layerStack; s.what |= DisplayState::eLayerStackChanged; @@ -1992,7 +2171,16 @@ status_t SurfaceComposerClient::injectVSync(nsecs_t when) { status_t SurfaceComposerClient::getDisplayState(const sp<IBinder>& display, ui::DisplayState* state) { - return ComposerService::getComposerService()->getDisplayState(display, state); + gui::DisplayState ds; + binder::Status status = + ComposerServiceAIDL::getComposerService()->getDisplayState(display, &ds); + if (status.isOk()) { + state->layerStack = ui::LayerStack::fromValue(ds.layerStack); + state->orientation = static_cast<ui::Rotation>(ds.orientation); + state->layerStackSpaceRect = + ui::Size(ds.layerStackSpaceRect.width, ds.layerStackSpaceRect.height); + } + return status.transactionError(); } status_t SurfaceComposerClient::getStaticDisplayInfo(const sp<IBinder>& display, @@ -2055,17 +2243,38 @@ status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display, return ComposerService::getComposerService()->setActiveColorMode(display, colorMode); } +status_t SurfaceComposerClient::getBootDisplayModeSupport(bool* support) { + binder::Status status = + ComposerServiceAIDL::getComposerService()->getBootDisplayModeSupport(support); + return status.transactionError(); +} + +status_t SurfaceComposerClient::setBootDisplayMode(const sp<IBinder>& display, + ui::DisplayModeId displayModeId) { + return ComposerService::getComposerService()->setBootDisplayMode(display, displayModeId); +} + +status_t SurfaceComposerClient::clearBootDisplayMode(const sp<IBinder>& display) { + binder::Status status = + ComposerServiceAIDL::getComposerService()->clearBootDisplayMode(display); + return status.transactionError(); +} + +status_t SurfaceComposerClient::setOverrideFrameRate(uid_t uid, float frameRate) { + return ComposerService::getComposerService()->setOverrideFrameRate(uid, frameRate); +} + void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) { - ComposerService::getComposerService()->setAutoLowLatencyMode(display, on); + ComposerServiceAIDL::getComposerService()->setAutoLowLatencyMode(display, on); } void SurfaceComposerClient::setGameContentType(const sp<IBinder>& display, bool on) { - ComposerService::getComposerService()->setGameContentType(display, on); + ComposerServiceAIDL::getComposerService()->setGameContentType(display, on); } void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token, int mode) { - ComposerService::getComposerService()->setPowerMode(token, mode); + ComposerServiceAIDL::getComposerService()->setPowerMode(token, mode); } status_t SurfaceComposerClient::getCompositionPreference( @@ -2126,8 +2335,10 @@ status_t SurfaceComposerClient::getDisplayedContentSample(const sp<IBinder>& dis status_t SurfaceComposerClient::isWideColorDisplay(const sp<IBinder>& display, bool* outIsWideColorDisplay) { - return ComposerService::getComposerService()->isWideColorDisplay(display, - outIsWideColorDisplay); + binder::Status status = + ComposerServiceAIDL::getComposerService()->isWideColorDisplay(display, + outIsWideColorDisplay); + return status.transactionError(); } status_t SurfaceComposerClient::addRegionSamplingListener( @@ -2164,28 +2375,39 @@ status_t SurfaceComposerClient::removeTunnelModeEnabledListener( bool SurfaceComposerClient::getDisplayBrightnessSupport(const sp<IBinder>& displayToken) { bool support = false; - ComposerService::getComposerService()->getDisplayBrightnessSupport(displayToken, &support); - return support; + binder::Status status = + ComposerServiceAIDL::getComposerService()->getDisplayBrightnessSupport(displayToken, + &support); + return status.isOk() ? support : false; } status_t SurfaceComposerClient::setDisplayBrightness(const sp<IBinder>& displayToken, const gui::DisplayBrightness& brightness) { - return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness); + binder::Status status = + ComposerServiceAIDL::getComposerService()->setDisplayBrightness(displayToken, + brightness); + return status.transactionError(); } status_t SurfaceComposerClient::addHdrLayerInfoListener( const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) { - return ComposerService::getComposerService()->addHdrLayerInfoListener(displayToken, listener); + binder::Status status = + ComposerServiceAIDL::getComposerService()->addHdrLayerInfoListener(displayToken, + listener); + return status.transactionError(); } status_t SurfaceComposerClient::removeHdrLayerInfoListener( const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) { - return ComposerService::getComposerService()->removeHdrLayerInfoListener(displayToken, - listener); + binder::Status status = + ComposerServiceAIDL::getComposerService()->removeHdrLayerInfoListener(displayToken, + listener); + return status.transactionError(); } status_t SurfaceComposerClient::notifyPowerBoost(int32_t boostId) { - return ComposerService::getComposerService()->notifyPowerBoost(boostId); + binder::Status status = ComposerServiceAIDL::getComposerService()->notifyPowerBoost(boostId); + return status.transactionError(); } status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColor, @@ -2196,14 +2418,23 @@ status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColo lightRadius); } +std::optional<DisplayDecorationSupport> SurfaceComposerClient::getDisplayDecorationSupport( + const sp<IBinder>& displayToken) { + std::optional<DisplayDecorationSupport> support; + ComposerService::getComposerService()->getDisplayDecorationSupport(displayToken, &support); + return support; +} + int SurfaceComposerClient::getGPUContextPriority() { return ComposerService::getComposerService()->getGPUContextPriority(); } status_t SurfaceComposerClient::addWindowInfosListener( - const sp<WindowInfosListener>& windowInfosListener) { + const sp<WindowInfosListener>& windowInfosListener, + std::pair<std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>>* outInitialInfo) { return WindowInfosListenerReporter::getInstance() - ->addWindowInfosListener(windowInfosListener, ComposerService::getComposerService()); + ->addWindowInfosListener(windowInfosListener, ComposerService::getComposerService(), + outInitialInfo); } status_t SurfaceComposerClient::removeWindowInfosListener( @@ -2216,26 +2447,68 @@ status_t SurfaceComposerClient::removeWindowInfosListener( status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs, const sp<IScreenCaptureListener>& captureListener) { - sp<ISurfaceComposer> s(ComposerService::getComposerService()); + sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService()); if (s == nullptr) return NO_INIT; - return s->captureDisplay(captureArgs, captureListener); + binder::Status status = s->captureDisplay(captureArgs, captureListener); + return status.transactionError(); } -status_t ScreenshotClient::captureDisplay(uint64_t displayOrLayerStack, +status_t ScreenshotClient::captureDisplay(DisplayId displayId, const sp<IScreenCaptureListener>& captureListener) { - sp<ISurfaceComposer> s(ComposerService::getComposerService()); + sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService()); if (s == nullptr) return NO_INIT; - return s->captureDisplay(displayOrLayerStack, captureListener); + binder::Status status = s->captureDisplayById(displayId.value, captureListener); + return status.transactionError(); } status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs, const sp<IScreenCaptureListener>& captureListener) { - sp<ISurfaceComposer> s(ComposerService::getComposerService()); + sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService()); if (s == nullptr) return NO_INIT; - return s->captureLayers(captureArgs, captureListener); + binder::Status status = s->captureLayers(captureArgs, captureListener); + return status.transactionError(); +} + +// --------------------------------------------------------------------------------- + +void ReleaseCallbackThread::addReleaseCallback(const ReleaseCallbackId callbackId, + sp<Fence> releaseFence) { + std::scoped_lock<std::mutex> lock(mMutex); + if (!mStarted) { + mThread = std::thread(&ReleaseCallbackThread::threadMain, this); + mStarted = true; + } + + mCallbackInfos.emplace(callbackId, std::move(releaseFence)); + mReleaseCallbackPending.notify_one(); +} + +void ReleaseCallbackThread::threadMain() { + const auto listener = TransactionCompletedListener::getInstance(); + std::queue<std::tuple<const ReleaseCallbackId, const sp<Fence>>> callbackInfos; + while (true) { + { + std::unique_lock<std::mutex> lock(mMutex); + callbackInfos = std::move(mCallbackInfos); + mCallbackInfos = {}; + } + + while (!callbackInfos.empty()) { + auto [callbackId, releaseFence] = callbackInfos.front(); + listener->onReleaseBuffer(callbackId, std::move(releaseFence), UINT_MAX); + callbackInfos.pop(); + } + + { + std::unique_lock<std::mutex> lock(mMutex); + if (mCallbackInfos.size() == 0) { + mReleaseCallbackPending.wait(lock); + } + } + } } } // namespace android |