diff options
-rw-r--r-- | libs/gui/LayerState.cpp | 57 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 58 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 24 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 16 | ||||
-rw-r--r-- | services/surfaceflinger/Tracing/TransactionProtoParser.cpp | 23 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp | 5 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp | 1 |
8 files changed, 105 insertions, 81 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index acd9ac5a93..27d86bb4e2 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -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; } @@ -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; } @@ -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 { @@ -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; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index b10c3848fa..6a4ddaea9d 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -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); } } @@ -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. @@ -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 @@ -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; @@ -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; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index e48f52d13d..968ace93b9 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -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, @@ -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; }; /* @@ -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; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index b739b3c8bf..62758af2c0 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -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, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 8db974ed0e..bd13c4169c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -3719,9 +3719,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; } @@ -3786,10 +3786,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; } @@ -4420,7 +4420,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) { diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp index 378deb061d..849de22a41 100644 --- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp +++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp @@ -132,14 +132,14 @@ proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer, } if (layer.what & layer_state_t::eBufferChanged) { proto::LayerState_BufferData* bufferProto = proto.mutable_buffer_data(); - if (layer.bufferData.buffer) { - bufferProto->set_buffer_id(layer.bufferData.buffer->getId()); - bufferProto->set_width(layer.bufferData.buffer->getWidth()); - bufferProto->set_height(layer.bufferData.buffer->getHeight()); + if (layer.bufferData->buffer) { + bufferProto->set_buffer_id(layer.bufferData->getId()); + bufferProto->set_width(layer.bufferData->getWidth()); + bufferProto->set_height(layer.bufferData->getHeight()); } - bufferProto->set_frame_number(layer.bufferData.frameNumber); - bufferProto->set_flags(layer.bufferData.flags.get()); - bufferProto->set_cached_buffer_id(layer.bufferData.cachedBuffer.id); + bufferProto->set_frame_number(layer.bufferData->frameNumber); + bufferProto->set_flags(layer.bufferData->flags.get()); + bufferProto->set_cached_buffer_id(layer.bufferData->cachedBuffer.id); } if (layer.what & layer_state_t::eSidebandStreamChanged) { proto.set_has_sideband_stream(layer.sidebandStream != nullptr); @@ -405,10 +405,13 @@ void TransactionProtoParser::fromProto(const proto::LayerState& proto, LayerProtoHelper::readFromProto(proto.crop(), layer.crop); } if (proto.what() & layer_state_t::eBufferChanged) { + if (!layer.bufferData) { + layer.bufferData = std::make_shared<BufferData>(); + } const proto::LayerState_BufferData& bufferProto = proto.buffer_data(); - layer.bufferData.frameNumber = bufferProto.frame_number(); - layer.bufferData.flags = Flags<BufferData::BufferDataChange>(bufferProto.flags()); - layer.bufferData.cachedBuffer.id = bufferProto.cached_buffer_id(); + layer.bufferData->frameNumber = bufferProto.frame_number(); + layer.bufferData->flags = Flags<BufferData::BufferDataChange>(bufferProto.flags()); + layer.bufferData->cachedBuffer.id = bufferProto.cached_buffer_id(); } if (proto.what() & layer_state_t::eApiChanged) { diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index 16d4b59250..1ce0309683 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -434,9 +434,10 @@ public: static ComposerState createComposerState(int layerId, sp<Fence> fence, uint32_t stateFlags = layer_state_t::eBufferChanged) { ComposerState composer_state; - composer_state.state.bufferData.acquireFence = std::move(fence); + composer_state.state.bufferData = std::make_shared<BufferData>(); + composer_state.state.bufferData->acquireFence = std::move(fence); composer_state.state.layerId = layerId; - composer_state.state.bufferData.flags = BufferData::BufferDataChange::fenceChanged; + composer_state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged; composer_state.state.flags = stateFlags; return composer_state; } diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp index 6e00748b45..271b1c0211 100644 --- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp @@ -39,6 +39,7 @@ TEST(TransactionProtoParserTest, parse) { layer_state_t layer; layer.layerId = 6; layer.what = std::numeric_limits<uint64_t>::max(); + layer.what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged); layer.x = 7; layer.matrix.dsdx = 15; |