summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger')
-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 2944c63..9fb94dd 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -127,6 +127,10 @@ void Layer::onFirstRef() {
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
+ // Set the shadow queue size to 0 to notify the BufferQueue that we are
+ // shadowing it
+ mSurfaceFlingerConsumer->setShadowQueueSize(0);
+
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
@@ -164,9 +168,10 @@ void Layer::onFrameAvailable(const BufferItem& item) {
{ // Autolock scope
Mutex::Autolock lock(mQueueItemLock);
mQueueItems.push_back(item);
+ mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+ android_atomic_inc(&mQueuedFrames);
}
- android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
}
@@ -1259,14 +1264,39 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
// layer update so we check again at the next opportunity.
mFlinger->signalLayerUpdate();
return outDirtyRegion;
+ } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
+ // If the buffer has been rejected, remove it from the shadow queue
+ // and return early
+ Mutex::Autolock lock(mQueueItemLock);
+
+ // Update the BufferQueue with the new shadow queue size after
+ // dropping this item
+ mQueueItems.removeAt(0);
+ mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
+
+ android_atomic_dec(&mQueuedFrames);
+ return outDirtyRegion;
}
- // Remove this buffer from our internal queue tracker
{ // Autolock scope
+ auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
+
Mutex::Autolock lock(mQueueItemLock);
+
+ // Remove any stale buffers that have been dropped during
+ // updateTexImage
+ while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
+ mQueueItems.removeAt(0);
+ android_atomic_dec(&mQueuedFrames);
+ }
+
+ // Update the BufferQueue with our new shadow queue size, since we
+ // have removed at least one item
mQueueItems.removeAt(0);
+ mSurfaceFlingerConsumer->setShadowQueueSize(mQueueItems.size());
}
+
// 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/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 19c497a..a9a2958 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -74,7 +74,7 @@ status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter,
int buf = item.mBuf;
if (rejecter && rejecter->reject(mSlots[buf].mGraphicBuffer, item)) {
releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
- return NO_ERROR;
+ return BUFFER_REJECTED;
}
// Release the previous buffer.
@@ -125,6 +125,10 @@ sp<NativeHandle> SurfaceFlingerConsumer::getSidebandStream() const {
return mConsumer->getSidebandStream();
}
+void SurfaceFlingerConsumer::setShadowQueueSize(size_t size) {
+ mConsumer->setShadowQueueSize(size);
+}
+
// We need to determine the time when a buffer acquired now will be
// displayed. This can be calculated:
// time when previous buffer's actual-present fence was signaled
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 1aaba18..a90a8b9 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -28,6 +28,8 @@ namespace android {
*/
class SurfaceFlingerConsumer : public GLConsumer {
public:
+ static const status_t BUFFER_REJECTED = UNKNOWN_ERROR + 8;
+
struct ContentsChangedListener: public FrameAvailableListener {
virtual void onSidebandStreamChanged() = 0;
};
@@ -68,6 +70,9 @@ public:
sp<NativeHandle> getSidebandStream() const;
+ // See IGraphicBufferConsumer::setShadowQueueSize
+ void setShadowQueueSize(size_t size);
+
nsecs_t computeExpectedPresent(const DispSync& dispSync);
private: