Add the MIN_UNDEQUEUED_BUFFERS query to ANW.

This change adds a new query to ANativeWindow for getting the minimum
number of buffers that must be left un-dequeued during the steady-state
operation of the ANativeWindow.

Change-Id: Ie8c461fc26b02ecde02ddb4f95bf763662cf1551
Related-Bug: 3356050
This commit is contained in:
Jamie Gennis 2011-02-27 14:10:20 -08:00
parent 2e158a769d
commit 9d4d6c101d
7 changed files with 62 additions and 15 deletions

View File

@ -37,7 +37,8 @@ class IGraphicBufferAlloc;
class SurfaceTexture : public BnSurfaceTexture {
public:
enum { MIN_BUFFER_SLOTS = 3 };
enum { MIN_UNDEQUEUED_BUFFERS = 2 };
enum { MIN_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1 };
enum { NUM_BUFFER_SLOTS = 32 };
struct FrameAvailableListener : public virtual RefBase {

View File

@ -40,40 +40,41 @@ private:
SurfaceTextureClient(const SurfaceTextureClient& rhs);
// ANativeWindow hooks
static int setSwapInterval(ANativeWindow* window, int interval);
static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
static int query(ANativeWindow* window, int what, int* value);
static int perform(ANativeWindow* window, int operation, ...);
static int query(ANativeWindow* window, int what, int* value);
static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
static int setSwapInterval(ANativeWindow* window, int interval);
int setSwapInterval(int interval);
int cancelBuffer(android_native_buffer_t* buffer);
int dequeueBuffer(android_native_buffer_t** buffer);
int lockBuffer(android_native_buffer_t* buffer);
int queueBuffer(android_native_buffer_t* buffer);
int cancelBuffer(android_native_buffer_t* buffer);
int query(int what, int* value);
int perform(int operation, va_list args);
int query(int what, int* value);
int queueBuffer(android_native_buffer_t* buffer);
int setSwapInterval(int interval);
int dispatchSetUsage(va_list args);
int dispatchConnect(va_list args);
int dispatchDisconnect(va_list args);
int dispatchSetCrop(va_list args);
int dispatchSetBufferCount(va_list args);
int dispatchSetBuffersGeometry(va_list args);
int dispatchSetBuffersTransform(va_list args);
int dispatchSetCrop(va_list args);
int dispatchSetUsage(va_list args);
int connect(int api);
int disconnect(int api);
int setUsage(uint32_t reqUsage);
int setCrop(Rect const* rect);
int setBufferCount(int bufferCount);
int setBuffersGeometry(int w, int h, int format);
int setBuffersTransform(int transform);
int setCrop(Rect const* rect);
int setUsage(uint32_t reqUsage);
void freeAllBuffers();
enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS };
enum { MIN_BUFFER_SLOTS = SurfaceTexture::MIN_BUFFER_SLOTS };
enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS };
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };

View File

@ -242,6 +242,10 @@ private:
status_t validate(bool inCancelBuffer = false) const;
sp<ISurface> getISurface() const;
// When the buffer pool is a fixed size we want to make sure SurfaceFlinger
// won't stall clients, so we require an extra buffer.
enum { MIN_UNDEQUEUED_BUFFERS = 2 };
inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }

View File

@ -75,6 +75,26 @@ enum {
NATIVE_WINDOW_WIDTH = 0,
NATIVE_WINDOW_HEIGHT,
NATIVE_WINDOW_FORMAT,
/* The minimum number of buffers that must remain un-dequeued after a buffer
* has been queued. This value applies only if set_buffer_count was used to
* override the number of buffers and if a buffer has since been queued.
* Users of the set_buffer_count ANativeWindow method should query this
* value before calling set_buffer_count. If it is necessary to have N
* buffers simultaneously dequeued as part of the steady-state operation,
* and this query returns M then N+M buffers should be requested via
* native_window_set_buffer_count.
*
* Note that this value does NOT apply until a single buffer has been
* queued. In particular this means that it is possible to:
*
* 1. Query M = min undequeued buffers
* 2. Set the buffer count to N + M
* 3. Dequeue all N + M buffers
* 4. Cancel M buffers
* 5. Queue, dequeue, queue, dequeue, ad infinitum
*/
NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
};
/* valid operations for the (*perform)() hook */

View File

@ -96,6 +96,11 @@ SurfaceTexture::~SurfaceTexture() {
status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGV("SurfaceTexture::setBufferCount");
if (bufferCount < MIN_BUFFER_SLOTS) {
return BAD_VALUE;
}
Mutex::Autolock lock(mMutex);
freeAllBuffers();
mBufferCount = bufferCount;

View File

@ -143,8 +143,21 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
int SurfaceTextureClient::query(int what, int* value) {
LOGV("SurfaceTextureClient::query");
Mutex::Autolock lock(mMutex);
// XXX: Implement this!
return INVALID_OPERATION;
switch (what) {
case NATIVE_WINDOW_WIDTH:
case NATIVE_WINDOW_HEIGHT:
// XXX: How should SurfaceTexture behave if setBuffersGeometry didn't
// override the size?
*value = 0;
return NO_ERROR;
case NATIVE_WINDOW_FORMAT:
*value = DEFAULT_FORMAT;
return NO_ERROR;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
*value = MIN_UNDEQUEUED_BUFFERS;
return NO_ERROR;
}
return BAD_VALUE;
}
int SurfaceTextureClient::perform(int operation, va_list args)

View File

@ -709,6 +709,9 @@ int Surface::query(int what, int* value)
case NATIVE_WINDOW_FORMAT:
*value = int(mFormat);
return NO_ERROR;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
*value = MIN_UNDEQUEUED_BUFFERS;
return NO_ERROR;
}
return BAD_VALUE;
}