Add interface for controlling single buffer auto refresh
- Adds a boolean to BufferQueue that controls whether or not auto
refresh is enabled in SurfaceFlinger when in single buffer mode.
- Adds plumbing up to ANativeWindow.
- When enabled, it will cache the shared buffer slot in Surface in
order to prevent the Binder transaction with SurfaceFlinger.
Bug 24940410
Change-Id: I83142afdc00e203f198a32288f071d926f8fda95
diff --git a/include/gui/BufferItem.h b/include/gui/BufferItem.h
index a515f39..6f45181 100644
--- a/include/gui/BufferItem.h
+++ b/include/gui/BufferItem.h
@@ -119,8 +119,10 @@
// previous frame
Region mSurfaceDamage;
- // Indicates that the BufferQueue is in single buffer mode
- bool mSingleBufferMode;
+ // Indicates that the consumer should acquire the next frame as soon as it
+ // can and not wait for a frame to become available. This is only relevant
+ // in single buffer mode.
+ bool mAutoRefresh;
// Indicates that this buffer was queued by the producer. When in single
// buffer mode acquire() can return a BufferItem that wasn't in the queue.
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index e2e73a0..d10ba2f 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -292,6 +292,11 @@
// consumer and producer to access the same buffer simultaneously.
bool mSingleBufferMode;
+ // When single buffer mode is enabled, this indicates whether the consumer
+ // should acquire buffers even if BufferQueue doesn't indicate that they are
+ // available.
+ bool mAutoRefresh;
+
// When single buffer mode is enabled, this tracks which slot contains the
// shared buffer.
int mSingleBufferSlot;
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index dc05e98..312f323 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -176,6 +176,9 @@
// See IGraphicBufferProducer::setSingleBufferMode
virtual status_t setSingleBufferMode(bool singleBufferMode) override;
+ // See IGraphicBufferProducer::setAutoRefresh
+ virtual status_t setAutoRefresh(bool autoRefresh) override;
+
// See IGraphicBufferProducer::setDequeueTimeout
virtual status_t setDequeueTimeout(nsecs_t timeout) override;
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 265728f..f6b4230 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -531,6 +531,14 @@
// the producer and consumer to simultaneously access the same buffer.
virtual status_t setSingleBufferMode(bool singleBufferMode) = 0;
+ // Used to enable/disable auto-refresh.
+ //
+ // Auto refresh has no effect outside of single buffer mode. In single
+ // buffer mode, when enabled, it indicates to the consumer that it should
+ // attempt to acquire buffers even if it is not aware of any being
+ // available.
+ virtual status_t setAutoRefresh(bool autoRefresh) = 0;
+
// Sets how long dequeueBuffer will wait for a buffer to become available
// before returning an error (TIMED_OUT).
//
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index f79210b..3afdaae 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -168,6 +168,7 @@
int dispatchSetBuffersDataSpace(va_list args);
int dispatchSetSurfaceDamage(va_list args);
int dispatchSetSingleBufferMode(va_list args);
+ int dispatchSetAutoRefresh(va_list args);
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
@@ -197,6 +198,7 @@
virtual int setMaxDequeuedBufferCount(int maxDequeuedBuffers);
virtual int setAsyncMode(bool async);
virtual int setSingleBufferMode(bool singleBufferMode);
+ virtual int setAutoRefresh(bool autoRefresh);
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
virtual int unlockAndPost();
@@ -331,6 +333,19 @@
// Stores the current generation number. See setGenerationNumber and
// IGraphicBufferProducer::setGenerationNumber for more information.
uint32_t mGenerationNumber;
+
+ // Caches the values that have been passed to the producer.
+ bool mSingleBufferMode;
+ bool mAutoRefresh;
+
+ // If in single buffer mode and auto refresh is enabled, store the shared
+ // buffer slot and return it for all calls to queue/dequeue without going
+ // over Binder.
+ int mSharedBufferSlot;
+
+ // This is true if the shared buffer has already been queued/canceled. It's
+ // used to prevent a mismatch between the number of queue/dequeue calls.
+ bool mSharedBufferHasBeenQueued;
};
}; // namespace android