Loading libs/gui/BLASTBufferQueue.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -132,12 +132,13 @@ void BLASTBufferItemConsumer::onSidebandStreamChanged() { } } BLASTBufferQueue::BLASTBufferQueue(const std::string& name) BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame) : mSurfaceControl(nullptr), mSize(1, 1), mRequestedSize(mSize), mFormat(PIXEL_FORMAT_RGBA_8888), mSyncTransaction(nullptr) { mSyncTransaction(nullptr), mUpdateDestinationFrame(updateDestinationFrame) { createBufferQueue(&mProducer, &mConsumer); // since the adapter is in the client process, set dequeue timeout // explicitly so that dequeueBuffer will block Loading Loading @@ -184,7 +185,7 @@ BLASTBufferQueue::~BLASTBufferQueue() { } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format, SurfaceComposerClient::Transaction* outTransaction) { int32_t format) { LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL"); std::unique_lock _lock{mMutex}; Loading @@ -193,7 +194,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format)); } SurfaceComposerClient::Transaction t; const bool surfaceControlChanged = !SurfaceControl::isSameSurface(mSurfaceControl, surface); if (surfaceControlChanged && mSurfaceControl != nullptr) { BQA_LOGD("Updating SurfaceControl without recreating BBQ"); Loading @@ -203,6 +203,7 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, // Always update the native object even though they might have the same layer handle, so we can // get the updated transform hint from WM. mSurfaceControl = surface; SurfaceComposerClient::Transaction t; if (surfaceControlChanged) { t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, layer_state_t::eEnableBackpressure); Loading @@ -221,14 +222,12 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; SurfaceComposerClient::Transaction* destFrameTransaction = (outTransaction) ? outTransaction : &t; destFrameTransaction->setDestinationFrame(mSurfaceControl, Rect(0, 0, newSize.getWidth(), newSize.getHeight())); if (mUpdateDestinationFrame) { t.setDestinationFrame(mSurfaceControl, Rect(newSize)); applyTransaction = true; } } } if (applyTransaction) { t.setApplyToken(mApplyToken).apply(); } Loading Loading @@ -498,7 +497,6 @@ void BLASTBufferQueue::acquireNextBufferLocked( // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); const bool updateDestinationFrame = mRequestedSize != mSize; mSize = mRequestedSize; Rect crop = computeCrop(bufferItem); mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), Loading @@ -517,12 +515,19 @@ void BLASTBufferQueue::acquireNextBufferLocked( mSurfaceControlsWithPendingCallback.push(mSurfaceControl); if (updateDestinationFrame) { t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight())); if (mUpdateDestinationFrame) { t->setDestinationFrame(mSurfaceControl, Rect(mSize)); } else { const bool ignoreDestinationFrame = bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE; t->setFlags(mSurfaceControl, ignoreDestinationFrame ? layer_state_t::eIgnoreDestinationFrame : 0, layer_state_t::eIgnoreDestinationFrame); } t->setBufferCrop(mSurfaceControl, crop); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh); if (!bufferItem.mIsAutoTimestamp) { t->setDesiredPresentTime(bufferItem.mTimestamp); } Loading @@ -532,10 +537,6 @@ void BLASTBufferQueue::acquireNextBufferLocked( mNextFrameTimelineInfoQueue.pop(); } if (mAutoRefresh != bufferItem.mAutoRefresh) { t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh); mAutoRefresh = bufferItem.mAutoRefresh; } { std::unique_lock _lock{mTimestampMutex}; auto dequeueTime = mDequeueTimestamps.find(buffer->getId()); Loading libs/gui/include/gui/BLASTBufferQueue.h +8 −8 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener { public: BLASTBufferQueue(const std::string& name); BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true); BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width, int height, int32_t format); Loading @@ -100,8 +100,7 @@ public: void applyPendingTransactions(uint64_t frameNumber); SurfaceComposerClient::Transaction* gatherPendingTransactions(uint64_t frameNumber); void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format, SurfaceComposerClient::Transaction* outTransaction = nullptr); void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format); status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineInfo(const FrameTimelineInfo& info); Loading Loading @@ -218,11 +217,6 @@ private: std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> mPendingTransactions GUARDED_BY(mMutex); // Last requested auto refresh state set by the producer. The state indicates that the consumer // should acquire the next frame as soon as it can and not wait for a frame to become available. // This is only relevant for shared buffer mode. bool mAutoRefresh GUARDED_BY(mMutex) = false; std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); // Tracks the last acquired frame number Loading Loading @@ -250,6 +244,12 @@ private: // Flag to determine if syncTransaction should only acquire a single buffer and then clear or // continue to acquire buffers until explicitly cleared bool mAcquireSingleBuffer GUARDED_BY(mMutex) = true; // True if BBQ will update the destination frame used to scale the buffer to the requested size. // If false, the caller is responsible for updating the destination frame on the BBQ // surfacecontol. This is useful if the caller wants to synchronize the buffer scale with // additional scales in the hierarchy. bool mUpdateDestinationFrame GUARDED_BY(mMutex) = true; }; } // namespace android Loading libs/gui/include/gui/LayerState.h +7 −2 Original line number Diff line number Diff line Loading @@ -130,6 +130,11 @@ struct layer_state_t { // have presentation timestamps, then we may drop buffers. eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE eLayerIsDisplayDecoration = 0x200, // DISPLAY_DECORATION // Ignore any destination frame set on the layer. This is used when the buffer scaling mode // is freeze and the destination frame is applied asynchronously with the buffer submission. // This is needed to maintain compatibility for SurfaceView scaling behavior. // See SurfaceView scaling behavior for more details. eIgnoreDestinationFrame = 0x400, }; enum { Loading services/surfaceflinger/BufferStateLayer.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -271,7 +271,8 @@ static bool assignTransform(ui::Transform* dst, ui::Transform& from) { // Translate destination frame into scale and position. If a destination frame is not set, use the // provided scale and position bool BufferStateLayer::updateGeometry() { if (mDrawingState.destinationFrame.isEmpty()) { if ((mDrawingState.flags & layer_state_t::eIgnoreDestinationFrame) || mDrawingState.destinationFrame.isEmpty()) { // If destination frame is not set, use the requested transform set via // BufferStateLayer::setPosition and BufferStateLayer::setMatrix. return assignTransform(&mDrawingState.transform, mRequestedTransform); Loading services/surfaceflinger/Layer.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -2142,6 +2142,9 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend()); } } LayerProtoHelper::writeToProto(state.destinationFrame, [&]() { return layerInfo->mutable_destination_frame(); }); } bool Layer::isRemovedFromCurrentState() const { Loading Loading
libs/gui/BLASTBufferQueue.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -132,12 +132,13 @@ void BLASTBufferItemConsumer::onSidebandStreamChanged() { } } BLASTBufferQueue::BLASTBufferQueue(const std::string& name) BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame) : mSurfaceControl(nullptr), mSize(1, 1), mRequestedSize(mSize), mFormat(PIXEL_FORMAT_RGBA_8888), mSyncTransaction(nullptr) { mSyncTransaction(nullptr), mUpdateDestinationFrame(updateDestinationFrame) { createBufferQueue(&mProducer, &mConsumer); // since the adapter is in the client process, set dequeue timeout // explicitly so that dequeueBuffer will block Loading Loading @@ -184,7 +185,7 @@ BLASTBufferQueue::~BLASTBufferQueue() { } void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format, SurfaceComposerClient::Transaction* outTransaction) { int32_t format) { LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL"); std::unique_lock _lock{mMutex}; Loading @@ -193,7 +194,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format)); } SurfaceComposerClient::Transaction t; const bool surfaceControlChanged = !SurfaceControl::isSameSurface(mSurfaceControl, surface); if (surfaceControlChanged && mSurfaceControl != nullptr) { BQA_LOGD("Updating SurfaceControl without recreating BBQ"); Loading @@ -203,6 +203,7 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, // Always update the native object even though they might have the same layer handle, so we can // get the updated transform hint from WM. mSurfaceControl = surface; SurfaceComposerClient::Transaction t; if (surfaceControlChanged) { t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure, layer_state_t::eEnableBackpressure); Loading @@ -221,14 +222,12 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, // If the buffer supports scaling, update the frame immediately since the client may // want to scale the existing buffer to the new size. mSize = mRequestedSize; SurfaceComposerClient::Transaction* destFrameTransaction = (outTransaction) ? outTransaction : &t; destFrameTransaction->setDestinationFrame(mSurfaceControl, Rect(0, 0, newSize.getWidth(), newSize.getHeight())); if (mUpdateDestinationFrame) { t.setDestinationFrame(mSurfaceControl, Rect(newSize)); applyTransaction = true; } } } if (applyTransaction) { t.setApplyToken(mApplyToken).apply(); } Loading Loading @@ -498,7 +497,6 @@ void BLASTBufferQueue::acquireNextBufferLocked( // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback. incStrong((void*)transactionCallbackThunk); const bool updateDestinationFrame = mRequestedSize != mSize; mSize = mRequestedSize; Rect crop = computeCrop(bufferItem); mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(), Loading @@ -517,12 +515,19 @@ void BLASTBufferQueue::acquireNextBufferLocked( mSurfaceControlsWithPendingCallback.push(mSurfaceControl); if (updateDestinationFrame) { t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight())); if (mUpdateDestinationFrame) { t->setDestinationFrame(mSurfaceControl, Rect(mSize)); } else { const bool ignoreDestinationFrame = bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE; t->setFlags(mSurfaceControl, ignoreDestinationFrame ? layer_state_t::eIgnoreDestinationFrame : 0, layer_state_t::eIgnoreDestinationFrame); } t->setBufferCrop(mSurfaceControl, crop); t->setTransform(mSurfaceControl, bufferItem.mTransform); t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse); t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh); if (!bufferItem.mIsAutoTimestamp) { t->setDesiredPresentTime(bufferItem.mTimestamp); } Loading @@ -532,10 +537,6 @@ void BLASTBufferQueue::acquireNextBufferLocked( mNextFrameTimelineInfoQueue.pop(); } if (mAutoRefresh != bufferItem.mAutoRefresh) { t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh); mAutoRefresh = bufferItem.mAutoRefresh; } { std::unique_lock _lock{mTimestampMutex}; auto dequeueTime = mDequeueTimestamps.find(buffer->getId()); Loading
libs/gui/include/gui/BLASTBufferQueue.h +8 −8 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener { public: BLASTBufferQueue(const std::string& name); BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true); BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width, int height, int32_t format); Loading @@ -100,8 +100,7 @@ public: void applyPendingTransactions(uint64_t frameNumber); SurfaceComposerClient::Transaction* gatherPendingTransactions(uint64_t frameNumber); void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format, SurfaceComposerClient::Transaction* outTransaction = nullptr); void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format); status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless); status_t setFrameTimelineInfo(const FrameTimelineInfo& info); Loading Loading @@ -218,11 +217,6 @@ private: std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>> mPendingTransactions GUARDED_BY(mMutex); // Last requested auto refresh state set by the producer. The state indicates that the consumer // should acquire the next frame as soon as it can and not wait for a frame to become available. // This is only relevant for shared buffer mode. bool mAutoRefresh GUARDED_BY(mMutex) = false; std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex); // Tracks the last acquired frame number Loading Loading @@ -250,6 +244,12 @@ private: // Flag to determine if syncTransaction should only acquire a single buffer and then clear or // continue to acquire buffers until explicitly cleared bool mAcquireSingleBuffer GUARDED_BY(mMutex) = true; // True if BBQ will update the destination frame used to scale the buffer to the requested size. // If false, the caller is responsible for updating the destination frame on the BBQ // surfacecontol. This is useful if the caller wants to synchronize the buffer scale with // additional scales in the hierarchy. bool mUpdateDestinationFrame GUARDED_BY(mMutex) = true; }; } // namespace android Loading
libs/gui/include/gui/LayerState.h +7 −2 Original line number Diff line number Diff line Loading @@ -130,6 +130,11 @@ struct layer_state_t { // have presentation timestamps, then we may drop buffers. eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE eLayerIsDisplayDecoration = 0x200, // DISPLAY_DECORATION // Ignore any destination frame set on the layer. This is used when the buffer scaling mode // is freeze and the destination frame is applied asynchronously with the buffer submission. // This is needed to maintain compatibility for SurfaceView scaling behavior. // See SurfaceView scaling behavior for more details. eIgnoreDestinationFrame = 0x400, }; enum { Loading
services/surfaceflinger/BufferStateLayer.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -271,7 +271,8 @@ static bool assignTransform(ui::Transform* dst, ui::Transform& from) { // Translate destination frame into scale and position. If a destination frame is not set, use the // provided scale and position bool BufferStateLayer::updateGeometry() { if (mDrawingState.destinationFrame.isEmpty()) { if ((mDrawingState.flags & layer_state_t::eIgnoreDestinationFrame) || mDrawingState.destinationFrame.isEmpty()) { // If destination frame is not set, use the requested transform set via // BufferStateLayer::setPosition and BufferStateLayer::setMatrix. return assignTransform(&mDrawingState.transform, mRequestedTransform); Loading
services/surfaceflinger/Layer.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -2142,6 +2142,9 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend()); } } LayerProtoHelper::writeToProto(state.destinationFrame, [&]() { return layerInfo->mutable_destination_frame(); }); } bool Layer::isRemovedFromCurrentState() const { Loading