Mark refreshPending as false when calling the fakeVsync
The fake vsync needs to get called to ensure dequeueBuffer doesn't get
stuck. However, latchBuffer will not call updateTexImage if the layer
thinks it already has a latched buffer (mRefreshPending = true). Since
mRefreshPending is normally set to false in onPreComposition, removed
layers will not get updated since they are no longer in the layer
hierarchy.
This change sets refreshPending to false for removed layers to ensure
that latchBuffer will attempt to call updateTexImage, allow
dequeueBuffer to continue.
Change-Id: If2a45b2d4cec069068466e0192355999ec265a66
Fixes: 119310197
Test: Open camera, press back, open camera again quickly
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 6eda20d..e3b7f2f 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -167,6 +167,8 @@
// from GLES
const uint32_t mTextureName;
+ bool mRefreshPending{false};
+
private:
// Returns true if this layer requires filtering
bool needsFiltering() const;
@@ -184,8 +186,6 @@
// The texture used to draw the layer in GLES composition mode
mutable renderengine::Texture mTexture;
- bool mRefreshPending{false};
-
Rect getBufferSize(const State& s) const override;
};
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 5a61122..42021d1 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -352,6 +352,14 @@
// Interface implementation for BufferLayerConsumer::ContentsChangedListener
// -----------------------------------------------------------------------
+void BufferQueueLayer::fakeVsync() {
+ mRefreshPending = false;
+ bool ignored = false;
+ latchBuffer(ignored, systemTime(), Fence::NO_FENCE);
+ usleep(16000);
+ releasePendingBuffer(systemTime());
+}
+
void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
// Add this buffer from our internal queue tracker
{ // Autolock scope
@@ -390,10 +398,7 @@
// If this layer is orphaned, then we run a fake vsync pulse so that
// dequeueBuffer doesn't block indefinitely.
if (isRemovedFromCurrentState()) {
- bool ignored = false;
- latchBuffer(ignored, systemTime(), Fence::NO_FENCE);
- usleep(16000);
- releasePendingBuffer(systemTime());
+ fakeVsync();
} else {
mFlinger->signalLayerUpdate();
}
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index ae0b705..d7c3f6a 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -137,6 +137,8 @@
// thread-safe
std::atomic<int32_t> mQueuedFrames{0};
std::atomic<bool> mSidebandStreamChanged{false};
+
+ void fakeVsync();
};
} // namespace android