add a way to query whether an ANativeWindow consumer is running ahead of the producer

Change-Id: Ibccfa1feb56db2ab11f0c0934ce2d570a2b65ae2
This commit is contained in:
Mathias Agopian 2012-04-20 17:19:28 -07:00
parent 24202f5676
commit 2488b20aec
4 changed files with 51 additions and 15 deletions

View File

@ -107,21 +107,26 @@ protected:
struct QueueBufferOutput {
inline QueueBufferOutput() { }
inline void deflate(uint32_t* outWidth,
uint32_t* outHeight, uint32_t* outTransformHint) const {
uint32_t* outHeight,
uint32_t* outTransformHint,
uint32_t* outNumPendingBuffers) const {
*outWidth = width;
*outHeight = height;
*outTransformHint = transformHint;
*outNumPendingBuffers = numPendingBuffers;
}
inline void inflate(uint32_t inWidth, uint32_t inHeight,
uint32_t inTransformHint) {
uint32_t inTransformHint, uint32_t inNumPendingBuffers) {
width = inWidth;
height = inHeight;
transformHint = inTransformHint;
numPendingBuffers = inNumPendingBuffers;
}
private:
uint32_t width;
uint32_t height;
uint32_t transformHint;
uint32_t numPendingBuffers;
};
virtual status_t queueBuffer(int slot,

View File

@ -187,6 +187,10 @@ private:
// window. this is only a hint, actual transform may differ.
uint32_t mTransformHint;
// mConsumerRunningBehind whether the consumer is running more than
// one buffer behind the producer.
mutable bool mConsumerRunningBehind;
// mMutex is the mutex used to prevent concurrent access to the member
// variables of SurfaceTexture objects. It must be locked whenever the
// member variables are accessed.

View File

@ -252,6 +252,9 @@ int BufferQueue::query(int what, int* outValue)
value = mSynchronousMode ?
(mMinUndequeuedBuffers-1) : mMinUndequeuedBuffers;
break;
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
value = (mQueue.size() >= 2);
break;
default:
return BAD_VALUE;
}
@ -615,7 +618,8 @@ status_t BufferQueue::queueBuffer(int buf,
mBufferHasBeenQueued = true;
mDequeueCondition.broadcast();
output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint);
output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
mQueue.size());
ATRACE_INT(mConsumerName.string(), mQueue.size());
} // scope for the lock
@ -678,7 +682,8 @@ status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
err = -EINVAL;
} else {
mConnectedApi = api;
output->inflate(mDefaultWidth, mDefaultHeight, mDefaultHeight);
output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
mQueue.size());
}
break;
default:

View File

@ -83,6 +83,7 @@ void SurfaceTextureClient::init() {
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
mConsumerRunningBehind = false;
mConnectedToCpu = false;
}
@ -243,7 +244,12 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
}
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint);
uint32_t numPendingBuffers = 0;
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
&numPendingBuffers);
mConsumerRunningBehind = (numPendingBuffers >= 2);
return err;
}
@ -259,17 +265,16 @@ int SurfaceTextureClient::query(int what, int* value) const {
return NO_ERROR;
}
break;
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
{
sp<ISurfaceComposer> composer(
ComposerService::getComposerService());
if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
*value = 1;
} else {
*value = 0;
}
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
sp<ISurfaceComposer> composer(
ComposerService::getComposerService());
if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
*value = 1;
} else {
*value = 0;
}
return NO_ERROR;
}
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
return NO_ERROR;
@ -282,6 +287,18 @@ int SurfaceTextureClient::query(int what, int* value) const {
case NATIVE_WINDOW_TRANSFORM_HINT:
*value = mTransformHint;
return NO_ERROR;
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
status_t err = NO_ERROR;
if (!mConsumerRunningBehind) {
*value = 0;
} else {
err = mSurfaceTexture->query(what, value);
if (err == NO_ERROR) {
mConsumerRunningBehind = *value;
}
}
return err;
}
}
}
return mSurfaceTexture->query(what, value);
@ -431,7 +448,12 @@ int SurfaceTextureClient::connect(int api) {
Mutex::Autolock lock(mMutex);
ISurfaceTexture::QueueBufferOutput output;
int err = mSurfaceTexture->connect(api, &output);
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint);
if (err == NO_ERROR) {
uint32_t numPendingBuffers = 0;
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
&numPendingBuffers);
mConsumerRunningBehind = (numPendingBuffers >= 2);
}
if (!err && api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = true;
}