add a way to query whether an ANativeWindow consumer is running ahead of the producer
Change-Id: Ibccfa1feb56db2ab11f0c0934ce2d570a2b65ae2
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index 929eda2..1e33764 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -107,21 +107,26 @@
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,
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 6644751..7fd9be5 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -187,6 +187,10 @@
// 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.
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 5941dc2..39e9724 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -252,6 +252,9 @@
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 @@
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 @@
err = -EINVAL;
} else {
mConnectedApi = api;
- output->inflate(mDefaultWidth, mDefaultHeight, mDefaultHeight);
+ output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,
+ mQueue.size());
}
break;
default:
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 48d3b6f..788524b 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -83,6 +83,7 @@
mUserWidth = 0;
mUserHeight = 0;
mTransformHint = 0;
+ mConsumerRunningBehind = false;
mConnectedToCpu = false;
}
@@ -243,7 +244,12 @@
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 @@
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 @@
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 @@
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;
}