[ANativeWindow] Add stub for ANativeWindow_setDequeueTimeout
HWUI and media both require setting a dequeue timeout so that dequeue
calls don't hang.
Bug: 137012798
Test: libnativewindow_test
Change-Id: Ic85b07096d490918ae4a722516b8c4b6cb0ab678
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index aad1849..fb9d742 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1084,6 +1084,9 @@
case NATIVE_WINDOW_GET_LAST_DEQUEUE_START:
res = dispatchGetLastDequeueStartTime(args);
break;
+ case NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT:
+ res = dispatchSetDequeueTimeout(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -1295,6 +1298,11 @@
return NO_ERROR;
}
+int Surface::dispatchSetDequeueTimeout(va_list args) {
+ nsecs_t timeout = va_arg(args, int64_t);
+ return setDequeueTimeout(timeout);
+}
+
bool Surface::transformToDisplayInverse() {
return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 5bcfcda..2527ec0 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -245,6 +245,7 @@
int dispatchGetConsumerUsage64(va_list args);
int dispatchSetAutoPrerotation(va_list args);
int dispatchGetLastDequeueStartTime(va_list args);
+ int dispatchSetDequeueTimeout(va_list args);
bool transformToDisplayInverse();
protected:
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index 3b195f7..fecfa19 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -284,3 +284,7 @@
int success = window->perform(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START, &time);
return success < 0 ? success : time;
}
+
+int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout) {
+ return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, timeout);
+}
diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h
index 3ddd549..9798c2f 100644
--- a/libs/nativewindow/include/apex/window.h
+++ b/libs/nativewindow/include/apex/window.h
@@ -48,4 +48,13 @@
*/
int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window);
+/**
+ * Sets a timeout in nanoseconds for dequeue calls. All subsequent dequeue calls
+ * made by the window will return -ETIMEDOUT after the timeout if the dequeue
+ * takes too long.
+ *
+ * \return NO_ERROR on succes, -errno on error.
+ */
+int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout);
+
__END_DECLS
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index b7ae28a..8f85007 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -240,6 +240,7 @@
NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
NATIVE_WINDOW_SET_AUTO_PREROTATION = 35,
NATIVE_WINDOW_GET_LAST_DEQUEUE_START = 36, /* private */
+ NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT = 37, /* private */
// clang-format on
};
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index 33c6400..b741faa 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -40,6 +40,7 @@
ANativeWindow_setBuffersGeometry;
ANativeWindow_setBuffersTimestamp; # vndk
ANativeWindow_setBuffersTransform;
+ ANativeWindow_setDequeueTimeout; # apex # introduced=30
ANativeWindow_setSharedBufferMode; # vndk
ANativeWindow_setSwapInterval; # vndk
ANativeWindow_setUsage; # vndk
diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp
index 947217d..4d2b8c8 100644
--- a/libs/nativewindow/tests/ANativeWindowTest.cpp
+++ b/libs/nativewindow/tests/ANativeWindowTest.cpp
@@ -138,3 +138,31 @@
EXPECT_GT(result, 0);
EXPECT_EQ(result, mWindow->getLastDequeueStartTime());
}
+
+TEST_F(ANativeWindowTest, setDequeueTimeout_causesDequeueTimeout) {
+ nsecs_t timeout = milliseconds_to_nanoseconds(100);
+ int result = ANativeWindow_setDequeueTimeout(mWindow.get(), timeout);
+ EXPECT_EQ(0, result);
+
+ // The two dequeues should not timeout...
+ ANativeWindowBuffer* buffer;
+ int fd;
+ int dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
+ close(fd);
+ EXPECT_EQ(0, dequeueResult);
+ int queueResult = ANativeWindow_queueBuffer(mWindow.get(), buffer, -1);
+ EXPECT_EQ(0, queueResult);
+ dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
+ close(fd);
+ EXPECT_EQ(0, dequeueResult);
+ queueResult = ANativeWindow_queueBuffer(mWindow.get(), buffer, -1);
+ EXPECT_EQ(0, queueResult);
+
+ // ...but the third one should since the queue depth is too deep.
+ nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
+ dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd);
+ nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
+ close(fd);
+ EXPECT_EQ(TIMED_OUT, dequeueResult);
+ EXPECT_GE(end - start, timeout);
+}