diff options
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 655 |
1 files changed, 502 insertions, 153 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index dfc61851c2..83bc06997a 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -31,8 +31,6 @@ #include <system/graphics.h> -#include <ui/DisplayInfo.h> - #include <gui/BufferItemConsumer.h> #include <gui/CpuConsumer.h> #include <gui/IGraphicBufferProducer.h> @@ -41,6 +39,7 @@ #include <gui/LayerState.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> +#include <ui/DisplayConfig.h> #ifndef NO_INPUT #include <input/InputWindow.h> @@ -189,52 +188,84 @@ void TransactionCompletedListener::addSurfaceControlToCallbacks( } void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { - std::lock_guard<std::mutex> lock(mMutex); + std::unordered_map<CallbackId, CallbackTranslation> callbacksMap; + { + std::lock_guard<std::mutex> lock(mMutex); - /* This listener knows all the sp<IBinder> to sp<SurfaceControl> for all its registered - * callbackIds, except for when Transactions are merged together. This probably cannot be - * solved before this point because the Transactions could be merged together and applied in a - * different process. - * - * Fortunately, we get all the callbacks for this listener for the same frame together at the - * same time. This means if any Transactions were merged together, we will get their callbacks - * at the same time. We can combine all the sp<IBinder> to sp<SurfaceControl> maps for all the - * callbackIds to generate one super map that contains all the sp<IBinder> to sp<SurfaceControl> - * that could possibly exist for the callbacks. - */ - std::unordered_map<sp<IBinder>, sp<SurfaceControl>, IBinderHash> surfaceControls; - for (const auto& transactionStats : listenerStats.transactionStats) { - for (auto callbackId : transactionStats.callbackIds) { - auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; - surfaceControls.insert(callbackSurfaceControls.begin(), callbackSurfaceControls.end()); + /* This listener knows all the sp<IBinder> to sp<SurfaceControl> for all its registered + * callbackIds, except for when Transactions are merged together. This probably cannot be + * solved before this point because the Transactions could be merged together and applied in + * a different process. + * + * Fortunately, we get all the callbacks for this listener for the same frame together at + * the same time. This means if any Transactions were merged together, we will get their + * callbacks at the same time. We can combine all the sp<IBinder> to sp<SurfaceControl> maps + * for all the callbackIds to generate one super map that contains all the sp<IBinder> to + * sp<SurfaceControl> that could possibly exist for the callbacks. + */ + callbacksMap = mCallbacks; + for (const auto& transactionStats : listenerStats.transactionStats) { + for (auto& callbackId : transactionStats.callbackIds) { + mCallbacks.erase(callbackId); + } } } - for (const auto& transactionStats : listenerStats.transactionStats) { for (auto callbackId : transactionStats.callbackIds) { - auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; + auto& [callbackFunction, callbackSurfaceControls] = callbacksMap[callbackId]; if (!callbackFunction) { ALOGE("cannot call null callback function, skipping"); continue; } std::vector<SurfaceControlStats> surfaceControlStats; for (const auto& surfaceStats : transactionStats.surfaceStats) { - surfaceControlStats.emplace_back(surfaceControls[surfaceStats.surfaceControl], - surfaceStats.acquireTime, - surfaceStats.previousReleaseFence); + surfaceControlStats + .emplace_back(callbacksMap[callbackId] + .surfaceControls[surfaceStats.surfaceControl], + transactionStats.latchTime, surfaceStats.acquireTime, + transactionStats.presentFence, + surfaceStats.previousReleaseFence, surfaceStats.transformHint, + surfaceStats.eventStats); + if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl]) { + callbacksMap[callbackId] + .surfaceControls[surfaceStats.surfaceControl] + ->setTransformHint(surfaceStats.transformHint); + } } callbackFunction(transactionStats.latchTime, transactionStats.presentFence, surfaceControlStats); - mCallbacks.erase(callbackId); } } } // --------------------------------------------------------------------------- -void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId); - +void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId); + +/** + * We use the BufferCache to reduce the overhead of exchanging GraphicBuffers with + * the server. If we were to simply parcel the GraphicBuffer we would pay two overheads + * 1. Cost of sending the FD + * 2. Cost of importing the GraphicBuffer with the mapper in the receiving process. + * To ease this cost we implement the following scheme of caching buffers to integers, + * or said-otherwise, naming them with integers. This is the scheme known as slots in + * the legacy BufferQueue system. + * 1. When sending Buffers to SurfaceFlinger we look up the Buffer in the cache. + * 2. If there is a cache-hit we remove the Buffer from the Transaction and instead + * send the cached integer. + * 3. If there is a cache miss, we cache the new buffer and send the integer + * along with the Buffer, SurfaceFlinger on it's side creates a new cache + * entry, and we use the integer for further communication. + * A few details about lifetime: + * 1. The cache evicts by LRU. The server side cache is keyed by BufferCache::getToken + * which is per process Unique. The server side cache is larger than the client side + * cache so that the server will never evict entries before the client. + * 2. When the client evicts an entry it notifies the server via an uncacheBuffer + * transaction. + * 3. The client only references the Buffers by ID, and uses buffer->addDeathCallback + * to auto-evict destroyed buffers. + */ class BufferCache : public Singleton<BufferCache> { public: BufferCache() : token(new BBinder()) {} @@ -262,7 +293,7 @@ public: evictLeastRecentlyUsedBuffer(); } - buffer->addDeathCallback(bufferCacheCallback, nullptr); + buffer->addDeathCallback(removeDeadBufferCallback, nullptr); mBuffers[buffer->getId()] = getCounter(); return buffer->getId(); @@ -310,7 +341,7 @@ private: ANDROID_SINGLETON_STATIC_INSTANCE(BufferCache); -void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId) { +void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) { // GraphicBuffer id's are used as the cache ids. BufferCache::getInstance().uncache(graphicBufferId); } @@ -322,21 +353,169 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mTransactionNestCount(other.mTransactionNestCount), mAnimation(other.mAnimation), mEarlyWakeup(other.mEarlyWakeup), + mExplicitEarlyWakeupStart(other.mExplicitEarlyWakeupStart), + mExplicitEarlyWakeupEnd(other.mExplicitEarlyWakeupEnd), + mContainsBuffer(other.mContainsBuffer), mDesiredPresentTime(other.mDesiredPresentTime) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; mInputWindowCommands = other.mInputWindowCommands; + mListenerCallbacks = other.mListenerCallbacks; +} + +std::unique_ptr<SurfaceComposerClient::Transaction> +SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) { + auto transaction = std::make_unique<Transaction>(); + if (transaction->readFromParcel(parcel) == NO_ERROR) { + return transaction; + } + return nullptr; +} + +status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel) { + const uint32_t forceSynchronous = parcel->readUint32(); + const uint32_t transactionNestCount = parcel->readUint32(); + const bool animation = parcel->readBool(); + const bool earlyWakeup = parcel->readBool(); + const bool explicitEarlyWakeupStart = parcel->readBool(); + const bool explicitEarlyWakeupEnd = parcel->readBool(); + const bool containsBuffer = parcel->readBool(); + const int64_t desiredPresentTime = parcel->readInt64(); + + size_t count = static_cast<size_t>(parcel->readUint32()); + if (count > parcel->dataSize()) { + return BAD_VALUE; + } + SortedVector<DisplayState> displayStates; + displayStates.setCapacity(count); + for (size_t i = 0; i < count; i++) { + DisplayState displayState; + if (displayState.read(*parcel) == BAD_VALUE) { + return BAD_VALUE; + } + displayStates.add(displayState); + } + + count = static_cast<size_t>(parcel->readUint32()); + if (count > parcel->dataSize()) { + return BAD_VALUE; + } + std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash> listenerCallbacks; + listenerCallbacks.reserve(count); + for (size_t i = 0; i < count; i++) { + sp<ITransactionCompletedListener> listener = + interface_cast<ITransactionCompletedListener>(parcel->readStrongBinder()); + size_t numCallbackIds = parcel->readUint32(); + if (numCallbackIds > parcel->dataSize()) { + return BAD_VALUE; + } + for (size_t j = 0; j < numCallbackIds; j++) { + listenerCallbacks[listener].callbackIds.insert(parcel->readInt64()); + } + size_t numSurfaces = parcel->readUint32(); + if (numSurfaces > parcel->dataSize()) { + return BAD_VALUE; + } + for (size_t j = 0; j < numSurfaces; j++) { + sp<SurfaceControl> surface; + surface = SurfaceControl::readFromParcel(parcel); + listenerCallbacks[listener].surfaceControls.insert(surface); + } + } + + count = static_cast<size_t>(parcel->readUint32()); + if (count > parcel->dataSize()) { + return BAD_VALUE; + } + std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> composerStates; + composerStates.reserve(count); + for (size_t i = 0; i < count; i++) { + sp<IBinder> surfaceControlHandle = parcel->readStrongBinder(); + + ComposerState composerState; + if (composerState.read(*parcel) == BAD_VALUE) { + return BAD_VALUE; + } + composerStates[surfaceControlHandle] = composerState; + } + + InputWindowCommands inputWindowCommands; + inputWindowCommands.read(*parcel); + + // Parsing was successful. Update the object. + mForceSynchronous = forceSynchronous; + mTransactionNestCount = transactionNestCount; + mAnimation = animation; + mEarlyWakeup = earlyWakeup; + mExplicitEarlyWakeupStart = explicitEarlyWakeupStart; + mExplicitEarlyWakeupEnd = explicitEarlyWakeupEnd; + mContainsBuffer = containsBuffer; + mDesiredPresentTime = desiredPresentTime; + mDisplayStates = displayStates; + mListenerCallbacks = listenerCallbacks; + mComposerStates = composerStates; + mInputWindowCommands = inputWindowCommands; + return NO_ERROR; +} + +status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const { + // If we write the Transaction to a parcel, we want to ensure the Buffers are cached + // before crossing the IPC boundary. Otherwise the receiving party will cache the buffers + // but is unlikely to use them again as they are owned by the other process. + // You may be asking yourself, is this const cast safe? Const cast is safe up + // until the point where you try and write to an object that was originally const at which + // point we enter undefined behavior. In this case we are safe though, because there are + // two possibilities: + // 1. The SurfaceComposerClient::Transaction was originally non-const. Safe. + // 2. It was originall const! In this case not only was it useless, but it by definition + // contains no composer states and so cacheBuffers will not perform any writes. + + const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers(); + + parcel->writeUint32(mForceSynchronous); + parcel->writeUint32(mTransactionNestCount); + parcel->writeBool(mAnimation); + parcel->writeBool(mEarlyWakeup); + parcel->writeBool(mExplicitEarlyWakeupStart); + parcel->writeBool(mExplicitEarlyWakeupEnd); + parcel->writeBool(mContainsBuffer); + parcel->writeInt64(mDesiredPresentTime); + parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size())); + for (auto const& displayState : mDisplayStates) { + displayState.write(*parcel); + } + + parcel->writeUint32(static_cast<uint32_t>(mListenerCallbacks.size())); + for (auto const& [listener, callbackInfo] : mListenerCallbacks) { + parcel->writeStrongBinder(ITransactionCompletedListener::asBinder(listener)); + parcel->writeUint32(static_cast<uint32_t>(callbackInfo.callbackIds.size())); + for (auto callbackId : callbackInfo.callbackIds) { + parcel->writeInt64(callbackId); + } + parcel->writeUint32(static_cast<uint32_t>(callbackInfo.surfaceControls.size())); + for (auto surfaceControl : callbackInfo.surfaceControls) { + surfaceControl->writeToParcel(parcel); + } + } + + parcel->writeUint32(static_cast<uint32_t>(mComposerStates.size())); + for (auto const& [surfaceHandle, composerState] : mComposerStates) { + parcel->writeStrongBinder(surfaceHandle); + composerState.write(*parcel); + } + + mInputWindowCommands.write(*parcel); + return NO_ERROR; } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { - for (auto const& kv : other.mComposerStates) { - if (mComposerStates.count(kv.first) == 0) { - mComposerStates[kv.first] = kv.second; + for (auto const& [surfaceHandle, composerState] : other.mComposerStates) { + if (mComposerStates.count(surfaceHandle) == 0) { + mComposerStates[surfaceHandle] = composerState; } else { - mComposerStates[kv.first].state.merge(kv.second.state); + mComposerStates[surfaceHandle].state.merge(composerState.state); } } - other.mComposerStates.clear(); for (auto const& state : other.mDisplayStates) { ssize_t index = mDisplayStates.indexOf(state); @@ -346,46 +525,53 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr mDisplayStates.editItemAt(static_cast<size_t>(index)).merge(state); } } - other.mDisplayStates.clear(); for (const auto& [listener, callbackInfo] : other.mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; mListenerCallbacks[listener].callbackIds.insert(std::make_move_iterator( callbackIds.begin()), std::make_move_iterator(callbackIds.end())); - mListenerCallbacks[listener] - .surfaceControls.insert(std::make_move_iterator(surfaceControls.begin()), - std::make_move_iterator(surfaceControls.end())); + + mListenerCallbacks[listener].surfaceControls.insert(surfaceControls.begin(), + surfaceControls.end()); + + auto& currentProcessCallbackInfo = + mListenerCallbacks[TransactionCompletedListener::getIInstance()]; + currentProcessCallbackInfo.surfaceControls + .insert(std::make_move_iterator(surfaceControls.begin()), + std::make_move_iterator(surfaceControls.end())); + + // register all surface controls for all callbackIds for this listener that is merging + for (const auto& surfaceControl : currentProcessCallbackInfo.surfaceControls) { + TransactionCompletedListener::getInstance() + ->addSurfaceControlToCallbacks(surfaceControl, + currentProcessCallbackInfo.callbackIds); + } } - other.mListenerCallbacks.clear(); mInputWindowCommands.merge(other.mInputWindowCommands); - other.mInputWindowCommands.clear(); - - mContainsBuffer = other.mContainsBuffer; - other.mContainsBuffer = false; + mContainsBuffer |= other.mContainsBuffer; mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup; - other.mEarlyWakeup = false; - + mExplicitEarlyWakeupStart = mExplicitEarlyWakeupStart || other.mExplicitEarlyWakeupStart; + mExplicitEarlyWakeupEnd = mExplicitEarlyWakeupEnd || other.mExplicitEarlyWakeupEnd; + other.clear(); return *this; } -void SurfaceComposerClient::doDropReferenceTransaction(const sp<IBinder>& handle, - const sp<ISurfaceComposerClient>& client) { - sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - Vector<ComposerState> composerStates; - Vector<DisplayState> displayStates; - - ComposerState s; - s.client = client; - s.state.surface = handle; - s.state.what |= layer_state_t::eReparent; - s.state.parentHandleForChild = nullptr; - - composerStates.add(s); - sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); - sf->setTransactionState(composerStates, displayStates, 0, applyToken, {}, -1, {}, {}); +void SurfaceComposerClient::Transaction::clear() { + mComposerStates.clear(); + mDisplayStates.clear(); + mListenerCallbacks.clear(); + mInputWindowCommands.clear(); + mContainsBuffer = false; + mForceSynchronous = 0; + mTransactionNestCount = 0; + mAnimation = false; + mEarlyWakeup = false; + mExplicitEarlyWakeupStart = false; + mExplicitEarlyWakeupEnd = false; + mDesiredPresentTime = -1; } void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { @@ -396,7 +582,7 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) { uncacheBuffer.id = cacheId; sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); - sf->setTransactionState({}, {}, 0, applyToken, {}, -1, uncacheBuffer, {}); + sf->setTransactionState({}, {}, 0, applyToken, {}, -1, uncacheBuffer, false, {}); } void SurfaceComposerClient::Transaction::cacheBuffers() { @@ -405,10 +591,15 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { } size_t count = 0; - for (auto& [sc, cs] : mComposerStates) { - layer_state_t* s = getLayerState(sc); + for (auto& [handle, cs] : mComposerStates) { + layer_state_t* s = getLayerState(handle); if (!(s->what & layer_state_t::eBufferChanged)) { continue; + } else if (s->what & layer_state_t::eCachedBufferChanged) { + // 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. + continue; } // Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste @@ -420,9 +611,11 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { uint64_t cacheId = 0; status_t ret = BufferCache::getInstance().getCacheId(s->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; } else { + // Cache-miss. Include the buffer and send the new cacheId. cacheId = BufferCache::getInstance().cache(s->buffer); } s->what |= layer_state_t::eCachedBufferChanged; @@ -445,8 +638,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + bool hasListenerCallbacks = !mListenerCallbacks.empty(); std::vector<ListenerCallbacks> listenerCallbacks; - // For every listener with registered callbacks for (const auto& [listener, callbackInfo] : mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; @@ -454,19 +647,24 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { continue; } - listenerCallbacks.emplace_back(listener, std::move(callbackIds)); - - // If the listener has any SurfaceControls set on this Transaction update the surface state - for (const auto& surfaceControl : surfaceControls) { - layer_state_t* s = getLayerState(surfaceControl); - if (!s) { - ALOGE("failed to get layer state"); - continue; + if (surfaceControls.empty()) { + listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds)); + } else { + // If the listener has any SurfaceControls set on this Transaction update the surface + // state + for (const auto& surfaceControl : surfaceControls) { + layer_state_t* s = getLayerState(surfaceControl); + if (!s) { + ALOGE("failed to get layer state"); + continue; + } + std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end()); + s->what |= layer_state_t::eHasListenerCallbacksChanged; + s->listeners.emplace_back(IInterface::asBinder(listener), callbacks); } - s->what |= layer_state_t::eHasListenerCallbacksChanged; - s->hasListenerCallbacks = true; } } + mListenerCallbacks.clear(); cacheBuffers(); @@ -496,15 +694,26 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { flags |= ISurfaceComposer::eEarlyWakeup; } + // If both mExplicitEarlyWakeupStart and mExplicitEarlyWakeupEnd are set + // it is equivalent for none + if (mExplicitEarlyWakeupStart && !mExplicitEarlyWakeupEnd) { + flags |= ISurfaceComposer::eExplicitEarlyWakeupStart; + } + if (mExplicitEarlyWakeupEnd && !mExplicitEarlyWakeupStart) { + flags |= ISurfaceComposer::eExplicitEarlyWakeupEnd; + } + mForceSynchronous = false; mAnimation = false; mEarlyWakeup = false; + mExplicitEarlyWakeupStart = false; + mExplicitEarlyWakeupEnd = false; sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/, - listenerCallbacks); + hasListenerCallbacks, listenerCallbacks); mInputWindowCommands.clear(); mStatus = NO_ERROR; return NO_ERROR; @@ -545,16 +754,23 @@ void SurfaceComposerClient::Transaction::setEarlyWakeup() { mEarlyWakeup = true; } -layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) { - if (mComposerStates.count(sc) == 0) { +void SurfaceComposerClient::Transaction::setExplicitEarlyWakeupStart() { + mExplicitEarlyWakeupStart = true; +} + +void SurfaceComposerClient::Transaction::setExplicitEarlyWakeupEnd() { + mExplicitEarlyWakeupEnd = true; +} + +layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<IBinder>& handle) { + if (mComposerStates.count(handle) == 0) { // we don't have it, add an initialized layer_state to our list ComposerState s; - s.client = sc->getClient()->mClient; - s.state.surface = sc->getHandle(); - mComposerStates[sc] = s; + s.state.surface = handle; + mComposerStates[handle] = s; } - return &(mComposerStates[sc].state); + return &(mComposerStates[handle].state); } void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( @@ -626,6 +842,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelat layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eRelativeLayerChanged; s->what &= ~layer_state_t::eLayerChanged; @@ -761,6 +978,18 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCorne return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundBlurRadius( + const sp<SurfaceControl>& sc, int backgroundBlurRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eBackgroundBlurRadiusChanged; + s->backgroundBlurRadius = backgroundBlurRadius; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp<SurfaceControl>& sc, const sp<IBinder>& handle, @@ -1035,6 +1264,22 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor } SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::setFrameRateSelectionPriority(const sp<SurfaceControl>& sc, + int32_t priority) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eFrameRateSelectionPriority; + s->frameRateSelectionPriority = priority; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext) { auto listener = TransactionCompletedListener::getInstance(); @@ -1051,11 +1296,24 @@ SurfaceComposerClient::Transaction::addTransactionCompletedCallback( return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::notifyProducerDisconnect( + const sp<SurfaceControl>& sc) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eProducerDisconnect; + return *this; +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachChildren( const sp<SurfaceControl>& sc) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; + return *this; } s->what |= layer_state_t::eDetachChildren; @@ -1092,19 +1350,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setOverr return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeometryAppliesWithResize( - const sp<SurfaceControl>& sc) { - layer_state_t* s = getLayerState(sc); - if (!s) { - mStatus = BAD_INDEX; - return *this; - } - s->what |= layer_state_t::eGeometryAppliesWithResize; - - registerSurfaceControlForCallback(sc); - return *this; -} - #ifndef NO_INPUT SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo( const sp<SurfaceControl>& sc, @@ -1119,15 +1364,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::transferTouchFocus( - const sp<IBinder>& fromToken, const sp<IBinder>& toToken) { - InputWindowCommands::TransferTouchFocusCommand transferTouchFocusCommand; - transferTouchFocusCommand.fromToken = fromToken; - transferTouchFocusCommand.toToken = toToken; - mInputWindowCommands.transferTouchFocusCommands.emplace_back(transferTouchFocusCommand); - return *this; -} - SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::syncInputWindows() { mInputWindowCommands.syncInputWindows = true; return *this; @@ -1196,8 +1432,55 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeome break; } setMatrix(sc, matrix[0], matrix[1], matrix[2], matrix[3]); - setPosition(sc, x, y); + float offsetX = xScale * source.left; + float offsetY = yScale * source.top; + setPosition(sc, x - offsetX, y - offsetY); + + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShadowRadius( + const sp<SurfaceControl>& sc, float shadowRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eShadowRadiusChanged; + s->shadowRadius = shadowRadius; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate( + const sp<SurfaceControl>& sc, float frameRate, int8_t compatibility) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate")) { + mStatus = BAD_VALUE; + return *this; + } + s->what |= layer_state_t::eFrameRateChanged; + s->frameRate = frameRate; + s->frameRateCompatibility = compatibility; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixedTransformHint( + const sp<SurfaceControl>& sc, int32_t fixedTransformHint) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + const ui::Transform::RotationFlags transform = fixedTransformHint == -1 + ? ui::Transform::ROT_INVALID + : ui::Transform::toRotationFlags(static_cast<ui::Rotation>(fixedTransformHint)); + s->what |= layer_state_t::eFixedTransformHintChanged; + s->fixedTransformHint = transform; return *this; } @@ -1242,9 +1525,9 @@ void SurfaceComposerClient::Transaction::setDisplayLayerStack(const sp<IBinder>& } void SurfaceComposerClient::Transaction::setDisplayProjection(const sp<IBinder>& token, - uint32_t orientation, - const Rect& layerStackRect, - const Rect& displayRect) { + ui::Rotation orientation, + const Rect& layerStackRect, + const Rect& displayRect) { DisplayState& s(getDisplayState(token)); s.orientation = orientation; s.viewport = layerStackRect; @@ -1317,16 +1600,19 @@ void SurfaceComposerClient::dispose() { sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, SurfaceControl* parent, - LayerMetadata metadata) { + LayerMetadata metadata, + uint32_t* outTransformHint) { sp<SurfaceControl> s; - createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata)); + createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata), + outTransformHint); return s; } sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, Surface* parent, - LayerMetadata metadata) { + LayerMetadata metadata, + uint32_t* outTransformHint) { sp<SurfaceControl> sur; status_t err = mStatus; @@ -1335,11 +1621,15 @@ sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer(); sp<IGraphicBufferProducer> gbp; + uint32_t transformHint = 0; err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp, - std::move(metadata), &handle, &gbp); + std::move(metadata), &handle, &gbp, &transformHint); + if (outTransformHint) { + *outTransformHint = transformHint; + } ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err)); if (err == NO_ERROR) { - return new SurfaceControl(this, handle, gbp, true /* owned */); + return new SurfaceControl(this, handle, gbp, transformHint); } } return nullptr; @@ -1348,8 +1638,8 @@ sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h, PixelFormat format, sp<SurfaceControl>* outSurface, uint32_t flags, - SurfaceControl* parent, - LayerMetadata metadata) { + SurfaceControl* parent, LayerMetadata metadata, + uint32_t* outTransformHint) { sp<SurfaceControl> sur; status_t err = mStatus; @@ -1362,16 +1652,34 @@ status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32 parentHandle = parent->getHandle(); } + uint32_t transformHint = 0; err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), - &handle, &gbp); + &handle, &gbp, &transformHint); + if (outTransformHint) { + *outTransformHint = transformHint; + } ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { - *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); + *outSurface = new SurfaceControl(this, handle, gbp, transformHint); } } return err; } +sp<SurfaceControl> SurfaceComposerClient::mirrorSurface(SurfaceControl* mirrorFromSurface) { + if (mirrorFromSurface == nullptr) { + return nullptr; + } + + sp<IBinder> handle; + sp<IBinder> mirrorFromHandle = mirrorFromSurface->getHandle(); + status_t err = mClient->mirrorSurface(mirrorFromHandle, &handle); + if (err == NO_ERROR) { + return new SurfaceControl(this, handle, nullptr, true /* owned */); + } + return nullptr; +} + status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const { if (mStatus != NO_ERROR) { return mStatus; @@ -1399,15 +1707,23 @@ status_t SurfaceComposerClient::injectVSync(nsecs_t when) { return sf->injectVSync(when); } -status_t SurfaceComposerClient::getDisplayConfigs( - const sp<IBinder>& display, Vector<DisplayInfo>* configs) -{ +status_t SurfaceComposerClient::getDisplayState(const sp<IBinder>& display, + ui::DisplayState* state) { + return ComposerService::getComposerService()->getDisplayState(display, state); +} + +status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) { + return ComposerService::getComposerService()->getDisplayInfo(display, info); +} + +status_t SurfaceComposerClient::getDisplayConfigs(const sp<IBinder>& display, + Vector<DisplayConfig>* configs) { return ComposerService::getComposerService()->getDisplayConfigs(display, configs); } -status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, - DisplayInfo* info) { - Vector<DisplayInfo> configs; +status_t SurfaceComposerClient::getActiveDisplayConfig(const sp<IBinder>& display, + DisplayConfig* config) { + Vector<DisplayConfig> configs; status_t result = getDisplayConfigs(display, &configs); if (result != NO_ERROR) { return result; @@ -1419,7 +1735,7 @@ status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, return NAME_NOT_FOUND; } - *info = configs[static_cast<size_t>(activeId)]; + *config = configs[static_cast<size_t>(activeId)]; return NO_ERROR; } @@ -1427,20 +1743,28 @@ int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) { return ComposerService::getComposerService()->getActiveConfig(display); } -status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int id) { - return ComposerService::getComposerService()->setActiveConfig(display, id); -} - -status_t SurfaceComposerClient::setAllowedDisplayConfigs( - const sp<IBinder>& displayToken, const std::vector<int32_t>& allowedConfigs) { - return ComposerService::getComposerService()->setAllowedDisplayConfigs(displayToken, - allowedConfigs); +status_t SurfaceComposerClient::setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, + int32_t defaultConfig, + float primaryRefreshRateMin, + float primaryRefreshRateMax, + float appRequestRefreshRateMin, + float appRequestRefreshRateMax) { + return ComposerService::getComposerService() + ->setDesiredDisplayConfigSpecs(displayToken, defaultConfig, primaryRefreshRateMin, + primaryRefreshRateMax, appRequestRefreshRateMin, + appRequestRefreshRateMax); } -status_t SurfaceComposerClient::getAllowedDisplayConfigs(const sp<IBinder>& displayToken, - std::vector<int32_t>* outAllowedConfigs) { - return ComposerService::getComposerService()->getAllowedDisplayConfigs(displayToken, - outAllowedConfigs); +status_t SurfaceComposerClient::getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, + int32_t* outDefaultConfig, + float* outPrimaryRefreshRateMin, + float* outPrimaryRefreshRateMax, + float* outAppRequestRefreshRateMin, + float* outAppRequestRefreshRateMax) { + return ComposerService::getComposerService() + ->getDesiredDisplayConfigSpecs(displayToken, outDefaultConfig, outPrimaryRefreshRateMin, + outPrimaryRefreshRateMax, outAppRequestRefreshRateMin, + outAppRequestRefreshRateMax); } status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display, @@ -1462,6 +1786,26 @@ status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display, return ComposerService::getComposerService()->setActiveColorMode(display, colorMode); } +bool SurfaceComposerClient::getAutoLowLatencyModeSupport(const sp<IBinder>& display) { + bool supported = false; + ComposerService::getComposerService()->getAutoLowLatencyModeSupport(display, &supported); + return supported; +} + +void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) { + ComposerService::getComposerService()->setAutoLowLatencyMode(display, on); +} + +bool SurfaceComposerClient::getGameContentTypeSupport(const sp<IBinder>& display) { + bool supported = false; + ComposerService::getComposerService()->getGameContentTypeSupport(display, &supported); + return supported; +} + +void SurfaceComposerClient::setGameContentType(const sp<IBinder>& display, bool on) { + ComposerService::getComposerService()->setGameContentType(display, on); +} + void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token, int mode) { ComposerService::getComposerService()->setPowerMode(token, mode); @@ -1553,30 +1897,36 @@ status_t SurfaceComposerClient::notifyPowerHint(int32_t hintId) { return ComposerService::getComposerService()->notifyPowerHint(hintId); } +status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColor, + const half4& spotColor, float lightPosY, + float lightPosZ, float lightRadius) { + return ComposerService::getComposerService()->setGlobalShadowSettings(ambientColor, spotColor, + lightPosY, lightPosZ, + lightRadius); +} + // ---------------------------------------------------------------------------- -status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, - const ui::PixelFormat reqPixelFormat, Rect sourceCrop, +status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace, + ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - uint32_t rotation, bool captureSecureLayers, + ui::Rotation rotation, bool captureSecureLayers, sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == nullptr) return NO_INIT; - status_t ret = - s->captureScreen(display, outBuffer, outCapturedSecureLayers, reqDataSpace, - reqPixelFormat, sourceCrop, reqWidth, reqHeight, useIdentityTransform, - static_cast<ISurfaceComposer::Rotation>(rotation), - captureSecureLayers); + status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, reqDataSpace, + reqPixelFormat, sourceCrop, reqWidth, reqHeight, + useIdentityTransform, rotation, captureSecureLayers); if (ret != NO_ERROR) { return ret; } return ret; } -status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, - const ui::PixelFormat reqPixelFormat, Rect sourceCrop, +status_t ScreenshotClient::capture(const sp<IBinder>& display, ui::Dataspace reqDataSpace, + ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, - uint32_t rotation, sp<GraphicBuffer>* outBuffer) { + ui::Rotation rotation, sp<GraphicBuffer>* outBuffer) { bool ignored; return capture(display, reqDataSpace, reqPixelFormat, sourceCrop, reqWidth, reqHeight, useIdentityTransform, rotation, false, outBuffer, ignored); @@ -1589,9 +1939,8 @@ status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace* return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer); } -status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, - const ui::Dataspace reqDataSpace, - const ui::PixelFormat reqPixelFormat, Rect sourceCrop, +status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace, + ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == nullptr) return NO_INIT; @@ -1601,8 +1950,8 @@ status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, } status_t ScreenshotClient::captureChildLayers( - const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace, - const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + const sp<IBinder>& layerHandle, ui::Dataspace reqDataSpace, ui::PixelFormat reqPixelFormat, + const Rect& sourceCrop, const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& excludeHandles, float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); @@ -1612,5 +1961,5 @@ status_t ScreenshotClient::captureChildLayers( excludeHandles, frameScale, true /* childrenOnly */); return ret; } -// ---------------------------------------------------------------------------- -}; // namespace android + +} // namespace android |