diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 58 |
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() |