[sf] Release the currently presented buffer when setBuffer is called
with null
Fixes a regression introduced in T which ignores a setBuffer call
with a null buffer. The expected behavior should be to release the
currently presented buffer from surfaceflinger. The subsequent frame
will not present this layer so the region behind the layer will be
composited instead.
Bug: 241271897
Test: presubmit
Change-Id: Ie06025c59c58cc75a267b783729996a3cbceef45
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 4dcdd96..040ebc1 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -134,7 +134,8 @@
void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
const uint32_t oldFlags = flags;
const half oldAlpha = color.a;
- const bool hadBufferOrSideStream = hasValidBuffer() || sidebandStream != nullptr;
+ const bool hadBuffer = externalTexture != nullptr;
+ const bool hadSideStream = sidebandStream != nullptr;
const layer_state_t& clientState = resolvedComposerState.state;
const bool hadBlur = hasBlur();
uint64_t clientChanges = what | layer_state_t::diff(clientState);
@@ -150,23 +151,32 @@
changes |= RequestedLayerState::Changes::Geometry;
}
}
- if (clientState.what &
- (layer_state_t::eBufferChanged | layer_state_t::eSidebandStreamChanged)) {
- const bool hasBufferOrSideStream = hasValidBuffer() || sidebandStream != nullptr;
- if (hadBufferOrSideStream != hasBufferOrSideStream) {
+ if (clientState.what & layer_state_t::eBufferChanged) {
+ externalTexture = resolvedComposerState.externalTexture;
+ barrierProducerId = std::max(bufferData->producerId, barrierProducerId);
+ barrierFrameNumber = std::max(bufferData->frameNumber, barrierFrameNumber);
+ // TODO(b/277265947) log and flush transaction trace when we detect out of order updates
+
+ const bool hasBuffer = externalTexture != nullptr;
+ if (hasBuffer || hasBuffer != hadBuffer) {
+ changes |= RequestedLayerState::Changes::Buffer;
+ }
+
+ if (hasBuffer != hadBuffer) {
changes |= RequestedLayerState::Changes::Geometry |
RequestedLayerState::Changes::VisibleRegion |
RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
}
}
- if (clientState.what & layer_state_t::eBufferChanged) {
- barrierProducerId = std::max(bufferData->producerId, barrierProducerId);
- barrierFrameNumber = std::max(bufferData->frameNumber, barrierFrameNumber);
- // TODO(b/277265947) log and flush transaction trace when we detect out of order updates
- changes |= RequestedLayerState::Changes::Buffer;
- }
+
if (clientState.what & layer_state_t::eSidebandStreamChanged) {
changes |= RequestedLayerState::Changes::SidebandStream;
+ const bool hasSideStream = sidebandStream != nullptr;
+ if (hasSideStream != hadSideStream) {
+ changes |= RequestedLayerState::Changes::Geometry |
+ RequestedLayerState::Changes::VisibleRegion |
+ RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
+ }
}
if (what & (layer_state_t::eAlphaChanged)) {
if (oldAlpha == 0 || color.a == 0) {
@@ -240,10 +250,6 @@
// TODO(b/238781169) handle callbacks
}
- if (clientState.what & layer_state_t::eBufferChanged) {
- externalTexture = resolvedComposerState.externalTexture;
- }
-
if (clientState.what & layer_state_t::ePositionChanged) {
requestedTransform.set(x, y);
}
@@ -465,6 +471,10 @@
return hasFrameUpdate() && sidebandStream.get();
}
+bool RequestedLayerState::willReleaseBufferOnLatch() const {
+ return changes.test(Changes::Buffer) && !externalTexture;
+}
+
void RequestedLayerState::clearChanges() {
what = 0;
changes.clear();