summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp58
1 files changed, 41 insertions, 17 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c469627..b8b6472 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -829,30 +829,39 @@ void SurfaceFlinger::eventControl(int disp, int event, int enabled) {
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
- case MessageQueue::TRANSACTION:
- handleMessageTransaction();
- break;
- case MessageQueue::INVALIDATE:
- handleMessageTransaction();
- handleMessageInvalidate();
- signalRefresh();
- break;
- case MessageQueue::REFRESH:
- handleMessageRefresh();
- break;
+ case MessageQueue::TRANSACTION: {
+ handleMessageTransaction();
+ break;
+ }
+ case MessageQueue::INVALIDATE: {
+ bool refreshNeeded = handleMessageTransaction();
+ refreshNeeded |= handleMessageInvalidate();
+ if (refreshNeeded) {
+ // Signal a refresh if a transaction modified the window state or if
+ // a new buffer was latched
+ signalRefresh();
+ }
+ break;
+ }
+ case MessageQueue::REFRESH: {
+ handleMessageRefresh();
+ break;
+ }
}
}
-void SurfaceFlinger::handleMessageTransaction() {
+bool SurfaceFlinger::handleMessageTransaction() {
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
if (transactionFlags) {
handleTransaction(transactionFlags);
+ return true;
}
+ return false;
}
-void SurfaceFlinger::handleMessageInvalidate() {
+bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
- handlePageFlip();
+ return handlePageFlip();
}
void SurfaceFlinger::handleMessageRefresh() {
@@ -1685,12 +1694,13 @@ void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
}
}
-void SurfaceFlinger::handlePageFlip()
+bool SurfaceFlinger::handlePageFlip()
{
Region dirtyRegion;
bool visibleRegions = false;
const LayerVector& layers(mDrawingState.layersSortedByZ);
+ bool frameQueued = false;
// Store the set of layers that need updates. This set must not change as
// buffers are being latched, as this could result in a deadlock.
@@ -1704,8 +1714,12 @@ void SurfaceFlinger::handlePageFlip()
Vector<Layer*> layersWithQueuedFrames;
for (size_t i = 0, count = layers.size(); i<count ; i++) {
const sp<Layer>& layer(layers[i]);
- if (layer->hasQueuedFrame())
- layersWithQueuedFrames.push_back(layer.get());
+ if (layer->hasQueuedFrame()) {
+ frameQueued = true;
+ if (layer->shouldPresentNow(mPrimaryDispSync)) {
+ layersWithQueuedFrames.push_back(layer.get());
+ }
+ }
}
for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
Layer* layer = layersWithQueuedFrames[i];
@@ -1715,6 +1729,16 @@ void SurfaceFlinger::handlePageFlip()
}
mVisibleRegionsDirty |= visibleRegions;
+
+ // If we will need to wake up at some time in the future to deal with a
+ // queued frame that shouldn't be displayed during this vsync period, wake
+ // up during the next vsync period to check again.
+ if (frameQueued && layersWithQueuedFrames.empty()) {
+ signalLayerUpdate();
+ }
+
+ // Only continue with the refresh if there is actually new work to do
+ return !layersWithQueuedFrames.empty();
}
void SurfaceFlinger::invalidateHwcGeometry()