diff options
author | Dan Stoza <stoza@google.com> | 2014-11-18 02:07:36 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-18 02:07:36 +0000 |
commit | 686c5be4722dce02ae8e5580d6677f1eeea22464 (patch) | |
tree | 09157f693489b945e0a9a6d873bd7e94a56c1e93 /services | |
parent | accddd9ca0bef572674b895b9b2b0553b133c793 (diff) | |
parent | 6b9454d1fee0347711af1746642aa7820b1ea04d (diff) | |
download | frameworks_native-686c5be4722dce02ae8e5580d6677f1eeea22464.zip frameworks_native-686c5be4722dce02ae8e5580d6677f1eeea22464.tar.gz frameworks_native-686c5be4722dce02ae8e5580d6677f1eeea22464.tar.bz2 |
am 6b9454d1: SurfaceFlinger: Do less work when using PTS
* commit '6b9454d1fee0347711af1746642aa7820b1ea04d':
SurfaceFlinger: Do less work when using PTS
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 32 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 58 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 15 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlingerConsumer.h | 2 |
5 files changed, 90 insertions, 24 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c91f0af..009baea 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -34,6 +34,7 @@ #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> +#include <gui/BufferItem.h> #include <gui/Surface.h> #include "clz.h" @@ -158,11 +159,26 @@ void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, } } -void Layer::onFrameAvailable(const BufferItem& /* item */) { +void Layer::onFrameAvailable(const BufferItem& item) { + // Add this buffer from our internal queue tracker + { // Autolock scope + Mutex::Autolock lock(mQueueItemLock); + mQueueItems.push_back(item); + } + android_atomic_inc(&mQueuedFrames); mFlinger->signalLayerUpdate(); } +void Layer::onFrameReplaced(const BufferItem& item) { + Mutex::Autolock lock(mQueueItemLock); + if (mQueueItems.empty()) { + ALOGE("Can't replace a frame on an empty queue"); + return; + } + mQueueItems.editItemAt(0) = item; +} + void Layer::onSidebandStreamChanged() { if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { // mSidebandStreamChanged was false @@ -1012,6 +1028,14 @@ bool Layer::setLayerStack(uint32_t layerStack) { // pageflip handling... // ---------------------------------------------------------------------------- +bool Layer::shouldPresentNow(const DispSync& dispSync) const { + Mutex::Autolock lock(mQueueItemLock); + nsecs_t expectedPresent = + mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); + return mQueueItems.empty() ? + false : mQueueItems[0].mTimestamp < expectedPresent; +} + bool Layer::onPreComposition() { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged; @@ -1201,6 +1225,12 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return outDirtyRegion; } + // Remove this buffer from our internal queue tracker + { // Autolock scope + Mutex::Autolock lock(mQueueItemLock); + mQueueItems.removeAt(0); + } + // Decrement the queued-frames count. Signal another event if we // have more frames pending. if (android_atomic_dec(&mQueuedFrames) > 1) { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index b705bc2..424c03e 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -210,6 +210,8 @@ public: void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer); + bool shouldPresentNow(const DispSync& dispSync) const; + /* * called before composition. * returns true if the layer has pending updates. @@ -331,6 +333,7 @@ protected: private: // Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener virtual void onFrameAvailable(const BufferItem& item); + virtual void onFrameReplaced(const BufferItem& item); virtual void onSidebandStreamChanged(); void commitTransaction(); @@ -403,6 +406,10 @@ private: // This layer can be a cursor on some displays. bool mPotentialCursor; + + // Local copy of the queued contents of the incoming BufferQueue + mutable Mutex mQueueItemLock; + Vector<BufferItem> mQueueItems; }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1060b09..e8c9025 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -828,30 +828,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() { @@ -1686,12 +1695,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. @@ -1705,8 +1715,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]; @@ -1716,6 +1730,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() diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 710dac7..4deb815 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -247,8 +247,12 @@ private: // called on the main thread in response to setPowerMode() void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode); - void handleMessageTransaction(); - void handleMessageInvalidate(); + // Returns whether the transaction actually modified any state + bool handleMessageTransaction(); + + // Returns whether a new buffer has been latched (see handlePageFlip()) + bool handleMessageInvalidate(); + void handleMessageRefresh(); void handleTransaction(uint32_t transactionFlags); @@ -256,10 +260,11 @@ private: void updateCursorAsync(); - /* handlePageFilp: this is were we latch a new buffer - * if available and compute the dirty region. + /* handlePageFlip - latch a new buffer if available and compute the dirty + * region. Returns whether a new buffer has been latched, i.e., whether it + * is necessary to perform a refresh during this vsync. */ - void handlePageFlip(); + bool handlePageFlip(); /* ------------------------------------------------------------------------ * Transactions diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h index 5633980..28f2f6a 100644 --- a/services/surfaceflinger/SurfaceFlingerConsumer.h +++ b/services/surfaceflinger/SurfaceFlingerConsumer.h @@ -67,9 +67,9 @@ public: sp<NativeHandle> getSidebandStream() const; -private: nsecs_t computeExpectedPresent(const DispSync& dispSync); +private: virtual void onSidebandStreamChanged(); wp<ContentsChangedListener> mContentsChangedListener; |