diff options
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 1019 |
1 files changed, 911 insertions, 108 deletions
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 100257629e..def9fe937c 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -25,7 +25,9 @@ #include <utils/String8.h> #include <utils/threads.h> +#include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> +#include <binder/ProcessState.h> #include <system/graphics.h> @@ -40,8 +42,15 @@ #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> +#ifndef NO_INPUT +#include <input/InputWindow.h> +#endif + #include <private/gui/ComposerService.h> +// This server size should always be smaller than the server cache size +#define BUFFER_CACHE_MAX_SIZE 64 + namespace android { using ui::ColorMode; @@ -60,7 +69,7 @@ void ComposerService::connectLocked() { while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); } - assert(mComposerService != NULL); + assert(mComposerService != nullptr); // Create the death listener. class DeathObserver : public IBinder::DeathRecipient { @@ -81,9 +90,9 @@ void ComposerService::connectLocked() { /*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() { ComposerService& instance = ComposerService::getInstance(); Mutex::Autolock _l(instance.mLock); - if (instance.mComposerService == NULL) { + if (instance.mComposerService == nullptr) { ComposerService::getInstance().connectLocked(); - assert(instance.mComposerService != NULL); + assert(instance.mComposerService != nullptr); ALOGD("ComposerService reconnected"); } return instance.mComposerService; @@ -92,19 +101,231 @@ void ComposerService::connectLocked() { void ComposerService::composerServiceDied() { Mutex::Autolock _l(mLock); - mComposerService = NULL; - mDeathObserver = NULL; + mComposerService = nullptr; + mDeathObserver = nullptr; +} + +class DefaultComposerClient: public Singleton<DefaultComposerClient> { + Mutex mLock; + sp<SurfaceComposerClient> mClient; + friend class Singleton<ComposerService>; +public: + static sp<SurfaceComposerClient> getComposerClient() { + DefaultComposerClient& dc = DefaultComposerClient::getInstance(); + Mutex::Autolock _l(dc.mLock); + if (dc.mClient == nullptr) { + dc.mClient = new SurfaceComposerClient; + } + return dc.mClient; + } +}; +ANDROID_SINGLETON_STATIC_INSTANCE(DefaultComposerClient); + + +sp<SurfaceComposerClient> SurfaceComposerClient::getDefault() { + return DefaultComposerClient::getComposerClient(); } // --------------------------------------------------------------------------- -SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : - mForceSynchronous(other.mForceSynchronous), - mTransactionNestCount(other.mTransactionNestCount), - mAnimation(other.mAnimation), - mEarlyWakeup(other.mEarlyWakeup) { +// TransactionCompletedListener does not use ANDROID_SINGLETON_STATIC_INSTANCE because it needs +// to be able to return a sp<> to its instance to pass to SurfaceFlinger. +// ANDROID_SINGLETON_STATIC_INSTANCE only allows a reference to an instance. + +// 0 is an invalid callback id +TransactionCompletedListener::TransactionCompletedListener() : mCallbackIdCounter(1) {} + +CallbackId TransactionCompletedListener::getNextIdLocked() { + return mCallbackIdCounter++; +} + +sp<TransactionCompletedListener> TransactionCompletedListener::getInstance() { + static sp<TransactionCompletedListener> sInstance = new TransactionCompletedListener; + return sInstance; +} + +sp<ITransactionCompletedListener> TransactionCompletedListener::getIInstance() { + return static_cast<sp<ITransactionCompletedListener>>(getInstance()); +} + +void TransactionCompletedListener::startListeningLocked() { + if (mListening) { + return; + } + ProcessState::self()->startThreadPool(); + mListening = true; +} + +CallbackId TransactionCompletedListener::addCallbackFunction( + const TransactionCompletedCallback& callbackFunction, + const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>& + surfaceControls) { + std::lock_guard<std::mutex> lock(mMutex); + startListeningLocked(); + + CallbackId callbackId = getNextIdLocked(); + mCallbacks[callbackId].callbackFunction = callbackFunction; + + auto& callbackSurfaceControls = mCallbacks[callbackId].surfaceControls; + + for (const auto& surfaceControl : surfaceControls) { + callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl; + } + + return callbackId; +} + +void TransactionCompletedListener::addSurfaceControlToCallbacks( + const sp<SurfaceControl>& surfaceControl, + const std::unordered_set<CallbackId>& callbackIds) { + std::lock_guard<std::mutex> lock(mMutex); + + for (auto callbackId : callbackIds) { + mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct, + std::forward_as_tuple( + surfaceControl->getHandle()), + std::forward_as_tuple(surfaceControl)); + } +} + +void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { + 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()); + } + } + + for (const auto& transactionStats : listenerStats.transactionStats) { + for (auto callbackId : transactionStats.callbackIds) { + auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[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); + } + + callbackFunction(transactionStats.latchTime, transactionStats.presentFence, + surfaceControlStats); + mCallbacks.erase(callbackId); + } + } +} + +// --------------------------------------------------------------------------- + +void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId); + +class BufferCache : public Singleton<BufferCache> { +public: + BufferCache() : token(new BBinder()) {} + + sp<IBinder> getToken() { + return IInterface::asBinder(TransactionCompletedListener::getIInstance()); + } + + status_t getCacheId(const sp<GraphicBuffer>& buffer, uint64_t* cacheId) { + std::lock_guard<std::mutex> lock(mMutex); + + auto itr = mBuffers.find(buffer->getId()); + if (itr == mBuffers.end()) { + return BAD_VALUE; + } + itr->second = getCounter(); + *cacheId = buffer->getId(); + return NO_ERROR; + } + + uint64_t cache(const sp<GraphicBuffer>& buffer) { + std::lock_guard<std::mutex> lock(mMutex); + + if (mBuffers.size() >= BUFFER_CACHE_MAX_SIZE) { + evictLeastRecentlyUsedBuffer(); + } + + buffer->addDeathCallback(bufferCacheCallback, nullptr); + + mBuffers[buffer->getId()] = getCounter(); + return buffer->getId(); + } + + 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); + } + +private: + void evictLeastRecentlyUsedBuffer() REQUIRES(mMutex) { + auto itr = mBuffers.begin(); + uint64_t minCounter = itr->second; + auto minBuffer = itr; + itr++; + + while (itr != mBuffers.end()) { + uint64_t counter = itr->second; + if (counter < minCounter) { + minCounter = counter; + minBuffer = itr; + } + itr++; + } + uncacheLocked(minBuffer->first); + } + + uint64_t getCounter() REQUIRES(mMutex) { + static uint64_t counter = 0; + return counter++; + } + + std::mutex mMutex; + std::map<uint64_t /*Cache id*/, uint64_t /*counter*/> mBuffers GUARDED_BY(mMutex); + + // Used by ISurfaceComposer to identify which process is sending the cached buffer. + sp<IBinder> token; +}; + +ANDROID_SINGLETON_STATIC_INSTANCE(BufferCache); + +void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId) { + // GraphicBuffer id's are used as the cache ids. + BufferCache::getInstance().uncache(graphicBufferId); +} + +// --------------------------------------------------------------------------- + +SurfaceComposerClient::Transaction::Transaction(const Transaction& other) + : mForceSynchronous(other.mForceSynchronous), + mTransactionNestCount(other.mTransactionNestCount), + mAnimation(other.mAnimation), + mEarlyWakeup(other.mEarlyWakeup), + mDesiredPresentTime(other.mDesiredPresentTime) { mDisplayStates = other.mDisplayStates; mComposerStates = other.mComposerStates; + mInputWindowCommands = other.mInputWindowCommands; } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { @@ -127,9 +348,96 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr } 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())); + } + other.mListenerCallbacks.clear(); + + mInputWindowCommands.merge(other.mInputWindowCommands); + other.mInputWindowCommands.clear(); + + mContainsBuffer = other.mContainsBuffer; + other.mContainsBuffer = false; + + mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup; + other.mEarlyWakeup = false; + 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::doUncacheBufferTransaction(uint64_t cacheId) { + sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + + client_cache_t uncacheBuffer; + uncacheBuffer.token = BufferCache::getInstance().getToken(); + uncacheBuffer.id = cacheId; + + sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); + sf->setTransactionState({}, {}, 0, applyToken, {}, -1, uncacheBuffer, {}); +} + +void SurfaceComposerClient::Transaction::cacheBuffers() { + if (!mContainsBuffer) { + return; + } + + size_t count = 0; + for (auto& [sc, cs] : mComposerStates) { + layer_state_t* s = getLayerState(sc); + if (!(s->what & layer_state_t::eBufferChanged)) { + continue; + } + + // 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) { + continue; + } + + uint64_t cacheId = 0; + status_t ret = BufferCache::getInstance().getCacheId(s->buffer, &cacheId); + if (ret == NO_ERROR) { + s->what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged); + s->buffer = nullptr; + } else { + cacheId = BufferCache::getInstance().cache(s->buffer); + } + s->what |= layer_state_t::eCachedBufferChanged; + s->cachedBuffer.token = BufferCache::getInstance().getToken(); + s->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 + count++; + if (count >= BUFFER_CACHE_MAX_SIZE) { + break; + } + } +} + status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { if (mStatus != NO_ERROR) { return mStatus; @@ -137,6 +445,32 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + std::vector<ListenerCallbacks> listenerCallbacks; + + // For every listener with registered callbacks + for (const auto& [listener, callbackInfo] : mListenerCallbacks) { + auto& [callbackIds, surfaceControls] = callbackInfo; + if (callbackIds.empty()) { + 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; + } + s->what |= layer_state_t::eHasListenerCallbacksChanged; + s->hasListenerCallbacks = true; + } + } + mListenerCallbacks.clear(); + + cacheBuffers(); + Vector<ComposerState> composerStates; Vector<DisplayState> displayStates; uint32_t flags = 0; @@ -166,7 +500,12 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { mAnimation = false; mEarlyWakeup = false; - sf->setTransactionState(composerStates, displayStates, flags); + sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance()); + sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands, + mDesiredPresentTime, + {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/, + listenerCallbacks); + mInputWindowCommands.clear(); mStatus = NO_ERROR; return NO_ERROR; } @@ -182,8 +521,20 @@ void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) { return ComposerService::getComposerService()->destroyDisplay(display); } -sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { - return ComposerService::getComposerService()->getBuiltInDisplay(id); +std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() { + return ComposerService::getComposerService()->getPhysicalDisplayIds(); +} + +std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() { + return ComposerService::getComposerService()->getInternalDisplayId(); +} + +sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) { + return ComposerService::getComposerService()->getPhysicalDisplayToken(displayId); +} + +sp<IBinder> SurfaceComposerClient::getInternalDisplayToken() { + return ComposerService::getComposerService()->getInternalDisplayToken(); } void SurfaceComposerClient::Transaction::setAnimationTransaction() { @@ -206,6 +557,15 @@ layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<Surfac return &(mComposerStates[sc].state); } +void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( + const sp<SurfaceControl>& sc) { + auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()]; + callbackInfo.surfaceControls.insert(sc); + + TransactionCompletedListener::getInstance() + ->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds); +} + SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( const sp<SurfaceControl>& sc, float x, float y) { layer_state_t* s = getLayerState(sc); @@ -216,6 +576,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosit s->what |= layer_state_t::ePositionChanged; s->x = x; s->y = y; + + registerSurfaceControlForCallback(sc); return *this; } @@ -240,9 +602,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSize( s->w = w; s->h = h; - // Resizing a surface makes the transaction synchronous. - mForceSynchronous = true; - + registerSurfaceControlForCallback(sc); return *this; } @@ -254,7 +614,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer return *this; } s->what |= layer_state_t::eLayerChanged; + s->what &= ~layer_state_t::eRelativeLayerChanged; s->z = z; + + registerSurfaceControlForCallback(sc); return *this; } @@ -265,8 +628,11 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelat mStatus = BAD_INDEX; } s->what |= layer_state_t::eRelativeLayerChanged; + s->what &= ~layer_state_t::eLayerChanged; s->relativeLayerHandle = relativeTo; s->z = z; + + registerSurfaceControlForCallback(sc); return *this; } @@ -286,6 +652,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags s->flags &= ~mask; s->flags |= (flags & mask); s->mask |= mask; + + registerSurfaceControlForCallback(sc); return *this; } @@ -299,6 +667,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans } s->what |= layer_state_t::eTransparentRegionChanged; s->transparentRegion = transparentRegion; + + registerSurfaceControlForCallback(sc); return *this; } @@ -311,6 +681,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha } s->what |= layer_state_t::eAlphaChanged; s->alpha = alpha; + + registerSurfaceControlForCallback(sc); return *this; } @@ -323,6 +695,22 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer } s->what |= layer_state_t::eLayerStackChanged; s->layerStack = layerStack; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMetadata( + const sp<SurfaceControl>& sc, uint32_t key, std::vector<uint8_t> data) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eMetadataChanged; + s->metadata.mMap[key] = std::move(data); + + registerSurfaceControlForCallback(sc); return *this; } @@ -341,57 +729,68 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatri matrix.dsdy = dsdy; matrix.dtdy = dtdy; s->matrix = matrix; + + registerSurfaceControlForCallback(sc); return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop_legacy( const sp<SurfaceControl>& sc, const Rect& crop) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eCropChanged; - s->crop = crop; + s->what |= layer_state_t::eCropChanged_legacy; + s->crop_legacy = crop; + + registerSurfaceControlForCallback(sc); return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFinalCrop(const sp<SurfaceControl>& sc, const Rect& crop) { +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCornerRadius( + const sp<SurfaceControl>& sc, float cornerRadius) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eFinalCropChanged; - s->finalCrop = crop; + s->what |= layer_state_t::eCornerRadiusChanged; + s->cornerRadius = cornerRadius; return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil( - const sp<SurfaceControl>& sc, - const sp<IBinder>& handle, uint64_t frameNumber) { +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp<SurfaceControl>& sc, + const sp<IBinder>& handle, + uint64_t frameNumber) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eDeferTransaction; - s->barrierHandle = handle; - s->frameNumber = frameNumber; + s->what |= layer_state_t::eDeferTransaction_legacy; + s->barrierHandle_legacy = handle; + s->frameNumber_legacy = frameNumber; + + registerSurfaceControlForCallback(sc); return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::deferTransactionUntil( - const sp<SurfaceControl>& sc, - const sp<Surface>& barrierSurface, uint64_t frameNumber) { +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::deferTransactionUntil_legacy(const sp<SurfaceControl>& sc, + const sp<Surface>& barrierSurface, + uint64_t frameNumber) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eDeferTransaction; - s->barrierGbp = barrierSurface->getIGraphicBufferProducer(); - s->frameNumber = frameNumber; + s->what |= layer_state_t::eDeferTransaction_legacy; + s->barrierGbp_legacy = barrierSurface->getIGraphicBufferProducer(); + s->frameNumber_legacy = frameNumber; + + registerSurfaceControlForCallback(sc); return *this; } @@ -405,6 +804,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent } s->what |= layer_state_t::eReparentChildren; s->reparentHandle = newParentHandle; + + registerSurfaceControlForCallback(sc); return *this; } @@ -418,6 +819,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::reparent } s->what |= layer_state_t::eReparent; s->parentHandleForChild = newParentHandle; + + registerSurfaceControlForCallback(sc); return *this; } @@ -431,6 +834,219 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor } s->what |= layer_state_t::eColorChanged; s->color = color; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundColor( + const sp<SurfaceControl>& sc, const half3& color, float alpha, ui::Dataspace dataspace) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + + s->what |= layer_state_t::eBackgroundColorChanged; + s->color = color; + s->bgColorAlpha = alpha; + s->bgColorDataspace = dataspace; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTransform( + const sp<SurfaceControl>& sc, uint32_t transform) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eTransformChanged; + s->transform = transform; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp<SurfaceControl>& sc, + bool transformToDisplayInverse) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eTransformToDisplayInverseChanged; + s->transformToDisplayInverse = transformToDisplayInverse; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( + const sp<SurfaceControl>& sc, const Rect& crop) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eCropChanged; + s->crop = crop; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame( + const sp<SurfaceControl>& sc, const Rect& frame) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eFrameChanged; + s->frame = frame; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( + const sp<SurfaceControl>& sc, const sp<GraphicBuffer>& buffer) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eBufferChanged; + s->buffer = buffer; + + registerSurfaceControlForCallback(sc); + + mContainsBuffer = true; + return *this; +} + +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; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDataspace( + const sp<SurfaceControl>& sc, ui::Dataspace dataspace) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eDataspaceChanged; + s->dataspace = dataspace; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setHdrMetadata( + const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eHdrMetadataChanged; + s->hdrMetadata = hdrMetadata; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSurfaceDamageRegion( + const sp<SurfaceControl>& sc, const Region& surfaceDamageRegion) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eSurfaceDamageRegionChanged; + s->surfaceDamageRegion = surfaceDamageRegion; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApi( + const sp<SurfaceControl>& sc, int32_t api) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eApiChanged; + s->api = api; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSidebandStream( + const sp<SurfaceControl>& sc, const sp<NativeHandle>& sidebandStream) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eSidebandStreamChanged; + s->sidebandStream = sidebandStream; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesiredPresentTime( + nsecs_t desiredPresentTime) { + mDesiredPresentTime = desiredPresentTime; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorSpaceAgnostic( + const sp<SurfaceControl>& sc, const bool agnostic) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eColorSpaceAgnosticChanged; + s->colorSpaceAgnostic = agnostic; + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& +SurfaceComposerClient::Transaction::addTransactionCompletedCallback( + TransactionCompletedCallbackTakesContext callback, void* callbackContext) { + auto listener = TransactionCompletedListener::getInstance(); + + auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3); + const auto& surfaceControls = + mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls; + + CallbackId callbackId = listener->addCallbackFunction(callbackWithContext, surfaceControls); + + mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( + callbackId); return *this; } @@ -441,6 +1057,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::detachCh mStatus = BAD_INDEX; } s->what |= layer_state_t::eDetachChildren; + + registerSurfaceControlForCallback(sc); return *this; } @@ -468,6 +1086,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setOverr s->what |= layer_state_t::eOverrideScalingModeChanged; s->overrideScalingMode = overrideScalingMode; + + registerSurfaceControlForCallback(sc); return *this; } @@ -479,17 +1099,104 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeome return *this; } s->what |= layer_state_t::eGeometryAppliesWithResize; + + registerSurfaceControlForCallback(sc); return *this; } -SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface( - const sp<SurfaceControl>& sc) { +#ifndef NO_INPUT +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInputWindowInfo( + const sp<SurfaceControl>& sc, + const InputWindowInfo& info) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } - s->what |= layer_state_t::eDestroySurface; + s->inputInfo = info; + s->what |= layer_state_t::eInputInfoChanged; + 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; +} + +#endif + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorTransform( + const sp<SurfaceControl>& sc, const mat3& matrix, const vec3& translation) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eColorTransformChanged; + s->colorTransform = mat4(matrix, translation); + + registerSurfaceControlForCallback(sc); + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeometry( + const sp<SurfaceControl>& sc, const Rect& source, const Rect& dst, int transform) { + setCrop_legacy(sc, source); + + int x = dst.left; + int y = dst.top; + + float sourceWidth = source.getWidth(); + float sourceHeight = source.getHeight(); + + float xScale = sourceWidth < 0 ? 1.0f : dst.getWidth() / sourceWidth; + float yScale = sourceHeight < 0 ? 1.0f : dst.getHeight() / sourceHeight; + float matrix[4] = {1, 0, 0, 1}; + + switch (transform) { + case NATIVE_WINDOW_TRANSFORM_FLIP_H: + matrix[0] = -xScale; matrix[1] = 0; + matrix[2] = 0; matrix[3] = yScale; + x += source.getWidth(); + break; + case NATIVE_WINDOW_TRANSFORM_FLIP_V: + matrix[0] = xScale; matrix[1] = 0; + matrix[2] = 0; matrix[3] = -yScale; + y += source.getHeight(); + break; + case NATIVE_WINDOW_TRANSFORM_ROT_90: + matrix[0] = 0; matrix[1] = -yScale; + matrix[2] = xScale; matrix[3] = 0; + x += source.getHeight(); + break; + case NATIVE_WINDOW_TRANSFORM_ROT_180: + matrix[0] = -xScale; matrix[1] = 0; + matrix[2] = 0; matrix[3] = -yScale; + x += source.getWidth(); + y += source.getHeight(); + break; + case NATIVE_WINDOW_TRANSFORM_ROT_270: + matrix[0] = 0; matrix[1] = yScale; + matrix[2] = -xScale; matrix[3] = 0; + y += source.getWidth(); + break; + default: + matrix[0] = xScale; matrix[1] = 0; + matrix[2] = 0; matrix[3] = yScale; + break; + } + setMatrix(sc, matrix[0], matrix[1], matrix[2], matrix[3]); + setPosition(sc, x, y); + return *this; } @@ -559,11 +1266,6 @@ SurfaceComposerClient::SurfaceComposerClient() { } -SurfaceComposerClient::SurfaceComposerClient(const sp<IGraphicBufferProducer>& root) - : mStatus(NO_INIT), mParent(root) -{ -} - SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client) : mStatus(NO_ERROR), mClient(client) { @@ -571,12 +1273,10 @@ SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& c void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - if (sf != 0 && mStatus == NO_INIT) { - auto rootProducer = mParent.promote(); + if (sf != nullptr && mStatus == NO_INIT) { sp<ISurfaceComposerClient> conn; - conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) : - sf->createConnection(); - if (conn != 0) { + conn = sf->createConnection(); + if (conn != nullptr) { mClient = conn; mStatus = NO_ERROR; } @@ -606,39 +1306,49 @@ void SurfaceComposerClient::dispose() { // this can be called more than once. sp<ISurfaceComposerClient> client; Mutex::Autolock _lm(mLock); - if (mClient != 0) { + if (mClient != nullptr) { client = mClient; // hold ref while lock is held mClient.clear(); } mStatus = NO_INIT; } -sp<SurfaceControl> SurfaceComposerClient::createSurface( - const String8& name, - uint32_t w, - uint32_t h, - PixelFormat format, - uint32_t flags, - SurfaceControl* parent, - int32_t windowType, - int32_t ownerUid) -{ +sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags, + SurfaceControl* parent, + LayerMetadata metadata) { sp<SurfaceControl> s; - createSurfaceChecked(name, w, h, format, &s, flags, parent, windowType, ownerUid); + createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata)); return s; } -status_t SurfaceComposerClient::createSurfaceChecked( - const String8& name, - uint32_t w, - uint32_t h, - PixelFormat format, - sp<SurfaceControl>* outSurface, - uint32_t flags, - SurfaceControl* parent, - int32_t windowType, - int32_t ownerUid) -{ +sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w, + uint32_t h, PixelFormat format, + uint32_t flags, Surface* parent, + LayerMetadata metadata) { + sp<SurfaceControl> sur; + status_t err = mStatus; + + if (mStatus == NO_ERROR) { + sp<IBinder> handle; + sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer(); + sp<IGraphicBufferProducer> gbp; + + err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp, + std::move(metadata), &handle, &gbp); + ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err)); + if (err == NO_ERROR) { + return new SurfaceControl(this, handle, gbp, true /* owned */); + } + } + return nullptr; +} + +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) { sp<SurfaceControl> sur; status_t err = mStatus; @@ -650,8 +1360,9 @@ status_t SurfaceComposerClient::createSurfaceChecked( if (parent != nullptr) { parentHandle = parent->getHandle(); } - err = mClient->createSurface(name, w, h, format, flags, parentHandle, - windowType, ownerUid, &handle, &gbp); + + err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata), + &handle, &gbp); ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err)); if (err == NO_ERROR) { *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); @@ -660,13 +1371,6 @@ status_t SurfaceComposerClient::createSurfaceChecked( return err; } -status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { - if (mStatus != NO_ERROR) - return mStatus; - status_t err = mClient->destroySurface(sid); - return err; -} - status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const { if (mStatus != NO_ERROR) { return mStatus; @@ -718,10 +1422,6 @@ status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display, return NO_ERROR; } -status_t SurfaceComposerClient::getDisplayViewport(const sp<IBinder>& display, Rect* outViewport) { - return ComposerService::getComposerService()->getDisplayViewport(display, outViewport); -} - int SurfaceComposerClient::getActiveConfig(const sp<IBinder>& display) { return ComposerService::getComposerService()->getActiveConfig(display); } @@ -730,11 +1430,28 @@ status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int 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::getAllowedDisplayConfigs(const sp<IBinder>& displayToken, + std::vector<int32_t>* outAllowedConfigs) { + return ComposerService::getComposerService()->getAllowedDisplayConfigs(displayToken, + outAllowedConfigs); +} + status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display, Vector<ColorMode>* outColorModes) { return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes); } +status_t SurfaceComposerClient::getDisplayNativePrimaries(const sp<IBinder>& display, + ui::DisplayPrimaries& outPrimaries) { + return ComposerService::getComposerService()->getDisplayNativePrimaries(display, outPrimaries); +} + ColorMode SurfaceComposerClient::getActiveColorMode(const sp<IBinder>& display) { return ComposerService::getComposerService()->getActiveColorMode(display); } @@ -749,6 +1466,20 @@ void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token, ComposerService::getComposerService()->setPowerMode(token, mode); } +status_t SurfaceComposerClient::getCompositionPreference( + ui::Dataspace* defaultDataspace, ui::PixelFormat* defaultPixelFormat, + ui::Dataspace* wideColorGamutDataspace, ui::PixelFormat* wideColorGamutPixelFormat) { + return ComposerService::getComposerService() + ->getCompositionPreference(defaultDataspace, defaultPixelFormat, + wideColorGamutDataspace, wideColorGamutPixelFormat); +} + +bool SurfaceComposerClient::getProtectedContentSupport() { + bool supported = false; + ComposerService::getComposerService()->getProtectedContentSupport(&supported); + return supported; +} + status_t SurfaceComposerClient::clearAnimationFrameStats() { return ComposerService::getComposerService()->clearAnimationFrameStats(); } @@ -763,49 +1494,121 @@ status_t SurfaceComposerClient::getHdrCapabilities(const sp<IBinder>& display, outCapabilities); } +status_t SurfaceComposerClient::getDisplayedContentSamplingAttributes(const sp<IBinder>& display, + ui::PixelFormat* outFormat, + ui::Dataspace* outDataspace, + uint8_t* outComponentMask) { + return ComposerService::getComposerService() + ->getDisplayedContentSamplingAttributes(display, outFormat, outDataspace, + outComponentMask); +} + +status_t SurfaceComposerClient::setDisplayContentSamplingEnabled(const sp<IBinder>& display, + bool enable, uint8_t componentMask, + uint64_t maxFrames) { + return ComposerService::getComposerService()->setDisplayContentSamplingEnabled(display, enable, + componentMask, + maxFrames); +} + +status_t SurfaceComposerClient::getDisplayedContentSample(const sp<IBinder>& display, + uint64_t maxFrames, uint64_t timestamp, + DisplayedFrameStats* outStats) { + return ComposerService::getComposerService()->getDisplayedContentSample(display, maxFrames, + timestamp, outStats); +} + +status_t SurfaceComposerClient::isWideColorDisplay(const sp<IBinder>& display, + bool* outIsWideColorDisplay) { + return ComposerService::getComposerService()->isWideColorDisplay(display, + outIsWideColorDisplay); +} + +status_t SurfaceComposerClient::addRegionSamplingListener( + const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, + const sp<IRegionSamplingListener>& listener) { + return ComposerService::getComposerService()->addRegionSamplingListener(samplingArea, + stopLayerHandle, + listener); +} + +status_t SurfaceComposerClient::removeRegionSamplingListener( + const sp<IRegionSamplingListener>& listener) { + return ComposerService::getComposerService()->removeRegionSamplingListener(listener); +} + +bool SurfaceComposerClient::getDisplayBrightnessSupport(const sp<IBinder>& displayToken) { + bool support = false; + ComposerService::getComposerService()->getDisplayBrightnessSupport(displayToken, &support); + return support; +} + +status_t SurfaceComposerClient::setDisplayBrightness(const sp<IBinder>& displayToken, + float brightness) { + return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness); +} + +status_t SurfaceComposerClient::notifyPowerHint(int32_t hintId) { + return ComposerService::getComposerService()->notifyPowerHint(hintId); +} + // ---------------------------------------------------------------------------- -status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, - uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, - bool useIdentityTransform, uint32_t rotation, - bool captureSecureLayers, sp<GraphicBuffer>* outBuffer, - bool& outCapturedSecureLayers) { +status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, + uint32_t rotation, bool captureSecureLayers, + sp<GraphicBuffer>* outBuffer, bool& outCapturedSecureLayers) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; - status_t ret = s->captureScreen(display, outBuffer, outCapturedSecureLayers, sourceCrop, - reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform, - static_cast<ISurfaceComposer::Rotation>(rotation), - captureSecureLayers); + 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); if (ret != NO_ERROR) { return ret; } return ret; } -status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth, - uint32_t reqHeight, int32_t minLayerZ, int32_t maxLayerZ, - bool useIdentityTransform, uint32_t rotation, - sp<GraphicBuffer>* outBuffer) { +status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, + uint32_t rotation, sp<GraphicBuffer>* outBuffer) { bool ignored; - return capture(display, sourceCrop, reqWidth, reqHeight, - minLayerZ, maxLayerZ, useIdentityTransform, rotation, false, outBuffer, ignored); + return capture(display, reqDataSpace, reqPixelFormat, sourceCrop, reqWidth, reqHeight, + useIdentityTransform, rotation, false, outBuffer, ignored); +} + +status_t ScreenshotClient::capture(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, + sp<GraphicBuffer>* outBuffer) { + sp<ISurfaceComposer> s(ComposerService::getComposerService()); + if (s == nullptr) return NO_INIT; + return s->captureScreen(displayOrLayerStack, outDataspace, outBuffer); } -status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, +status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, + const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; - status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale, - false /* childrenOnly */); + if (s == nullptr) return NO_INIT; + status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat, + sourceCrop, {}, frameScale, false /* childrenOnly */); return ret; } -status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, - float frameScale, sp<GraphicBuffer>* outBuffer) { +status_t ScreenshotClient::captureChildLayers( + const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace, + const ui::PixelFormat reqPixelFormat, Rect sourceCrop, + const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& excludeHandles, + float frameScale, sp<GraphicBuffer>* outBuffer) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); - if (s == NULL) return NO_INIT; - status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale, - true /* childrenOnly */); + if (s == nullptr) return NO_INIT; + status_t ret = + s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop, + excludeHandles, frameScale, true /* childrenOnly */); return ret; } // ---------------------------------------------------------------------------- |