Loading libs/gui/LayerState.cpp +30 −27 Original line number Diff line number Diff line Loading @@ -153,7 +153,8 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeBool, isTrustedOverlay); SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode)); SAFE_PARCEL(bufferData.write, output); SAFE_PARCEL(output.writeNullableParcelable, bufferData ? std::make_optional<BufferData>(*bufferData) : std::nullopt); return NO_ERROR; } Loading Loading @@ -263,7 +264,9 @@ status_t layer_state_t::read(const Parcel& input) uint32_t mode; SAFE_PARCEL(input.readUint32, &mode); dropInputMode = static_cast<gui::DropInputMode>(mode); SAFE_PARCEL(bufferData.read, input); std::optional<BufferData> tmpBufferData; SAFE_PARCEL(input.readParcelable, &tmpBufferData); bufferData = tmpBufferData ? std::make_shared<BufferData>(*tmpBufferData) : nullptr; return NO_ERROR; } Loading Loading @@ -518,7 +521,7 @@ bool layer_state_t::hasBufferChanges() const { } bool layer_state_t::hasValidBuffer() const { return bufferData.buffer || bufferData.cachedBuffer.isValid(); return bufferData && (bufferData->buffer || bufferData->cachedBuffer.isValid()); } status_t layer_state_t::matrix22_t::write(Parcel& output) const { Loading Loading @@ -681,64 +684,64 @@ ReleaseCallbackId BufferData::generateReleaseCallbackId() const { return {buffer->getId(), frameNumber}; } status_t BufferData::write(Parcel& output) const { SAFE_PARCEL(output.writeInt32, flags.get()); status_t BufferData::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt32, flags.get()); if (buffer) { SAFE_PARCEL(output.writeBool, true); SAFE_PARCEL(output.write, *buffer); SAFE_PARCEL(output->writeBool, true); SAFE_PARCEL(output->write, *buffer); } else { SAFE_PARCEL(output.writeBool, false); SAFE_PARCEL(output->writeBool, false); } if (acquireFence) { SAFE_PARCEL(output.writeBool, true); SAFE_PARCEL(output.write, *acquireFence); SAFE_PARCEL(output->writeBool, true); SAFE_PARCEL(output->write, *acquireFence); } else { SAFE_PARCEL(output.writeBool, false); SAFE_PARCEL(output->writeBool, false); } SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(releaseBufferListener)); SAFE_PARCEL(output.writeStrongBinder, releaseBufferEndpoint); SAFE_PARCEL(output->writeUint64, frameNumber); SAFE_PARCEL(output->writeStrongBinder, IInterface::asBinder(releaseBufferListener)); SAFE_PARCEL(output->writeStrongBinder, releaseBufferEndpoint); SAFE_PARCEL(output.writeStrongBinder, cachedBuffer.token.promote()); SAFE_PARCEL(output.writeUint64, cachedBuffer.id); SAFE_PARCEL(output->writeStrongBinder, cachedBuffer.token.promote()); SAFE_PARCEL(output->writeUint64, cachedBuffer.id); return NO_ERROR; } status_t BufferData::read(const Parcel& input) { status_t BufferData::readFromParcel(const Parcel* input) { int32_t tmpInt32; SAFE_PARCEL(input.readInt32, &tmpInt32); SAFE_PARCEL(input->readInt32, &tmpInt32); flags = Flags<BufferDataChange>(tmpInt32); bool tmpBool = false; SAFE_PARCEL(input.readBool, &tmpBool); SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { buffer = new GraphicBuffer(); SAFE_PARCEL(input.read, *buffer); SAFE_PARCEL(input->read, *buffer); } SAFE_PARCEL(input.readBool, &tmpBool); SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { acquireFence = new Fence(); SAFE_PARCEL(input.read, *acquireFence); SAFE_PARCEL(input->read, *acquireFence); } SAFE_PARCEL(input.readUint64, &frameNumber); SAFE_PARCEL(input->readUint64, &frameNumber); sp<IBinder> tmpBinder = nullptr; SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder); SAFE_PARCEL(input->readNullableStrongBinder, &tmpBinder); if (tmpBinder) { releaseBufferListener = checked_interface_cast<ITransactionCompletedListener>(tmpBinder); } SAFE_PARCEL(input.readNullableStrongBinder, &releaseBufferEndpoint); SAFE_PARCEL(input->readNullableStrongBinder, &releaseBufferEndpoint); tmpBinder = nullptr; SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder); SAFE_PARCEL(input->readNullableStrongBinder, &tmpBinder); cachedBuffer.token = tmpBinder; SAFE_PARCEL(input.readUint64, &cachedBuffer.id); SAFE_PARCEL(input->readUint64, &cachedBuffer.id); return NO_ERROR; } Loading libs/gui/SurfaceComposerClient.cpp +29 −29 Original line number Diff line number Diff line Loading @@ -728,18 +728,18 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_ return; } auto listener = state.bufferData.releaseBufferListener; auto listener = state.bufferData->releaseBufferListener; sp<Fence> fence = state.bufferData.acquireFence ? state.bufferData.acquireFence : Fence::NO_FENCE; if (state.bufferData.releaseBufferEndpoint == 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); .addReleaseCallback(state.bufferData->generateReleaseCallbackId(), fence); } else { listener->onReleaseBuffer(state.bufferData.generateReleaseCallbackId(), fence, UINT_MAX); listener->onReleaseBuffer(state.bufferData->generateReleaseCallbackId(), fence, UINT_MAX); } } Loading Loading @@ -839,7 +839,8 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { layer_state_t* s = &(mComposerStates[handle].state); if (!(s->what & layer_state_t::eBufferChanged)) { continue; } else if (s->bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged)) { } 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. Loading @@ -848,22 +849,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->bufferData.buffer) { if (!s->bufferData || !s->bufferData->buffer) { continue; } uint64_t cacheId = 0; status_t ret = BufferCache::getInstance().getCacheId(s->bufferData.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->bufferData.buffer = nullptr; s->bufferData->buffer = nullptr; } else { // Cache-miss. Include the buffer and send the new cacheId. cacheId = BufferCache::getInstance().cache(s->bufferData.buffer); cacheId = BufferCache::getInstance().cache(s->bufferData->buffer); } s->bufferData.flags |= BufferData::BufferDataChange::cachedBufferChanged; s->bufferData.cachedBuffer.token = BufferCache::getInstance().getToken(); s->bufferData.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 Loading Loading @@ -1322,23 +1323,22 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp<Surfac return *this; } std::optional<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffer( std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffer( const sp<SurfaceControl>& sc) { layer_state_t* s = getLayerState(sc); if (!s) { return std::nullopt; return nullptr; } if (!(s->what & layer_state_t::eBufferChanged)) { return std::nullopt; return nullptr; } BufferData bufferData = s->bufferData; std::shared_ptr<BufferData> bufferData = std::move(s->bufferData); TransactionCompletedListener::getInstance()->removeReleaseBufferCallback( bufferData.generateReleaseCallbackId()); BufferData emptyBufferData; bufferData->generateReleaseCallbackId()); s->what &= ~layer_state_t::eBufferChanged; s->bufferData = emptyBufferData; s->bufferData = nullptr; mContainsBuffer = false; return bufferData; Loading @@ -1356,24 +1356,24 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe releaseBufferIfOverwriting(*s); BufferData bufferData; bufferData.buffer = buffer; std::shared_ptr<BufferData> bufferData = std::make_shared<BufferData>(); bufferData->buffer = buffer; if (frameNumber) { bufferData.frameNumber = *frameNumber; bufferData.flags |= BufferData::BufferDataChange::frameNumberChanged; bufferData->frameNumber = *frameNumber; bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged; } if (fence) { bufferData.acquireFence = *fence; bufferData.flags |= BufferData::BufferDataChange::fenceChanged; bufferData->acquireFence = *fence; bufferData->flags |= BufferData::BufferDataChange::fenceChanged; } bufferData.releaseBufferEndpoint = bufferData->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); if (mIsAutoTimestamp) { mDesiredPresentTime = systemTime(); } setReleaseBufferCallback(&bufferData, callback); setReleaseBufferCallback(bufferData.get(), callback); s->what |= layer_state_t::eBufferChanged; s->bufferData = bufferData; s->bufferData = std::move(bufferData); registerSurfaceControlForCallback(sc); mContainsBuffer = true; Loading libs/gui/include/gui/LayerState.h +20 −4 Original line number Diff line number Diff line Loading @@ -58,7 +58,22 @@ struct client_cache_t { bool isValid() const { return token != nullptr; } }; struct BufferData { class BufferData : public Parcelable { public: virtual ~BufferData() = default; virtual bool hasBuffer() const { return buffer != nullptr; } virtual bool hasSameBuffer(const BufferData& other) const { return buffer == other.buffer && frameNumber == other.frameNumber; } virtual uint32_t getWidth() const { return buffer->getWidth(); } virtual uint32_t getHeight() const { return buffer->getHeight(); } Rect getBounds() const { return {0, 0, static_cast<int32_t>(getWidth()), static_cast<int32_t>(getHeight())}; } virtual uint64_t getId() const { return buffer->getId(); } virtual PixelFormat getPixelFormat() const { return buffer->getPixelFormat(); } virtual uint64_t getUsage() const { return buffer->getUsage(); } enum class BufferDataChange : uint32_t { fenceChanged = 0x01, frameNumberChanged = 0x02, Loading Loading @@ -89,8 +104,9 @@ struct BufferData { // Generates the release callback id based on the buffer id and frame number. // This is used as an identifier when release callbacks are invoked. ReleaseCallbackId generateReleaseCallbackId() const; status_t write(Parcel& output) const; status_t read(const Parcel& input); status_t writeToParcel(Parcel* parcel) const override; status_t readFromParcel(const Parcel* parcel) override; }; /* Loading Loading @@ -204,7 +220,7 @@ struct layer_state_t { uint32_t transform; bool transformToDisplayInverse; Rect crop; BufferData bufferData; std::shared_ptr<BufferData> bufferData = nullptr; ui::Dataspace dataspace; HdrMetadata hdrMetadata; Region surfaceDamageRegion; Loading libs/gui/include/gui/SurfaceComposerClient.h +1 −1 Original line number Diff line number Diff line Loading @@ -501,7 +501,7 @@ public: const std::optional<sp<Fence>>& fence = std::nullopt, const std::optional<uint64_t>& frameNumber = std::nullopt, ReleaseBufferCallback callback = nullptr); std::optional<BufferData> getAndClearBuffer(const sp<SurfaceControl>& sc); std::shared_ptr<BufferData> getAndClearBuffer(const sp<SurfaceControl>& sc); Transaction& setDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace); Transaction& setHdrMetadata(const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata); Transaction& setSurfaceDamageRegion(const sp<SurfaceControl>& sc, Loading services/surfaceflinger/SurfaceFlinger.cpp +8 −8 Original line number Diff line number Diff line Loading @@ -3775,9 +3775,9 @@ bool SurfaceFlinger::checkTransactionCanLatchUnsignaled(const TransactionState& if (transaction.states.size() == 1) { const auto& state = transaction.states.begin()->state; if ((state.flags & ~layer_state_t::eBufferChanged) == 0 && state.bufferData.flags.test(BufferData::BufferDataChange::fenceChanged) && state.bufferData.acquireFence && state.bufferData.acquireFence->getStatus() == Fence::Status::Unsignaled) { state.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) && state.bufferData->acquireFence && state.bufferData->acquireFence->getStatus() == Fence::Status::Unsignaled) { ATRACE_NAME("transactionCanLatchUnsignaled"); return true; } Loading Loading @@ -3842,10 +3842,10 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( for (const ComposerState& state : states) { const layer_state_t& s = state.state; const bool acquireFenceChanged = s.bufferData.flags.test(BufferData::BufferDataChange::fenceChanged); if (acquireFenceChanged && s.bufferData.acquireFence && !allowLatchUnsignaled && s.bufferData.acquireFence->getStatus() == Fence::Status::Unsignaled) { const bool acquireFenceChanged = s.bufferData && s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged); if (acquireFenceChanged && s.bufferData->acquireFence && !allowLatchUnsignaled && s.bufferData->acquireFence->getStatus() == Fence::Status::Unsignaled) { ATRACE_NAME("fence unsignaled"); return false; } Loading Loading @@ -4476,7 +4476,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime } if (what & layer_state_t::eBufferChanged && layer->setBuffer(s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, layer->setBuffer(*s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp, frameTimelineInfo)) { flags |= eTraversalNeeded; } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { Loading Loading
libs/gui/LayerState.cpp +30 −27 Original line number Diff line number Diff line Loading @@ -153,7 +153,8 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.writeBool, isTrustedOverlay); SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode)); SAFE_PARCEL(bufferData.write, output); SAFE_PARCEL(output.writeNullableParcelable, bufferData ? std::make_optional<BufferData>(*bufferData) : std::nullopt); return NO_ERROR; } Loading Loading @@ -263,7 +264,9 @@ status_t layer_state_t::read(const Parcel& input) uint32_t mode; SAFE_PARCEL(input.readUint32, &mode); dropInputMode = static_cast<gui::DropInputMode>(mode); SAFE_PARCEL(bufferData.read, input); std::optional<BufferData> tmpBufferData; SAFE_PARCEL(input.readParcelable, &tmpBufferData); bufferData = tmpBufferData ? std::make_shared<BufferData>(*tmpBufferData) : nullptr; return NO_ERROR; } Loading Loading @@ -518,7 +521,7 @@ bool layer_state_t::hasBufferChanges() const { } bool layer_state_t::hasValidBuffer() const { return bufferData.buffer || bufferData.cachedBuffer.isValid(); return bufferData && (bufferData->buffer || bufferData->cachedBuffer.isValid()); } status_t layer_state_t::matrix22_t::write(Parcel& output) const { Loading Loading @@ -681,64 +684,64 @@ ReleaseCallbackId BufferData::generateReleaseCallbackId() const { return {buffer->getId(), frameNumber}; } status_t BufferData::write(Parcel& output) const { SAFE_PARCEL(output.writeInt32, flags.get()); status_t BufferData::writeToParcel(Parcel* output) const { SAFE_PARCEL(output->writeInt32, flags.get()); if (buffer) { SAFE_PARCEL(output.writeBool, true); SAFE_PARCEL(output.write, *buffer); SAFE_PARCEL(output->writeBool, true); SAFE_PARCEL(output->write, *buffer); } else { SAFE_PARCEL(output.writeBool, false); SAFE_PARCEL(output->writeBool, false); } if (acquireFence) { SAFE_PARCEL(output.writeBool, true); SAFE_PARCEL(output.write, *acquireFence); SAFE_PARCEL(output->writeBool, true); SAFE_PARCEL(output->write, *acquireFence); } else { SAFE_PARCEL(output.writeBool, false); SAFE_PARCEL(output->writeBool, false); } SAFE_PARCEL(output.writeUint64, frameNumber); SAFE_PARCEL(output.writeStrongBinder, IInterface::asBinder(releaseBufferListener)); SAFE_PARCEL(output.writeStrongBinder, releaseBufferEndpoint); SAFE_PARCEL(output->writeUint64, frameNumber); SAFE_PARCEL(output->writeStrongBinder, IInterface::asBinder(releaseBufferListener)); SAFE_PARCEL(output->writeStrongBinder, releaseBufferEndpoint); SAFE_PARCEL(output.writeStrongBinder, cachedBuffer.token.promote()); SAFE_PARCEL(output.writeUint64, cachedBuffer.id); SAFE_PARCEL(output->writeStrongBinder, cachedBuffer.token.promote()); SAFE_PARCEL(output->writeUint64, cachedBuffer.id); return NO_ERROR; } status_t BufferData::read(const Parcel& input) { status_t BufferData::readFromParcel(const Parcel* input) { int32_t tmpInt32; SAFE_PARCEL(input.readInt32, &tmpInt32); SAFE_PARCEL(input->readInt32, &tmpInt32); flags = Flags<BufferDataChange>(tmpInt32); bool tmpBool = false; SAFE_PARCEL(input.readBool, &tmpBool); SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { buffer = new GraphicBuffer(); SAFE_PARCEL(input.read, *buffer); SAFE_PARCEL(input->read, *buffer); } SAFE_PARCEL(input.readBool, &tmpBool); SAFE_PARCEL(input->readBool, &tmpBool); if (tmpBool) { acquireFence = new Fence(); SAFE_PARCEL(input.read, *acquireFence); SAFE_PARCEL(input->read, *acquireFence); } SAFE_PARCEL(input.readUint64, &frameNumber); SAFE_PARCEL(input->readUint64, &frameNumber); sp<IBinder> tmpBinder = nullptr; SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder); SAFE_PARCEL(input->readNullableStrongBinder, &tmpBinder); if (tmpBinder) { releaseBufferListener = checked_interface_cast<ITransactionCompletedListener>(tmpBinder); } SAFE_PARCEL(input.readNullableStrongBinder, &releaseBufferEndpoint); SAFE_PARCEL(input->readNullableStrongBinder, &releaseBufferEndpoint); tmpBinder = nullptr; SAFE_PARCEL(input.readNullableStrongBinder, &tmpBinder); SAFE_PARCEL(input->readNullableStrongBinder, &tmpBinder); cachedBuffer.token = tmpBinder; SAFE_PARCEL(input.readUint64, &cachedBuffer.id); SAFE_PARCEL(input->readUint64, &cachedBuffer.id); return NO_ERROR; } Loading
libs/gui/SurfaceComposerClient.cpp +29 −29 Original line number Diff line number Diff line Loading @@ -728,18 +728,18 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_ return; } auto listener = state.bufferData.releaseBufferListener; auto listener = state.bufferData->releaseBufferListener; sp<Fence> fence = state.bufferData.acquireFence ? state.bufferData.acquireFence : Fence::NO_FENCE; if (state.bufferData.releaseBufferEndpoint == 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); .addReleaseCallback(state.bufferData->generateReleaseCallbackId(), fence); } else { listener->onReleaseBuffer(state.bufferData.generateReleaseCallbackId(), fence, UINT_MAX); listener->onReleaseBuffer(state.bufferData->generateReleaseCallbackId(), fence, UINT_MAX); } } Loading Loading @@ -839,7 +839,8 @@ void SurfaceComposerClient::Transaction::cacheBuffers() { layer_state_t* s = &(mComposerStates[handle].state); if (!(s->what & layer_state_t::eBufferChanged)) { continue; } else if (s->bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged)) { } 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. Loading @@ -848,22 +849,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->bufferData.buffer) { if (!s->bufferData || !s->bufferData->buffer) { continue; } uint64_t cacheId = 0; status_t ret = BufferCache::getInstance().getCacheId(s->bufferData.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->bufferData.buffer = nullptr; s->bufferData->buffer = nullptr; } else { // Cache-miss. Include the buffer and send the new cacheId. cacheId = BufferCache::getInstance().cache(s->bufferData.buffer); cacheId = BufferCache::getInstance().cache(s->bufferData->buffer); } s->bufferData.flags |= BufferData::BufferDataChange::cachedBufferChanged; s->bufferData.cachedBuffer.token = BufferCache::getInstance().getToken(); s->bufferData.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 Loading Loading @@ -1322,23 +1323,22 @@ SurfaceComposerClient::Transaction::setTransformToDisplayInverse(const sp<Surfac return *this; } std::optional<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffer( std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffer( const sp<SurfaceControl>& sc) { layer_state_t* s = getLayerState(sc); if (!s) { return std::nullopt; return nullptr; } if (!(s->what & layer_state_t::eBufferChanged)) { return std::nullopt; return nullptr; } BufferData bufferData = s->bufferData; std::shared_ptr<BufferData> bufferData = std::move(s->bufferData); TransactionCompletedListener::getInstance()->removeReleaseBufferCallback( bufferData.generateReleaseCallbackId()); BufferData emptyBufferData; bufferData->generateReleaseCallbackId()); s->what &= ~layer_state_t::eBufferChanged; s->bufferData = emptyBufferData; s->bufferData = nullptr; mContainsBuffer = false; return bufferData; Loading @@ -1356,24 +1356,24 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe releaseBufferIfOverwriting(*s); BufferData bufferData; bufferData.buffer = buffer; std::shared_ptr<BufferData> bufferData = std::make_shared<BufferData>(); bufferData->buffer = buffer; if (frameNumber) { bufferData.frameNumber = *frameNumber; bufferData.flags |= BufferData::BufferDataChange::frameNumberChanged; bufferData->frameNumber = *frameNumber; bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged; } if (fence) { bufferData.acquireFence = *fence; bufferData.flags |= BufferData::BufferDataChange::fenceChanged; bufferData->acquireFence = *fence; bufferData->flags |= BufferData::BufferDataChange::fenceChanged; } bufferData.releaseBufferEndpoint = bufferData->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); if (mIsAutoTimestamp) { mDesiredPresentTime = systemTime(); } setReleaseBufferCallback(&bufferData, callback); setReleaseBufferCallback(bufferData.get(), callback); s->what |= layer_state_t::eBufferChanged; s->bufferData = bufferData; s->bufferData = std::move(bufferData); registerSurfaceControlForCallback(sc); mContainsBuffer = true; Loading
libs/gui/include/gui/LayerState.h +20 −4 Original line number Diff line number Diff line Loading @@ -58,7 +58,22 @@ struct client_cache_t { bool isValid() const { return token != nullptr; } }; struct BufferData { class BufferData : public Parcelable { public: virtual ~BufferData() = default; virtual bool hasBuffer() const { return buffer != nullptr; } virtual bool hasSameBuffer(const BufferData& other) const { return buffer == other.buffer && frameNumber == other.frameNumber; } virtual uint32_t getWidth() const { return buffer->getWidth(); } virtual uint32_t getHeight() const { return buffer->getHeight(); } Rect getBounds() const { return {0, 0, static_cast<int32_t>(getWidth()), static_cast<int32_t>(getHeight())}; } virtual uint64_t getId() const { return buffer->getId(); } virtual PixelFormat getPixelFormat() const { return buffer->getPixelFormat(); } virtual uint64_t getUsage() const { return buffer->getUsage(); } enum class BufferDataChange : uint32_t { fenceChanged = 0x01, frameNumberChanged = 0x02, Loading Loading @@ -89,8 +104,9 @@ struct BufferData { // Generates the release callback id based on the buffer id and frame number. // This is used as an identifier when release callbacks are invoked. ReleaseCallbackId generateReleaseCallbackId() const; status_t write(Parcel& output) const; status_t read(const Parcel& input); status_t writeToParcel(Parcel* parcel) const override; status_t readFromParcel(const Parcel* parcel) override; }; /* Loading Loading @@ -204,7 +220,7 @@ struct layer_state_t { uint32_t transform; bool transformToDisplayInverse; Rect crop; BufferData bufferData; std::shared_ptr<BufferData> bufferData = nullptr; ui::Dataspace dataspace; HdrMetadata hdrMetadata; Region surfaceDamageRegion; Loading
libs/gui/include/gui/SurfaceComposerClient.h +1 −1 Original line number Diff line number Diff line Loading @@ -501,7 +501,7 @@ public: const std::optional<sp<Fence>>& fence = std::nullopt, const std::optional<uint64_t>& frameNumber = std::nullopt, ReleaseBufferCallback callback = nullptr); std::optional<BufferData> getAndClearBuffer(const sp<SurfaceControl>& sc); std::shared_ptr<BufferData> getAndClearBuffer(const sp<SurfaceControl>& sc); Transaction& setDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace); Transaction& setHdrMetadata(const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata); Transaction& setSurfaceDamageRegion(const sp<SurfaceControl>& sc, Loading
services/surfaceflinger/SurfaceFlinger.cpp +8 −8 Original line number Diff line number Diff line Loading @@ -3775,9 +3775,9 @@ bool SurfaceFlinger::checkTransactionCanLatchUnsignaled(const TransactionState& if (transaction.states.size() == 1) { const auto& state = transaction.states.begin()->state; if ((state.flags & ~layer_state_t::eBufferChanged) == 0 && state.bufferData.flags.test(BufferData::BufferDataChange::fenceChanged) && state.bufferData.acquireFence && state.bufferData.acquireFence->getStatus() == Fence::Status::Unsignaled) { state.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) && state.bufferData->acquireFence && state.bufferData->acquireFence->getStatus() == Fence::Status::Unsignaled) { ATRACE_NAME("transactionCanLatchUnsignaled"); return true; } Loading Loading @@ -3842,10 +3842,10 @@ bool SurfaceFlinger::transactionIsReadyToBeApplied( for (const ComposerState& state : states) { const layer_state_t& s = state.state; const bool acquireFenceChanged = s.bufferData.flags.test(BufferData::BufferDataChange::fenceChanged); if (acquireFenceChanged && s.bufferData.acquireFence && !allowLatchUnsignaled && s.bufferData.acquireFence->getStatus() == Fence::Status::Unsignaled) { const bool acquireFenceChanged = s.bufferData && s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged); if (acquireFenceChanged && s.bufferData->acquireFence && !allowLatchUnsignaled && s.bufferData->acquireFence->getStatus() == Fence::Status::Unsignaled) { ATRACE_NAME("fence unsignaled"); return false; } Loading Loading @@ -4476,7 +4476,7 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime } if (what & layer_state_t::eBufferChanged && layer->setBuffer(s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, layer->setBuffer(*s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, dequeueBufferTimestamp, frameTimelineInfo)) { flags |= eTraversalNeeded; } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { Loading