summaryrefslogtreecommitdiff
path: root/libs/gui/SurfaceComposerClient.cpp
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2022-08-16 19:08:21 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2022-08-16 19:08:21 +0000
commit44732cde9e19a005def5e110140963a5c2e2f5ae (patch)
tree9a4deff758bed03ccc5ff838dc55f467c303d762 /libs/gui/SurfaceComposerClient.cpp
parent896cdca96956b6f14e262380b34a0b04e1214b50 (diff)
parent91192c8103e78895c57d9da1fc04c8695898580f (diff)
Merge "DO NOT MERGE - Merge Android 13"
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r--libs/gui/SurfaceComposerClient.cpp511
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