summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Stoza2015-04-28 16:42:06 -0500
committerDan Stoza2015-04-30 17:29:05 -0500
commit2e36f2283f48ab764b496490c73a132acf21df3a (patch)
tree9c6a951420250a966b71b12317927c4d1d49114d /services
parent8de71a2408f632407c25942a39c31f78c7f64ffd (diff)
downloadframeworks-native-2e36f2283f48ab764b496490c73a132acf21df3a.tar.gz
frameworks-native-2e36f2283f48ab764b496490c73a132acf21df3a.tar.xz
frameworks-native-2e36f2283f48ab764b496490c73a132acf21df3a.zip
SurfaceFlinger: Fix PTS on stale buffers
SurfaceFlinger's (Layer's) shadow copy of the BufferQueue queue was getting out of sync for a few reasons. This change fixes these by doing the following: - Adds a check to re-synchronize the shadow copy every time we successfully acquire a buffer by first dropping stale buffers before removing the current buffer. - Avoids trying to perform updates for buffers which have been rejected (for incorrect dimensions) by SurfaceFlinger. - Adds IGraphicBufferConsumer::setShadowQueueSize, which allows the consumer to notify the BufferQueue that it is maintaining a shadow copy of the queue and prevents it from dropping so many buffers during acquireBuffer that it ends up returning a buffer for which the consumer has not yet received an onFrameAvailable call. Bug: 20096136 Change-Id: I78d0738428005fc19b3be85cc8f1db498043612f
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/Layer.cpp34
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.cpp6
-rw-r--r--services/surfaceflinger/SurfaceFlingerConsumer.h5
3 files changed, 42 insertions, 3 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2944c6323..9fb94dd3d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -127,6 +127,10 @@ void Layer::onFirstRef() {
127 mSurfaceFlingerConsumer->setContentsChangedListener(this); 127 mSurfaceFlingerConsumer->setContentsChangedListener(this);
128 mSurfaceFlingerConsumer->setName(mName); 128 mSurfaceFlingerConsumer->setName(mName);
129 129
130 // Set the shadow queue size to 0 to notify the BufferQueue that we are
131 // shadowing it
132 mSurfaceFlingerConsumer->setShadowQueueSize(0);
133
130#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 134#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
131#warning "disabling triple buffering" 135#warning "disabling triple buffering"
132 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 136 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
@@ -164,9 +168,10 @@ void Layer::onFrameAvailable(const BufferItem& item) {
164 { // Autolock scope 168 { // Autolock scope
165 Mutex::Autolock lock(mQueueItemLock); 169 Mutex::Autolock lock(mQueueItemLock);
166 mQueueItems.push_back(item); 170 mQueueItems.push_back(item);
171 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
172 android_atomic_inc(&mQueuedFrames);
167 } 173 }
168 174
169 android_atomic_inc(&mQueuedFrames);
170 mFlinger->signalLayerUpdate(); 175 mFlinger->signalLayerUpdate();
171} 176}
172 177
@@ -1259,14 +1264,39 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
1259 // layer update so we check again at the next opportunity. 1264 // layer update so we check again at the next opportunity.
1260 mFlinger->signalLayerUpdate(); 1265 mFlinger->signalLayerUpdate();
1261 return outDirtyRegion; 1266 return outDirtyRegion;
1267 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
1268 // If the buffer has been rejected, remove it from the shadow queue
1269 // and return early
1270 Mutex::Autolock lock(mQueueItemLock);
1271
1272 // Update the BufferQueue with the new shadow queue size after
1273 // dropping this item
1274 mQueueItems.removeAt(0);
1275 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
1276
1277 android_atomic_dec(&mQueuedFrames);
1278 return outDirtyRegion;
1262 } 1279 }
1263 1280
1264 // Remove this buffer from our internal queue tracker
1265 { // Autolock scope 1281 { // Autolock scope
1282 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
1283
1266 Mutex::Autolock lock(mQueueItemLock); 1284 Mutex::Autolock lock(mQueueItemLock);
1285
1286 // Remove any stale buffers that have been dropped during
1287 // updateTexImage
1288 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
1289 mQueueItems.removeAt(0);
1290 android_atomic_dec(&mQueuedFrames);
1291 }
1292
1293 // Update the BufferQueue with our new shadow queue size, since we
1294 // have removed at least one item
1267 mQueueItems.removeAt(0); 1295 mQueueItems.removeAt(0);
1296 mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
1268 } 1297 }
1269 1298
1299
1270 // Decrement the queued-frames count. Signal another event if we 1300 // Decrement the queued-frames count. Signal another event if we
1271 // have more frames pending. 1301 // have more frames pending.
1272 if (android_atomic_dec(&mQueuedFrames) > 1) { 1302 if (android_atomic_dec(&mQueuedFrames) > 1) {
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 19c497a5d..a9a295882 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -74,7 +74,7 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter,
74 int buf = item.mBuf; 74 int buf = item.mBuf;
75 if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) { 75 if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
76 releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR); 76 releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
77 return NO_ERROR; 77 return BUFFER_REJECTED;
78 } 78 }
79 79
80 // Release the previous buffer. 80 // Release the previous buffer.
@@ -125,6 +125,10 @@ sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
125 return mConsumer->getSidebandStream(); 125 return mConsumer->getSidebandStream();
126} 126}
127 127
128void SurfaceFlingerConsumer::setShadowQueueSize(size_t size) {
129 mConsumer->setShadowQueueSize(size);
130}
131
128// We need to determine the time when a buffer acquired now will be 132// We need to determine the time when a buffer acquired now will be
129// displayed. This can be calculated: 133// displayed. This can be calculated:
130// time when previous buffer's actual-present fence was signaled 134// time when previous buffer's actual-present fence was signaled
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 1aaba1884..a90a8b931 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -28,6 +28,8 @@ namespace android {
28 */ 28 */
29class SurfaceFlingerConsumer : public GLConsumer { 29class SurfaceFlingerConsumer : public GLConsumer {
30public: 30public:
31 static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8;
32
31 struct ContentsChangedListener: public FrameAvailableListener { 33 struct ContentsChangedListener: public FrameAvailableListener {
32 virtual void onSidebandStreamChanged() = 0; 34 virtual void onSidebandStreamChanged() = 0;
33 }; 35 };
@@ -68,6 +70,9 @@ public:
68 70
69 sp<NativeHandle> getSidebandStream() const; 71 sp<NativeHandle> getSidebandStream() const;
70 72
73 // See IGraphicBufferConsumer::setShadowQueueSize
74 void setShadowQueueSize(size_t size);
75
71 nsecs_t computeExpectedPresent(const DispSync& dispSync); 76 nsecs_t computeExpectedPresent(const DispSync& dispSync);
72 77
73private: 78private: