summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2014-11-18 02:07:36 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-11-18 02:07:36 +0000
commit686c5be4722dce02ae8e5580d6677f1eeea22464 (patch)
tree09157f693489b945e0a9a6d873bd7e94a56c1e93 /services
parentaccddd9ca0bef572674b895b9b2b0553b133c793 (diff)
parent6b9454d1fee0347711af1746642aa7820b1ea04d (diff)
downloadframeworks_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.cpp32
-rw-r--r--services/surfaceflinger/Layer.h7
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp58
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h15
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.h2
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;