Add support for timestamps into SurfaceTexture.
API addition: The timestamps are represented as nanoseconds from some
arbitrary time point. Like the SurfaceTexture transform matrix, the
timestamp retrieved by getTimestamp is for the last frame sent to the
GL texture using updateTexImage().
Camera HAL change: Expect vendors to set these timestamps using
native_window_set_buffers_timestamp(). For now, they are
autogenerated by SurfaceTextureClient if set_buffers_timestamp() is
never called, but such timing is likely not accurate enough to pass a
CTS test.
bug:3300707
Change-Id: Ife131a0c2a826ac27342e11b8a6c42ff49e1bea7
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 7f1d9cb..a4812d0 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -26,7 +26,8 @@
SurfaceTextureClient::SurfaceTextureClient(
const sp<ISurfaceTexture>& surfaceTexture):
mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(1),
- mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() {
+ mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0),
+ mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), mMutex() {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = setSwapInterval;
ANativeWindow::dequeueBuffer = dequeueBuffer;
@@ -135,9 +136,17 @@
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
LOGV("SurfaceTextureClient::queueBuffer");
Mutex::Autolock lock(mMutex);
+ int64_t timestamp;
+ if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
+ timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ LOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
+ timestamp / 1000000.f);
+ } else {
+ timestamp = mTimestamp;
+ }
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (mSlots[i]->handle == buffer->handle) {
- return mSurfaceTexture->queueBuffer(i);
+ return mSurfaceTexture->queueBuffer(i, timestamp);
}
}
LOGE("queueBuffer: unknown buffer queued");
@@ -196,6 +205,9 @@
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
res = dispatchSetBuffersTransform(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ res = dispatchSetBuffersTimestamp(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -240,6 +252,11 @@
return setBuffersTransform(transform);
}
+int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
+ int64_t timestamp = va_arg(args, int64_t);
+ return setBuffersTimestamp(timestamp);
+}
+
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
// XXX: Implement this!
@@ -323,6 +340,14 @@
return err;
}
+int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
+{
+ LOGV("SurfaceTextureClient::setBuffersTimestamp");
+ Mutex::Autolock lock(mMutex);
+ mTimestamp = timestamp;
+ return NO_ERROR;
+}
+
void SurfaceTextureClient::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i] = 0;