From 538cedc381f66f6b07265f82be65e5bc725c7e87 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Mon, 24 Jun 2019 19:35:03 -0700 Subject: BufferQueue: handle consumer driven size for pre-rotation This change adds an option for the producer to set auto pre-rotation on the buffers to be allocated. When auto pre-rotation is enabled, if the current buffer size is driven by the consumer and there's 90 or 270 degree rotation specified in the transform hint currently used by the producer, then the dimension of the buffers to be allocated will be additionally swapped upon buffers pre-allocaton or dequeueBuffer. Auto prerotaion will be cached at Surface producer side, and will be reset to false upon Surface disconnection. Bug: 129422697 Test: atest libgui_test:SurfaceTest#DequeueWithConsumerDrivenSize Change-Id: I01ddf3e00d5951935e557d18932ea9869f36b5d6 --- libs/nativewindow/ANativeWindow.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 8435dac636..1751443419 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -262,3 +262,7 @@ int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMo int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh) { return native_window_set_auto_refresh(window, autoRefresh); } + +int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation) { + return native_window_set_auto_prerotation(window, autoPrerotation); +} -- cgit v1.2.3-59-g8ed1b From 9fa2cb6c5af15e5386c4632aed4847057c08340b Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 15 Jul 2019 17:36:26 -0700 Subject: [ANativeWindow] Add test infrastructure for apex apis * Add ANativeWindow_getLastDequeueDuration as proof of concept * Add ANativeWindowTest harness * apex/ include directory for code living in apex modules, so that vndk or system apis aren't pulled in * TEST_MAPPING configuration for presubmit Note that we're not piggybacking off of the existing Surface_test harness, as those tests assume that the libgui Surface is The ANativeWindow surface implementation, which means that those tests may test implementation details that the harness defined in this change should not attempt to test. Further, if an alternative implementation is provided (e.g. an ANativeWindow -> BLAST adapter), we should be able to parameterize the tests here. For now, however, we'll keep the assumption that Surface is the only relevant surface implementation so that nonzero tests may be written. Bug: 137012161 Bug: 137012798 Test: libnativewindow_test Change-Id: I0dddc348563ba95530fb1bd04bde66080755a91d --- libs/gui/TEST_MAPPING | 7 +++ libs/nativewindow/ANativeWindow.cpp | 8 +++ libs/nativewindow/TEST_MAPPING | 7 +++ libs/nativewindow/include/apex/window.h | 34 +++++++++++++ libs/nativewindow/include/system/window.h | 3 +- libs/nativewindow/libnativewindow.map.txt | 1 + libs/nativewindow/tests/ANativeWindowTest.cpp | 72 +++++++++++++++++++++++++++ libs/nativewindow/tests/Android.bp | 13 ++++- libs/nativewindow/tests/c_compatibility.c | 1 + 9 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 libs/gui/TEST_MAPPING create mode 100644 libs/nativewindow/TEST_MAPPING create mode 100644 libs/nativewindow/include/apex/window.h create mode 100644 libs/nativewindow/tests/ANativeWindowTest.cpp (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/TEST_MAPPING b/libs/gui/TEST_MAPPING new file mode 100644 index 0000000000..1c435304a8 --- /dev/null +++ b/libs/gui/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "imports": [ + { + "path": "frameworks/native/libs/nativewindow" + } + ] +} diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 1751443419..4c59e6ce98 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -266,3 +266,11 @@ int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh) { int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation) { return native_window_set_auto_prerotation(window, autoPrerotation); } + +/************************************************************************************************** + * apex-stable + **************************************************************************************************/ + +int ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_LAST_DEQUEUE_DURATION); +} diff --git a/libs/nativewindow/TEST_MAPPING b/libs/nativewindow/TEST_MAPPING new file mode 100644 index 0000000000..3d7f3c28f4 --- /dev/null +++ b/libs/nativewindow/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "libnativewindow_test" + } + ] +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h new file mode 100644 index 0000000000..0260cbcfb4 --- /dev/null +++ b/libs/nativewindow/include/apex/window.h @@ -0,0 +1,34 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +// apex is a superset of the NDK +#include + +__BEGIN_DECLS + +/** + * Retrieves how long it took for the last time a buffer was dequeued. + * + * \return a negative value on error, otherwise returns the duration in + * microseconds. + */ +int ANativeWindow_getLastDequeueDuration(ANativeWindow* window); + +__END_DECLS diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 8cbf0a4244..78354bba6b 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -41,7 +41,8 @@ #include #include -// system/window.h is a superset of the vndk +// system/window.h is a superset of the vndk and apex apis +#include #include diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 119a07dad7..7fe4df0606 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -22,6 +22,7 @@ LIBNATIVEWINDOW { ANativeWindow_getBuffersDataSpace; # introduced=28 ANativeWindow_getFormat; ANativeWindow_getHeight; + ANativeWindow_getLastDequeueDuration; # apex # introduced=30 ANativeWindow_getWidth; ANativeWindow_lock; ANativeWindow_query; # vndk diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp new file mode 100644 index 0000000000..a80da24a47 --- /dev/null +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -0,0 +1,72 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ANativeWindow_test" +//#define LOG_NDEBUG 0 + +#include +#include +#include +#include +#include +#include +// We need to use the private system apis since not everything is visible to +// apexes yet. +#include + +using namespace android; + +class ANativeWindowTest : public ::testing::Test { +protected: + void SetUp() override { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGV("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + BufferQueue::createBufferQueue(&mProducer, &mConsumer); + mItemConsumer = new BufferItemConsumer(mConsumer, GRALLOC_USAGE_SW_READ_OFTEN); + mWindow = new Surface(mProducer); + const int success = native_window_api_connect(mWindow.get(), NATIVE_WINDOW_API_CPU); + EXPECT_EQ(0, success); + } + + void TearDown() override { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGV("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); + const int success = native_window_api_disconnect(mWindow.get(), NATIVE_WINDOW_API_CPU); + EXPECT_EQ(0, success); + } + sp mProducer; + sp mConsumer; + sp mItemConsumer; + sp mWindow; +}; + +TEST_F(ANativeWindowTest, getLastDequeueDuration_noDequeue_returnsZero) { + int result = ANativeWindow_getLastDequeueDuration(mWindow.get()); + EXPECT_EQ(0, result); +} + +TEST_F(ANativeWindowTest, getLastDequeueDuration_withDequeue_returnsTime) { + ANativeWindowBuffer* buffer; + int fd; + int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd); + close(fd); + EXPECT_EQ(0, result); + + result = ANativeWindow_getLastDequeueDuration(mWindow.get()); + EXPECT_GT(result, 0); +} diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp index 20071be668..cdb3d2054f 100644 --- a/libs/nativewindow/tests/Android.bp +++ b/libs/nativewindow/tests/Android.bp @@ -15,13 +15,22 @@ // cc_test { - name: "AHardwareBufferTest", + name: "libnativewindow_test", + test_suites: [ + "device-tests", + ], shared_libs: [ + "libgui", + "liblog", "libnativewindow", + "libsync", + "libutils", "android.hardware.graphics.common@1.0", ], srcs: [ "AHardwareBufferTest.cpp", - "c_compatibility.c"], + "ANativeWindowTest.cpp", + "c_compatibility.c", + ], cflags: ["-Wall", "-Werror"], } diff --git a/libs/nativewindow/tests/c_compatibility.c b/libs/nativewindow/tests/c_compatibility.c index befd88fd07..aa9b4f7e78 100644 --- a/libs/nativewindow/tests/c_compatibility.c +++ b/libs/nativewindow/tests/c_compatibility.c @@ -16,6 +16,7 @@ #include #include +#include #include #include -- cgit v1.2.3-59-g8ed1b From 0d1398b2da8aee028c52a90be6d3b75b4f12b9d6 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Wed, 14 Aug 2019 10:53:50 -0700 Subject: [ANativeWindow] Add apex header for getLastQueueDuration Bug: 137012798 Test: libnativewindow_test Change-Id: I46d5ab9c11161923ebbbc67400b10b2e7c0c6b61 --- libs/nativewindow/ANativeWindow.cpp | 4 +++ libs/nativewindow/include/apex/window.h | 8 ++++++ libs/nativewindow/libnativewindow.map.txt | 1 + libs/nativewindow/tests/ANativeWindowTest.cpp | 35 +++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 4c59e6ce98..5c91d587bc 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -274,3 +274,7 @@ int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation int ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { return query(window, NATIVE_WINDOW_LAST_DEQUEUE_DURATION); } + +int ANativeWindow_getLastQueueDuration(ANativeWindow* window) { + return query(window, NATIVE_WINDOW_LAST_QUEUE_DURATION); +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 0260cbcfb4..82ff50d2d5 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -31,4 +31,12 @@ __BEGIN_DECLS */ int ANativeWindow_getLastDequeueDuration(ANativeWindow* window); +/** + * Retrieves how long it took for the last time a buffer was queued. + * + * \return a negative value on error, otherwise returns the duration in + * microseconds + */ +int ANativeWindow_getLastQueueDuration(ANativeWindow* window); + __END_DECLS diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 7fe4df0606..b8b45ae62b 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -23,6 +23,7 @@ LIBNATIVEWINDOW { ANativeWindow_getFormat; ANativeWindow_getHeight; ANativeWindow_getLastDequeueDuration; # apex # introduced=30 + ANativeWindow_getLastQueueDuration; # apex # introduced=30 ANativeWindow_getWidth; ANativeWindow_lock; ANativeWindow_query; # vndk diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp index 5247e04c32..9b358da4b5 100644 --- a/libs/nativewindow/tests/ANativeWindowTest.cpp +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -36,6 +36,9 @@ public: // Exposes the internal last dequeue duration that's stored on the Surface. nsecs_t getLastDequeueDuration() const { return mLastDequeueDuration; } + + // Exposes the internal last queue duration that's stored on the Surface. + nsecs_t getLastQueueDuration() const { return mLastQueueDuration; } }; class ANativeWindowTest : public ::testing::Test { @@ -82,3 +85,35 @@ TEST_F(ANativeWindowTest, getLastDequeueDuration_withDequeue_returnsTime) { EXPECT_GT(result, 0); EXPECT_EQ(result, mWindow->getLastDequeueDuration() / 1000); } + +TEST_F(ANativeWindowTest, getLastQueueDuration_noDequeue_returnsZero) { + int result = ANativeWindow_getLastQueueDuration(mWindow.get()); + EXPECT_EQ(0, result); + EXPECT_EQ(0, mWindow->getLastQueueDuration()); +} + +TEST_F(ANativeWindowTest, getLastQueueDuration_noQueue_returnsZero) { + ANativeWindowBuffer* buffer; + int fd; + int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd); + close(fd); + EXPECT_EQ(0, result); + + result = ANativeWindow_getLastQueueDuration(mWindow.get()); + EXPECT_EQ(result, 0); + EXPECT_EQ(result, mWindow->getLastQueueDuration()); +} + +TEST_F(ANativeWindowTest, getLastQueueDuration_withQueue_returnsTime) { + ANativeWindowBuffer* buffer; + int fd; + int result = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd); + close(fd); + EXPECT_EQ(0, result); + + result = ANativeWindow_queueBuffer(mWindow.get(), buffer, 0); + + result = ANativeWindow_getLastQueueDuration(mWindow.get()); + EXPECT_GT(result, 0); + EXPECT_EQ(result, mWindow->getLastQueueDuration() / 1000); +} -- cgit v1.2.3-59-g8ed1b From a161966a658f46f8bec93ea0490bef799843c3c6 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Wed, 21 Aug 2019 19:30:48 -0700 Subject: [ANativeWindow] Add apex stub for getLastDequeueStartTime Also adding private query64 hook so that timing queries can have nanosecond precision. Otherwise with a 32-bit width we can only have millisecond precision for timestamps and microsecond precision for time intervals, and really we shouldn't need to be less precise if we can help it. Bug: 137012798 Test: libnativewindow_test Change-Id: I62233a588eee80f7ea70b74824c8e47461a3be81 --- libs/gui/Surface.cpp | 14 +++++++++----- libs/gui/include/gui/Surface.h | 4 +--- libs/gui/tests/Surface_test.cpp | 2 +- libs/nativewindow/ANativeWindow.cpp | 6 ++++++ libs/nativewindow/include/apex/window.h | 9 +++++++++ libs/nativewindow/include/system/window.h | 2 +- libs/nativewindow/libnativewindow.map.txt | 1 + libs/nativewindow/tests/ANativeWindowTest.cpp | 21 +++++++++++++++++++++ 8 files changed, 49 insertions(+), 10 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 7e356e4eb1..aad18491b4 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1081,6 +1081,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_AUTO_PREROTATION: res = dispatchSetAutoPrerotation(args); break; + case NATIVE_WINDOW_GET_LAST_DEQUEUE_START: + res = dispatchGetLastDequeueStartTime(args); + break; default: res = NAME_NOT_FOUND; break; @@ -1286,6 +1289,12 @@ int Surface::dispatchSetAutoPrerotation(va_list args) { return setAutoPrerotation(autoPrerotation); } +int Surface::dispatchGetLastDequeueStartTime(va_list args) { + int64_t* lastDequeueStartTime = va_arg(args, int64_t*); + *lastDequeueStartTime = mLastDequeueStartTime; + return NO_ERROR; +} + bool Surface::transformToDisplayInverse() { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; @@ -1950,11 +1959,6 @@ int Surface::getConsumerUsage(uint64_t* outUsage) const { return mGraphicBufferProducer->getConsumerUsage(outUsage); } -nsecs_t Surface::getLastDequeueStartTime() const { - Mutex::Autolock lock(mMutex); - return mLastDequeueStartTime; -} - status_t Surface::getAndFlushRemovedBuffers(std::vector>* out) { if (out == nullptr) { ALOGE("%s: out must not be null!", __FUNCTION__); diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 28f5a26072..5bcfcda6ad 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -179,9 +179,6 @@ public: status_t getUniqueId(uint64_t* outId) const; status_t getConsumerUsage(uint64_t* outUsage) const; - // Returns the CLOCK_MONOTONIC start time of the last dequeueBuffer call - nsecs_t getLastDequeueStartTime() const; - protected: virtual ~Surface(); @@ -247,6 +244,7 @@ private: int dispatchGetHdrSupport(va_list args); int dispatchGetConsumerUsage64(va_list args); int dispatchSetAutoPrerotation(va_list args); + int dispatchGetLastDequeueStartTime(va_list args); bool transformToDisplayInverse(); protected: diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 5a121d77ab..0b61d9231c 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -617,7 +617,7 @@ TEST_F(SurfaceTest, TestGetLastDequeueStartTime) { anw->dequeueBuffer(anw.get(), &buffer, &fenceFd); nsecs_t after = systemTime(CLOCK_MONOTONIC); - nsecs_t lastDequeueTime = mSurface->getLastDequeueStartTime(); + nsecs_t lastDequeueTime = ANativeWindow_getLastDequeueStartTime(anw.get()); ASSERT_LE(before, lastDequeueTime); ASSERT_GE(after, lastDequeueTime); } diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 5c91d587bc..3b195f7913 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -278,3 +278,9 @@ int ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { int ANativeWindow_getLastQueueDuration(ANativeWindow* window) { return query(window, NATIVE_WINDOW_LAST_QUEUE_DURATION); } + +int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) { + int64_t time; + int success = window->perform(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START, &time); + return success < 0 ? success : time; +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 82ff50d2d5..3ddd5493ac 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -39,4 +39,13 @@ int ANativeWindow_getLastDequeueDuration(ANativeWindow* window); */ int ANativeWindow_getLastQueueDuration(ANativeWindow* window); +/** + * Retrieves the system time in nanoseconds when the last time a buffer + * was dequeued. + * + * \return a negative value on error, otherwise returns the duration in + * nanoseconds. + */ +int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window); + __END_DECLS diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 78354bba6b..b7ae28a93c 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -93,7 +93,6 @@ enum { */ NATIVE_WINDOW_CONCRETE_TYPE = 5, - /* * Default width and height of ANativeWindow buffers, these are the * dimensions of the window buffers irrespective of the @@ -240,6 +239,7 @@ enum { NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34, NATIVE_WINDOW_SET_AUTO_PREROTATION = 35, + NATIVE_WINDOW_GET_LAST_DEQUEUE_START = 36, /* private */ // clang-format on }; diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index b8b45ae62b..33c6400d52 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -23,6 +23,7 @@ LIBNATIVEWINDOW { ANativeWindow_getFormat; ANativeWindow_getHeight; ANativeWindow_getLastDequeueDuration; # apex # introduced=30 + ANativeWindow_getLastDequeueStartTime; # apex # introduced=30 ANativeWindow_getLastQueueDuration; # apex # introduced=30 ANativeWindow_getWidth; ANativeWindow_lock; diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp index 9b358da4b5..947217d52c 100644 --- a/libs/nativewindow/tests/ANativeWindowTest.cpp +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -39,6 +39,9 @@ public: // Exposes the internal last queue duration that's stored on the Surface. nsecs_t getLastQueueDuration() const { return mLastQueueDuration; } + + // Exposes the internal last dequeue start time that's stored on the Surface. + nsecs_t getLastDequeueStartTime() const { return mLastDequeueStartTime; } }; class ANativeWindowTest : public ::testing::Test { @@ -117,3 +120,21 @@ TEST_F(ANativeWindowTest, getLastQueueDuration_withQueue_returnsTime) { EXPECT_GT(result, 0); EXPECT_EQ(result, mWindow->getLastQueueDuration() / 1000); } + +TEST_F(ANativeWindowTest, getLastDequeueStartTime_noDequeue_returnsZero) { + int64_t result = ANativeWindow_getLastDequeueStartTime(mWindow.get()); + EXPECT_EQ(0, result); + EXPECT_EQ(0, mWindow->getLastQueueDuration()); +} + +TEST_F(ANativeWindowTest, getLastDequeueStartTime_withDequeue_returnsTime) { + ANativeWindowBuffer* buffer; + int fd; + int dequeueResult = ANativeWindow_dequeueBuffer(mWindow.get(), &buffer, &fd); + close(fd); + EXPECT_EQ(0, dequeueResult); + + int64_t result = ANativeWindow_getLastDequeueStartTime(mWindow.get()); + EXPECT_GT(result, 0); + EXPECT_EQ(result, mWindow->getLastDequeueStartTime()); +} -- cgit v1.2.3-59-g8ed1b From 04fdb60d01038d4d1e82b4c71f9bd3e9c74cb031 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Fri, 23 Aug 2019 19:41:43 -0700 Subject: [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 --- libs/gui/Surface.cpp | 8 ++++++++ libs/gui/include/gui/Surface.h | 1 + libs/nativewindow/ANativeWindow.cpp | 4 ++++ libs/nativewindow/include/apex/window.h | 9 +++++++++ libs/nativewindow/include/system/window.h | 1 + libs/nativewindow/libnativewindow.map.txt | 1 + libs/nativewindow/tests/ANativeWindowTest.cpp | 28 +++++++++++++++++++++++++++ 7 files changed, 52 insertions(+) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index aad18491b4..fb9d7427d7 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1084,6 +1084,9 @@ int Surface::perform(int operation, va_list args) 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 @@ int Surface::dispatchGetLastDequeueStartTime(va_list args) { 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 5bcfcda6ad..2527ec0a75 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -245,6 +245,7 @@ private: 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 3b195f7913..fecfa193df 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -284,3 +284,7 @@ int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) { 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 3ddd5493ac..9798c2fd47 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -48,4 +48,13 @@ int ANativeWindow_getLastQueueDuration(ANativeWindow* window); */ 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 b7ae28a93c..8f850070b6 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -240,6 +240,7 @@ enum { 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 33c6400d52..b741faa11f 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -40,6 +40,7 @@ LIBNATIVEWINDOW { 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 947217d52c..4d2b8c8f3b 100644 --- a/libs/nativewindow/tests/ANativeWindowTest.cpp +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -138,3 +138,31 @@ TEST_F(ANativeWindowTest, getLastDequeueStartTime_withDequeue_returnsTime) { 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); +} -- cgit v1.2.3-59-g8ed1b From 72670c57aa1a158ab05055d65a618307d57bf154 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Sat, 31 Aug 2019 01:54:33 -0700 Subject: [ANativeWindow] Increase precision for duration queries. Use perform() instead in query() to retrieve dequeue/queue durations for nanosecond resolution. Bug: 137012798 Test: atest Change-Id: I894a8784f3321d4ab6f538d7e7fc1457de26f289 --- libs/gui/Surface.cpp | 18 ++++++++++++++++++ libs/gui/include/gui/Surface.h | 2 ++ libs/nativewindow/ANativeWindow.cpp | 18 +++++++++++------- libs/nativewindow/include/apex/window.h | 8 ++++---- libs/nativewindow/include/system/window.h | 12 +++++++++--- libs/nativewindow/tests/ANativeWindowTest.cpp | 6 +++--- 6 files changed, 47 insertions(+), 17 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index fb9d7427d7..e490d6d17d 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1087,6 +1087,12 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT: res = dispatchSetDequeueTimeout(args); break; + case NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION: + res = dispatchGetLastDequeueDuration(args); + break; + case NATIVE_WINDOW_GET_LAST_QUEUE_DURATION: + res = dispatchGetLastQueueDuration(args); + break; default: res = NAME_NOT_FOUND; break; @@ -1303,6 +1309,18 @@ int Surface::dispatchSetDequeueTimeout(va_list args) { return setDequeueTimeout(timeout); } +int Surface::dispatchGetLastDequeueDuration(va_list args) { + int64_t* lastDequeueDuration = va_arg(args, int64_t*); + *lastDequeueDuration = mLastDequeueDuration; + return NO_ERROR; +} + +int Surface::dispatchGetLastQueueDuration(va_list args) { + int64_t* lastQueueDuration = va_arg(args, int64_t*); + *lastQueueDuration = mLastQueueDuration; + return NO_ERROR; +} + 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 2527ec0a75..e582509b6e 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -246,6 +246,8 @@ private: int dispatchSetAutoPrerotation(va_list args); int dispatchGetLastDequeueStartTime(va_list args); int dispatchSetDequeueTimeout(va_list args); + int dispatchGetLastDequeueDuration(va_list args); + int dispatchGetLastQueueDuration(va_list args); bool transformToDisplayInverse(); protected: diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index fecfa193df..0ba01f4da4 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -33,6 +33,12 @@ static int32_t query(ANativeWindow* window, int what) { return res < 0 ? res : value; } +static int64_t query64(ANativeWindow* window, int what) { + int64_t value; + int res = window->perform(window, what, &value); + return res < 0 ? res : value; +} + static bool isDataSpaceValid(ANativeWindow* window, int32_t dataSpace) { bool supported = false; switch (dataSpace) { @@ -271,18 +277,16 @@ int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation * apex-stable **************************************************************************************************/ -int ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { - return query(window, NATIVE_WINDOW_LAST_DEQUEUE_DURATION); +int64_t ANativeWindow_getLastDequeueDuration(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION); } -int ANativeWindow_getLastQueueDuration(ANativeWindow* window) { - return query(window, NATIVE_WINDOW_LAST_QUEUE_DURATION); +int64_t ANativeWindow_getLastQueueDuration(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_LAST_QUEUE_DURATION); } int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) { - int64_t time; - int success = window->perform(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START, &time); - return success < 0 ? success : time; + return query64(window, NATIVE_WINDOW_GET_LAST_DEQUEUE_START); } int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout) { diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 9798c2fd47..869b22ec19 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -27,17 +27,17 @@ __BEGIN_DECLS * Retrieves how long it took for the last time a buffer was dequeued. * * \return a negative value on error, otherwise returns the duration in - * microseconds. + * nanoseconds */ -int ANativeWindow_getLastDequeueDuration(ANativeWindow* window); +int64_t ANativeWindow_getLastDequeueDuration(ANativeWindow* window); /** * Retrieves how long it took for the last time a buffer was queued. * * \return a negative value on error, otherwise returns the duration in - * microseconds + * nanoseconds. */ -int ANativeWindow_getLastQueueDuration(ANativeWindow* window); +int64_t ANativeWindow_getLastQueueDuration(ANativeWindow* window); /** * Retrieves the system time in nanoseconds when the last time a buffer diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 8f850070b6..1814ab5568 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -63,9 +63,9 @@ __BEGIN_DECLS /* attributes queriable with query() */ enum { - NATIVE_WINDOW_WIDTH = 0, - NATIVE_WINDOW_HEIGHT = 1, - NATIVE_WINDOW_FORMAT = 2, + NATIVE_WINDOW_WIDTH = 0, + NATIVE_WINDOW_HEIGHT = 1, + NATIVE_WINDOW_FORMAT = 2, /* see ANativeWindowQuery in vndk/window.h */ NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS, @@ -147,11 +147,15 @@ enum { /* * Returns the duration of the last dequeueBuffer call in microseconds + * Deprecated: please use NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION in + * perform() instead, which supports nanosecond precision. */ NATIVE_WINDOW_LAST_DEQUEUE_DURATION = 14, /* * Returns the duration of the last queueBuffer call in microseconds + * Deprecated: please use NATIVE_WINDOW_GET_LAST_QUEUE_DURATION in + * perform() instead, which supports nanosecond precision. */ NATIVE_WINDOW_LAST_QUEUE_DURATION = 15, @@ -241,6 +245,8 @@ enum { NATIVE_WINDOW_SET_AUTO_PREROTATION = 35, NATIVE_WINDOW_GET_LAST_DEQUEUE_START = 36, /* private */ NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT = 37, /* private */ + NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION = 38, /* private */ + NATIVE_WINDOW_GET_LAST_QUEUE_DURATION = 39, /* private */ // clang-format on }; diff --git a/libs/nativewindow/tests/ANativeWindowTest.cpp b/libs/nativewindow/tests/ANativeWindowTest.cpp index 4d2b8c8f3b..6cf8291da2 100644 --- a/libs/nativewindow/tests/ANativeWindowTest.cpp +++ b/libs/nativewindow/tests/ANativeWindowTest.cpp @@ -74,7 +74,7 @@ protected: TEST_F(ANativeWindowTest, getLastDequeueDuration_noDequeue_returnsZero) { int result = ANativeWindow_getLastDequeueDuration(mWindow.get()); EXPECT_EQ(0, result); - EXPECT_EQ(0, mWindow->getLastDequeueDuration() / 1000); + EXPECT_EQ(0, mWindow->getLastDequeueDuration()); } TEST_F(ANativeWindowTest, getLastDequeueDuration_withDequeue_returnsTime) { @@ -86,7 +86,7 @@ TEST_F(ANativeWindowTest, getLastDequeueDuration_withDequeue_returnsTime) { result = ANativeWindow_getLastDequeueDuration(mWindow.get()); EXPECT_GT(result, 0); - EXPECT_EQ(result, mWindow->getLastDequeueDuration() / 1000); + EXPECT_EQ(result, mWindow->getLastDequeueDuration()); } TEST_F(ANativeWindowTest, getLastQueueDuration_noDequeue_returnsZero) { @@ -118,7 +118,7 @@ TEST_F(ANativeWindowTest, getLastQueueDuration_withQueue_returnsTime) { result = ANativeWindow_getLastQueueDuration(mWindow.get()); EXPECT_GT(result, 0); - EXPECT_EQ(result, mWindow->getLastQueueDuration() / 1000); + EXPECT_EQ(result, mWindow->getLastQueueDuration()); } TEST_F(ANativeWindowTest, getLastDequeueStartTime_noDequeue_returnsZero) { -- cgit v1.2.3-59-g8ed1b From 91a2b3d80488ea105cf2ca76375f54791ef701e0 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Thu, 12 Dec 2019 21:33:11 -0800 Subject: Extend ADataspace. In order to allow NDK image decoding to access more color spaces, extend ADataspace to match Named.ColorSpace as many as possible. BUG: b/140635413 Test: build Change-Id: I8e06071060ab19b103900ff04d60f1c3d3fccda9 --- libs/nativewindow/ANativeWindow.cpp | 5 +++ libs/nativewindow/include/android/data_space.h | 50 ++++++++++++++++++++++ services/surfaceflinger/tests/Android.bp | 6 ++- services/surfaceflinger/tests/CommonTypes_test.cpp | 46 ++++++++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 0ba01f4da4..842af18c8c 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -138,6 +138,11 @@ int32_t ANativeWindow_setBuffersDataSpace(ANativeWindow* window, int32_t dataSpa static_assert(static_cast(ADATASPACE_SCRGB) == static_cast(HAL_DATASPACE_V0_SCRGB)); static_assert(static_cast(ADATASPACE_DISPLAY_P3) == static_cast(HAL_DATASPACE_DISPLAY_P3)); static_assert(static_cast(ADATASPACE_BT2020_PQ) == static_cast(HAL_DATASPACE_BT2020_PQ)); + static_assert(static_cast(ADATASPACE_ADOBE_RGB) == static_cast(HAL_DATASPACE_ADOBE_RGB)); + static_assert(static_cast(ADATASPACE_BT2020) == static_cast(HAL_DATASPACE_BT2020)); + static_assert(static_cast(ADATASPACE_BT709) == static_cast(HAL_DATASPACE_V0_BT709)); + static_assert(static_cast(ADATASPACE_DCI_P3) == static_cast(HAL_DATASPACE_DCI_P3)); + static_assert(static_cast(ADATASPACE_SRGB_LINEAR) == static_cast(HAL_DATASPACE_V0_SRGB_LINEAR)); if (!window || !query(window, NATIVE_WINDOW_IS_VALID) || !isDataSpaceValid(window, dataSpace)) { diff --git a/libs/nativewindow/include/android/data_space.h b/libs/nativewindow/include/android/data_space.h index 2899bcf1f7..e759513a63 100644 --- a/libs/nativewindow/include/android/data_space.h +++ b/libs/nativewindow/include/android/data_space.h @@ -101,6 +101,56 @@ enum ADataSpace { * Use full range, SMPTE 2084 (PQ) transfer and BT2020 standard */ ADATASPACE_BT2020_PQ = 163971072, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL + + /** + * Adobe RGB + * + * Use full range, gamma 2.2 transfer and Adobe RGB primaries + * Note: Application is responsible for gamma encoding the data as + * a 2.2 gamma encoding is not supported in HW. + */ + ADATASPACE_ADOBE_RGB = 151715840, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL + + /** + * ITU-R Recommendation 2020 (BT.2020) + * + * Ultra High-definition television + * + * Use full range, BT.709 transfer and BT2020 standard + */ + ADATASPACE_BT2020 = 147193856, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL + + /** + * ITU-R Recommendation 709 (BT.709) + * + * High-definition television + * + * Use limited range, BT.709 transfer and BT.709 standard. + */ + ADATASPACE_BT709 = 281083904, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED + + /** + * SMPTE EG 432-1 and SMPTE RP 431-2. + * + * Digital Cinema DCI-P3 + * + * Use full range, gamma 2.6 transfer and D65 DCI-P3 standard + * Note: Application is responsible for gamma encoding the data as + * a 2.6 gamma encoding is not supported in HW. + */ + ADATASPACE_DCI_P3 = 155844608, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL + + /** + * sRGB linear encoding: + * + * The red, green, and blue components are stored in sRGB space, but + * are linear, not gamma-encoded. + * The RGB primaries and the white point are the same as BT.709. + * + * The values are encoded using the full range ([0,255] for 8-bit) for all + * components. + */ + ADATASPACE_SRGB_LINEAR = 138477568, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL }; __END_DECLS diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index a4d9ff3539..0403237371 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -53,11 +53,15 @@ cc_test { "libgui", "liblayers_proto", "liblog", + "libnativewindow", "libprotobuf-cpp-full", "libtimestats_proto", "libui", "libutils", - ] + ], + header_libs: [ + "libnativewindow_headers", + ], } cc_defaults { diff --git a/services/surfaceflinger/tests/CommonTypes_test.cpp b/services/surfaceflinger/tests/CommonTypes_test.cpp index ab4af09fac..25b4615239 100644 --- a/services/surfaceflinger/tests/CommonTypes_test.cpp +++ b/services/surfaceflinger/tests/CommonTypes_test.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -34,6 +35,51 @@ static_assert(static_cast(AidlBlendMode::PREMULTIPLIED) == static_assert(static_cast(AidlBlendMode::COVERAGE) == static_cast(HidlBlendMode::COVERAGE)); +static_assert(static_cast(ADATASPACE_UNKNOWN) == + static_cast(AidlDataspace::UNKNOWN)); +static_assert(static_cast(ADATASPACE_SCRGB_LINEAR) == + static_cast(AidlDataspace::SCRGB_LINEAR)); +static_assert(static_cast(ADATASPACE_SRGB) == static_cast(AidlDataspace::SRGB)); +static_assert(static_cast(ADATASPACE_SCRGB) == + static_cast(AidlDataspace::SCRGB)); +static_assert(static_cast(ADATASPACE_DISPLAY_P3) == + static_cast(AidlDataspace::DISPLAY_P3)); +static_assert(static_cast(ADATASPACE_BT2020_PQ) == + static_cast(AidlDataspace::BT2020_PQ)); +static_assert(static_cast(ADATASPACE_ADOBE_RGB) == + static_cast(AidlDataspace::ADOBE_RGB)); +static_assert(static_cast(ADATASPACE_BT2020) == + static_cast(AidlDataspace::BT2020)); +static_assert(static_cast(ADATASPACE_BT709) == + static_cast(AidlDataspace::BT709)); +static_assert(static_cast(ADATASPACE_DCI_P3) == + static_cast(AidlDataspace::DCI_P3)); +static_assert(static_cast(ADATASPACE_SRGB_LINEAR) == + static_cast(AidlDataspace::SRGB_LINEAR)); + +static_assert(static_cast(ADATASPACE_UNKNOWN) == + static_cast(HidlDataspace::UNKNOWN)); +static_assert(static_cast(ADATASPACE_SCRGB_LINEAR) == + static_cast(HidlDataspace::V0_SCRGB_LINEAR)); +static_assert(static_cast(ADATASPACE_SRGB) == + static_cast(HidlDataspace::V0_SRGB)); +static_assert(static_cast(ADATASPACE_SCRGB) == + static_cast(HidlDataspace::V0_SCRGB)); +static_assert(static_cast(ADATASPACE_DISPLAY_P3) == + static_cast(HidlDataspace::DISPLAY_P3)); +static_assert(static_cast(ADATASPACE_BT2020_PQ) == + static_cast(HidlDataspace::BT2020_PQ)); +static_assert(static_cast(ADATASPACE_ADOBE_RGB) == + static_cast(HidlDataspace::ADOBE_RGB)); +static_assert(static_cast(ADATASPACE_BT2020) == + static_cast(HidlDataspace::BT2020)); +static_assert(static_cast(ADATASPACE_BT709) == + static_cast(HidlDataspace::V0_BT709)); +static_assert(static_cast(ADATASPACE_DCI_P3) == + static_cast(HidlDataspace::DCI_P3)); +static_assert(static_cast(ADATASPACE_SRGB_LINEAR) == + static_cast(HidlDataspace::V0_SRGB_LINEAR)); + static_assert(static_cast(AidlDataspace::UNKNOWN) == static_cast(HidlDataspace::UNKNOWN)); static_assert(static_cast(AidlDataspace::ARBITRARY) == -- cgit v1.2.3-59-g8ed1b From 6d88a487b0fe7f72314f81e81c9786005032afa3 Mon Sep 17 00:00:00 2001 From: Steven Thomas Date: Mon, 2 Dec 2019 22:00:47 -0800 Subject: Add setFrameRate() api setFrameRate() is a new api in Android 11 that will enable apps to specify their intended frame rate. Bug: 143912624 Bug: 137287430 Test: Added a new CTS test - android.graphics.cts.SetFrameRateTest. Change-Id: I0150055fbffd37f2d644829e9dadbfc517045d8e --- include/android/surface_control.h | 27 +++++++++++++++++++ libs/nativewindow/ANativeWindow.cpp | 7 +++++ libs/nativewindow/include/android/native_window.h | 33 +++++++++++++++++++++++ libs/nativewindow/libnativewindow.map.txt | 1 + 4 files changed, 68 insertions(+) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/include/android/surface_control.h b/include/android/surface_control.h index 31abb6622e..157b4242fe 100644 --- a/include/android/surface_control.h +++ b/include/android/surface_control.h @@ -407,6 +407,33 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio #endif // __ANDROID_API__ >= 29 +#if __ANDROID_API__ >= 30 + +/* + * Sets the intended frame rate for |surface_control|. + * + * On devices that are capable of running the display at different refresh rates, the system may + * choose a display refresh rate to better match this surface's frame rate. Usage of this API won't + * directly affect the application's frame production pipeline. However, because the system may + * change the display refresh rate, calls to this function may result in changes to Choreographer + * callback timings, and changes to the time interval at which the system releases buffers back to + * the application. + * + * |frameRate| is the intended frame rate of this surface. 0 is a special value that indicates the + * app will accept the system's choice for the display frame rate, which is the default behavior if + * this function isn't called. The frameRate param does *not* need to be a valid refresh rate for + * this device's display - e.g., it's fine to pass 30fps to a device that can only run the display + * at 60fps. + * + * Available since API level 30. + */ +void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction, + ASurfaceControl* surface_control, + float frameRate) + __INTRODUCED_IN(30); + +#endif // __ANDROID_API__ >= 30 + __END_DECLS #endif // ANDROID_SURFACE_CONTROL_H diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 842af18c8c..a60bc4dad3 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -158,6 +158,13 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) { return query(window, NATIVE_WINDOW_DATASPACE); } +int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) { + if (!window || !query(window, NATIVE_WINDOW_IS_VALID) || frameRate < 0) { + return -EINVAL; + } + return native_window_set_frame_rate(window, frameRate); +} + /************************************************************************************************** * vndk-stable **************************************************************************************************/ diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index 3e436e3b07..0637db390d 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -230,6 +230,39 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) __INTRODUCED_IN #endif // __ANDROID_API__ >= 28 +#if __ANDROID_API__ >= 30 + +/** + * Sets the intended frame rate for this window. + * + * On devices that are capable of running the display at different refresh + * rates, the system may choose a display refresh rate to better match this + * window's frame rate. Usage of this API won't introduce frame rate throttling, + * or affect other aspects of the application's frame production + * pipeline. However, because the system may change the display refresh rate, + * calls to this function may result in changes to Choreographer callback + * timings, and changes to the time interval at which the system releases + * buffers back to the application. + * + * Note that this only has an effect for windows presented on the display. If + * this ANativeWindow is consumed by something other than the system compositor, + * e.g. a media codec, this call has no effect. + * + * Available since API level 30. + * + * \param frameRate The intended frame rate of this window. 0 is a special value + * that indicates the app will accept the system's choice for the display frame + * rate, which is the default behavior if this function isn't called. The + * frameRate param does *not* need to be a valid refresh rate for this device's + * display - e.g., it's fine to pass 30fps to a device that can only run the + * display at 60fps. + * + * \return 0 for success, -EINVAL if the window or frame rate are invalid. + */ +int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) __INTRODUCED_IN(30); + +#endif // __ANDROID_API__ >= 30 + #ifdef __cplusplus }; #endif diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index f59e8f0546..3002da29e7 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -43,6 +43,7 @@ LIBNATIVEWINDOW { ANativeWindow_setDequeueTimeout; # apex # introduced=30 ANativeWindow_setSharedBufferMode; # llndk ANativeWindow_setSwapInterval; # llndk + ANativeWindow_setFrameRate; # introduced=30 ANativeWindow_setUsage; # llndk ANativeWindow_unlockAndPost; local: -- cgit v1.2.3-59-g8ed1b From 09d122a798c8436a7e32ab4ca49a0e73398cf106 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 25 Nov 2019 10:00:53 -0800 Subject: [ANativeWindow] Support interception methods in apex This is to support HWUI's ReliableSurface. Test: builds Test: Hook up with HWUI and manually verify with settings app Change-Id: I3a1d75dbd993dde1771930ad25212d8e4e7d94a0 --- libs/gui/Surface.cpp | 133 +++++++++++++++++++++++++-- libs/gui/include/gui/Surface.h | 28 +++++- libs/nativewindow/ANativeWindow.cpp | 23 +++++ libs/nativewindow/include/apex/window.h | 147 ++++++++++++++++++++++++++++++ libs/nativewindow/include/system/window.h | 12 ++- libs/nativewindow/libnativewindow.map.txt | 4 + 6 files changed, 333 insertions(+), 14 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index d5cf11d305..e7880ebc39 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -50,6 +50,17 @@ namespace android { using ui::ColorMode; using ui::Dataspace; +namespace { + +bool isInterceptorRegistrationOp(int op) { + return op == NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR || + op == NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR || + op == NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR || + op == NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR; +} + +} // namespace + Surface::Surface(const sp& bufferProducer, bool controlledByApp) : mGraphicBufferProducer(bufferProducer), mCrop(Rect::EMPTY_RECT), @@ -366,18 +377,58 @@ int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { int Surface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) { Surface* c = getSelf(window); + { + std::shared_lock lock(c->mInterceptorMutex); + if (c->mDequeueInterceptor != nullptr) { + auto interceptor = c->mDequeueInterceptor; + auto data = c->mDequeueInterceptorData; + return interceptor(window, Surface::dequeueBufferInternal, data, buffer, fenceFd); + } + } + return c->dequeueBuffer(buffer, fenceFd); +} + +int Surface::dequeueBufferInternal(ANativeWindow* window, ANativeWindowBuffer** buffer, + int* fenceFd) { + Surface* c = getSelf(window); return c->dequeueBuffer(buffer, fenceFd); } int Surface::hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) { Surface* c = getSelf(window); + { + std::shared_lock lock(c->mInterceptorMutex); + if (c->mCancelInterceptor != nullptr) { + auto interceptor = c->mCancelInterceptor; + auto data = c->mCancelInterceptorData; + return interceptor(window, Surface::cancelBufferInternal, data, buffer, fenceFd); + } + } + return c->cancelBuffer(buffer, fenceFd); +} + +int Surface::cancelBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) { + Surface* c = getSelf(window); return c->cancelBuffer(buffer, fenceFd); } int Surface::hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) { Surface* c = getSelf(window); + { + std::shared_lock lock(c->mInterceptorMutex); + if (c->mQueueInterceptor != nullptr) { + auto interceptor = c->mQueueInterceptor; + auto data = c->mQueueInterceptorData; + return interceptor(window, Surface::queueBufferInternal, data, buffer, fenceFd); + } + } + return c->queueBuffer(buffer, fenceFd); +} + +int Surface::queueBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) { + Surface* c = getSelf(window); return c->queueBuffer(buffer, fenceFd); } @@ -420,21 +471,38 @@ int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, return c->queueBuffer(buffer, -1); } -int Surface::hook_query(const ANativeWindow* window, - int what, int* value) { - const Surface* c = getSelf(window); - return c->query(what, value); -} - int Surface::hook_perform(ANativeWindow* window, int operation, ...) { va_list args; va_start(args, operation); Surface* c = getSelf(window); - int result = c->perform(operation, args); + int result; + // Don't acquire shared ownership of the interceptor mutex if we're going to + // do interceptor registration, as otherwise we'll deadlock on acquiring + // exclusive ownership. + if (!isInterceptorRegistrationOp(operation)) { + std::shared_lock lock(c->mInterceptorMutex); + if (c->mPerformInterceptor != nullptr) { + result = c->mPerformInterceptor(window, Surface::performInternal, + c->mPerformInterceptorData, operation, args); + va_end(args); + return result; + } + } + result = c->perform(operation, args); va_end(args); return result; } +int Surface::performInternal(ANativeWindow* window, int operation, va_list args) { + Surface* c = getSelf(window); + return c->perform(operation, args); +} + +int Surface::hook_query(const ANativeWindow* window, int what, int* value) { + const Surface* c = getSelf(window); + return c->query(what, value); +} + int Surface::setSwapInterval(int interval) { ATRACE_CALL(); // EGL specification states: @@ -1096,6 +1164,18 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_FRAME_RATE: res = dispatchSetFrameRate(args); break; + case NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR: + res = dispatchAddCancelInterceptor(args); + break; + case NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR: + res = dispatchAddDequeueInterceptor(args); + break; + case NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR: + res = dispatchAddPerformInterceptor(args); + break; + case NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR: + res = dispatchAddQueueInterceptor(args); + break; default: res = NAME_NOT_FOUND; break; @@ -1329,6 +1409,45 @@ int Surface::dispatchSetFrameRate(va_list args) { return setFrameRate(frameRate); } +int Surface::dispatchAddCancelInterceptor(va_list args) { + ANativeWindow_cancelBufferInterceptor interceptor = + va_arg(args, ANativeWindow_cancelBufferInterceptor); + void* data = va_arg(args, void*); + std::lock_guard lock(mInterceptorMutex); + mCancelInterceptor = interceptor; + mCancelInterceptorData = data; + return NO_ERROR; +} + +int Surface::dispatchAddDequeueInterceptor(va_list args) { + ANativeWindow_dequeueBufferInterceptor interceptor = + va_arg(args, ANativeWindow_dequeueBufferInterceptor); + void* data = va_arg(args, void*); + std::lock_guard lock(mInterceptorMutex); + mDequeueInterceptor = interceptor; + mDequeueInterceptorData = data; + return NO_ERROR; +} + +int Surface::dispatchAddPerformInterceptor(va_list args) { + ANativeWindow_performInterceptor interceptor = va_arg(args, ANativeWindow_performInterceptor); + void* data = va_arg(args, void*); + std::lock_guard lock(mInterceptorMutex); + mPerformInterceptor = interceptor; + mPerformInterceptorData = data; + return NO_ERROR; +} + +int Surface::dispatchAddQueueInterceptor(va_list args) { + ANativeWindow_queueBufferInterceptor interceptor = + va_arg(args, ANativeWindow_queueBufferInterceptor); + void* data = va_arg(args, void*); + std::lock_guard lock(mInterceptorMutex); + mQueueInterceptor = interceptor; + mQueueInterceptorData = data; + return NO_ERROR; +} + 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 86cc61f3ec..0139507101 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -21,16 +21,15 @@ #include #include #include - +#include #include #include #include - #include #include #include -#include +#include namespace android { @@ -205,6 +204,13 @@ private: ANativeWindowBuffer* buffer, int fenceFd); static int hook_setSwapInterval(ANativeWindow* window, int interval); + static int cancelBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, + int fenceFd); + static int dequeueBufferInternal(ANativeWindow* window, ANativeWindowBuffer** buffer, + int* fenceFd); + static int performInternal(ANativeWindow* window, int operation, va_list args); + static int queueBufferInternal(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd); + static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer); static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, @@ -252,6 +258,10 @@ private: int dispatchGetLastDequeueDuration(va_list args); int dispatchGetLastQueueDuration(va_list args); int dispatchSetFrameRate(va_list args); + int dispatchAddCancelInterceptor(va_list args); + int dispatchAddDequeueInterceptor(va_list args); + int dispatchAddPerformInterceptor(va_list args); + int dispatchAddQueueInterceptor(va_list args); bool transformToDisplayInverse(); protected: @@ -457,6 +467,18 @@ protected: // member variables are accessed. mutable Mutex mMutex; + // mInterceptorMutex is the mutex guarding interceptors. + std::shared_mutex mInterceptorMutex; + + ANativeWindow_cancelBufferInterceptor mCancelInterceptor = nullptr; + void* mCancelInterceptorData = nullptr; + ANativeWindow_dequeueBufferInterceptor mDequeueInterceptor = nullptr; + void* mDequeueInterceptorData = nullptr; + ANativeWindow_performInterceptor mPerformInterceptor = nullptr; + void* mPerformInterceptorData = nullptr; + ANativeWindow_queueBufferInterceptor mQueueInterceptor = nullptr; + void* mQueueInterceptorData = nullptr; + // must be used from the lock/unlock thread sp mLockedBuffer; sp mPostedBuffer; diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 842af18c8c..7fdbeb5a06 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -297,3 +297,26 @@ int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window) { int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout) { return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, timeout); } + +int ANativeWindow_setCancelBufferInterceptor(ANativeWindow* window, + ANativeWindow_cancelBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setDequeueBufferInterceptor(ANativeWindow* window, + ANativeWindow_dequeueBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setPerformInterceptor(ANativeWindow* window, + ANativeWindow_performInterceptor interceptor, void* data) { + return window->perform(window, NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR, interceptor, data); +} + +int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, + ANativeWindow_queueBufferInterceptor interceptor, + void* data) { + return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data); +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 869b22ec19..2060d037e2 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -17,12 +17,159 @@ #pragma once #include +#include // apex is a superset of the NDK #include __BEGIN_DECLS +/* + * perform bits that can be used with ANativeWindow_perform() + * + * This is only to support the intercepting methods below - these should notbe + * used directly otherwise. + */ +enum ANativeWindowPerform { + // clang-format off + ANATIVEWINDOW_PERFORM_SET_USAGE = 0, + ANATIVEWINDOW_PERFORM_SET_BUFFERS_GEOMETRY = 5, + ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT = 9, + ANATIVEWINDOW_PERFORM_SET_USAGE64 = 30, + // clang-format on +}; + +/** + * Prototype of the function that an ANativeWindow implementation would call + * when ANativeWindow_cancelBuffer is called. + */ +typedef int (*ANativeWindow_cancelBufferFn)(ANativeWindow* window, ANativeWindowBuffer* buffer, + int fenceFd); + +/** + * Prototype of the function that intercepts an invocation of + * ANativeWindow_cancelBufferFn, along with a data pointer that's passed by the + * caller who set the interceptor, as well as arguments that would be + * passed to ANativeWindow_cancelBufferFn if it were to be called. + */ +typedef int (*ANativeWindow_cancelBufferInterceptor)(ANativeWindow* window, + ANativeWindow_cancelBufferFn cancelBuffer, + void* data, ANativeWindowBuffer* buffer, + int fenceFd); + +/** + * Prototype of the function that an ANativeWindow implementation would call + * when ANativeWindow_dequeueBuffer is called. + */ +typedef int (*ANativeWindow_dequeueBufferFn)(ANativeWindow* window, ANativeWindowBuffer** buffer, + int* fenceFd); + +/** + * Prototype of the function that intercepts an invocation of + * ANativeWindow_dequeueBufferFn, along with a data pointer that's passed by the + * caller who set the interceptor, as well as arguments that would be + * passed to ANativeWindow_dequeueBufferFn if it were to be called. + */ +typedef int (*ANativeWindow_dequeueBufferInterceptor)(ANativeWindow* window, + ANativeWindow_dequeueBufferFn dequeueBuffer, + void* data, ANativeWindowBuffer** buffer, + int* fenceFd); + +/** + * Prototype of the function that an ANativeWindow implementation would call + * when ANativeWindow_perform is called. + */ +typedef int (*ANativeWindow_performFn)(ANativeWindow* window, int operation, va_list args); + +/** + * Prototype of the function that intercepts an invocation of + * ANativeWindow_performFn, along with a data pointer that's passed by the + * caller who set the interceptor, as well as arguments that would be + * passed to ANativeWindow_performFn if it were to be called. + */ +typedef int (*ANativeWindow_performInterceptor)(ANativeWindow* window, + ANativeWindow_performFn perform, void* data, + int operation, va_list args); + +/** + * Prototype of the function that an ANativeWindow implementation would call + * when ANativeWindow_queueBuffer is called. + */ +typedef int (*ANativeWindow_queueBufferFn)(ANativeWindow* window, ANativeWindowBuffer* buffer, + int fenceFd); + +/** + * Prototype of the function that intercepts an invocation of + * ANativeWindow_queueBufferFn, along with a data pointer that's passed by the + * caller who set the interceptor, as well as arguments that would be + * passed to ANativeWindow_queueBufferFn if it were to be called. + */ +typedef int (*ANativeWindow_queueBufferInterceptor)(ANativeWindow* window, + ANativeWindow_queueBufferFn queueBuffer, + void* data, ANativeWindowBuffer* buffer, + int fenceFd); + +/** + * Registers an interceptor for ANativeWindow_cancelBuffer. Instead of calling + * the underlying cancelBuffer function, instead the provided interceptor is + * called, which may optionally call the underlying cancelBuffer function. An + * optional data pointer is also provided to side-channel additional arguments. + * + * Note that usage of this should only be used for specialized use-cases by + * either the system partition or to Mainline modules. This should never be + * exposed to NDK or LL-NDK. + * + * Returns NO_ERROR on success, -errno if registration failed. + */ +int ANativeWindow_setCancelBufferInterceptor(ANativeWindow* window, + ANativeWindow_cancelBufferInterceptor interceptor, + void* data); + +/** + * Registers an interceptor for ANativeWindow_dequeueBuffer. Instead of calling + * the underlying dequeueBuffer function, instead the provided interceptor is + * called, which may optionally call the underlying dequeueBuffer function. An + * optional data pointer is also provided to side-channel additional arguments. + * + * Note that usage of this should only be used for specialized use-cases by + * either the system partition or to Mainline modules. This should never be + * exposed to NDK or LL-NDK. + * + * Returns NO_ERROR on success, -errno if registration failed. + */ +int ANativeWindow_setDequeueBufferInterceptor(ANativeWindow* window, + ANativeWindow_dequeueBufferInterceptor interceptor, + void* data); +/** + * Registers an interceptor for ANativeWindow_perform. Instead of calling + * the underlying perform function, instead the provided interceptor is + * called, which may optionally call the underlying perform function. An + * optional data pointer is also provided to side-channel additional arguments. + * + * Note that usage of this should only be used for specialized use-cases by + * either the system partition or to Mainline modules. This should never be + * exposed to NDK or LL-NDK. + * + * Returns NO_ERROR on success, -errno if registration failed. + */ +int ANativeWindow_setPerformInterceptor(ANativeWindow* window, + ANativeWindow_performInterceptor interceptor, void* data); +/** + * Registers an interceptor for ANativeWindow_queueBuffer. Instead of calling + * the underlying queueBuffer function, instead the provided interceptor is + * called, which may optionally call the underlying queueBuffer function. An + * optional data pointer is also provided to side-channel additional arguments. + * + * Note that usage of this should only be used for specialized use-cases by + * either the system partition or to Mainline modules. This should never be + * exposed to NDK or LL-NDK. + * + * Returns NO_ERROR on success, -errno if registration failed. + */ +int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, + ANativeWindow_queueBufferInterceptor interceptor, + void* data); + /** * Retrieves how long it took for the last time a buffer was dequeued. * diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 14f7214882..a4e5afd38d 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -207,16 +207,16 @@ enum { */ enum { // clang-format off - NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */ + NATIVE_WINDOW_SET_USAGE = ANATIVEWINDOW_PERFORM_SET_USAGE, /* deprecated */ NATIVE_WINDOW_CONNECT = 1, /* deprecated */ NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */ NATIVE_WINDOW_SET_CROP = 3, /* private */ NATIVE_WINDOW_SET_BUFFER_COUNT = 4, - NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */ + NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = ANATIVEWINDOW_PERFORM_SET_BUFFERS_GEOMETRY, /* deprecated */ NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8, - NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9, + NATIVE_WINDOW_SET_BUFFERS_FORMAT = ANATIVEWINDOW_PERFORM_SET_BUFFERS_FORMAT, NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */ NATIVE_WINDOW_LOCK = 11, /* private */ NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */ @@ -237,7 +237,7 @@ enum { NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27, NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28, NATIVE_WINDOW_GET_HDR_SUPPORT = 29, - NATIVE_WINDOW_SET_USAGE64 = 30, + NATIVE_WINDOW_SET_USAGE64 = ANATIVEWINDOW_PERFORM_SET_USAGE64, NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31, NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32, NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33, @@ -248,6 +248,10 @@ enum { NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION = 38, /* private */ NATIVE_WINDOW_GET_LAST_QUEUE_DURATION = 39, /* private */ NATIVE_WINDOW_SET_FRAME_RATE = 40, + NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR = 41, /* private */ + NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR = 42, /* private */ + NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR = 43, /* private */ + NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR = 44, /* private */ // clang-format on }; diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index f59e8f0546..127e633247 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -30,6 +30,10 @@ LIBNATIVEWINDOW { ANativeWindow_query; # llndk ANativeWindow_queryf; # llndk ANativeWindow_queueBuffer; # llndk + ANativeWindow_setCancelBufferInterceptor; # apex # introduced=30 + ANativeWindow_setDequeueBufferInterceptor; # apex # introduced=30 + ANativeWindow_setPerformInterceptor; # apex # introduced=30 + ANativeWindow_setQueueBufferInterceptor; # apex # introduced=30 ANativeWindow_release; ANativeWindow_setAutoPrerotation; # llndk ANativeWindow_setAutoRefresh; # llndk -- cgit v1.2.3-59-g8ed1b From 74aef6d55db3e2a34369142b738b8270d242739e Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 9 Dec 2019 17:10:24 -0800 Subject: [ANativeWindow] Add ANativeWindow_allocateBuffers stable abi. Bug: 137012798 Test: builds Change-Id: Ibe2afe83d48adb583bfbda088376fcf402050814 --- libs/gui/Surface.cpp | 4 ++++ libs/nativewindow/ANativeWindow.cpp | 4 ++++ libs/nativewindow/include/apex/window.h | 10 +++++++++- libs/nativewindow/include/system/window.h | 1 + libs/nativewindow/libnativewindow.map.txt | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index e7880ebc39..23532e7e38 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1176,6 +1176,10 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR: res = dispatchAddQueueInterceptor(args); break; + case NATIVE_WINDOW_ALLOCATE_BUFFERS: + allocateBuffers(); + res = NO_ERROR; + break; default: res = NAME_NOT_FOUND; break; diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 7fdbeb5a06..06b793660d 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -320,3 +320,7 @@ int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, void* data) { return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data); } + +void ANativeWindow_allocateBuffers(ANativeWindow* window) { + window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 2060d037e2..3dec011a93 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -200,8 +200,16 @@ int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window); * made by the window will return -ETIMEDOUT after the timeout if the dequeue * takes too long. * - * \return NO_ERROR on succes, -errno on error. + * \return NO_ERROR on success, -errno on error. */ int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout); +/** + * Provides a hint to the window that buffers should be preallocated ahead of + * time. Note that the window implementation is not guaranteed to preallocate + * any buffers, for instance if a private API disallows allocation of new + * buffers. As such no success/error status is returned. + */ +void ANativeWindow_allocateBuffers(ANativeWindow* window); + __END_DECLS diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index a4e5afd38d..121374b1d5 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -252,6 +252,7 @@ enum { NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR = 42, /* private */ NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR = 43, /* private */ NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR = 44, /* private */ + NATIVE_WINDOW_ALLOCATE_BUFFERS = 45, /* private */ // clang-format on }; diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 127e633247..148bf07d0d 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -17,6 +17,7 @@ LIBNATIVEWINDOW { ANativeWindow_OemStorageGet; # llndk ANativeWindow_OemStorageSet; # llndk ANativeWindow_acquire; + ANativeWindow_allocateBuffers; # apex # introduced=30 ANativeWindow_cancelBuffer; # llndk ANativeWindow_dequeueBuffer; # llndk ANativeWindow_getBuffersDataSpace; # introduced=28 -- cgit v1.2.3-59-g8ed1b From ca87ad94879593d8f0c7b7580dd74779ed95cd88 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Tue, 10 Dec 2019 15:06:53 -0800 Subject: [ANativeWindow] add ANativeWindow_getNextFrameId api. Stable API for getNextFrameNumber. Here the naming is mirroring the existing EGL api for eglGetNextFrameIdANDROID. Bug: 137012798 Test: builds Change-Id: I8bf6fb198055a295b8aa68d3b9db2577376d39b1 --- libs/nativewindow/ANativeWindow.cpp | 4 ++++ libs/nativewindow/include/apex/window.h | 7 +++++++ libs/nativewindow/libnativewindow.map.txt | 1 + 3 files changed, 12 insertions(+) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 2caffca828..a1c9eb806b 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -331,3 +331,7 @@ int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, void ANativeWindow_allocateBuffers(ANativeWindow* window) { window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); } + +int64_t ANativeWindow_getNextFrameId(ANativeWindow* window) { + return query64(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID); +} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 3dec011a93..02b886c4f0 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -212,4 +212,11 @@ int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout); */ void ANativeWindow_allocateBuffers(ANativeWindow* window); +/** + * Retrieves an identifier for the next frame to be queued by this window. + * + * \return -errno on error, otherwise returns the next frame id. + */ +int64_t ANativeWindow_getNextFrameId(ANativeWindow* window); + __END_DECLS diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 427f317406..e0e20c3ae2 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -26,6 +26,7 @@ LIBNATIVEWINDOW { ANativeWindow_getLastDequeueDuration; # apex # introduced=30 ANativeWindow_getLastDequeueStartTime; # apex # introduced=30 ANativeWindow_getLastQueueDuration; # apex # introduced=30 + ANativeWindow_getNextFrameId; # apex # introduced=30 ANativeWindow_getWidth; ANativeWindow_lock; ANativeWindow_query; # llndk -- cgit v1.2.3-59-g8ed1b From d9d8572a850fa179f8ba81d6dd673d90d83e7742 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 13 Feb 2020 13:57:19 -0800 Subject: [ANativeWindow] allocateBuffers changes * rename allocateBuffers to tryAllocateBuffers to reflect that its a best-effort API * promote to public NDK Bug: 148962594 Test: builds Change-Id: Iff73c2eb7bb07d28ef26b95202257950e9da4627 --- libs/nativewindow/ANativeWindow.cpp | 12 ++++++++---- libs/nativewindow/include/android/native_window.h | 11 +++++++++++ libs/nativewindow/libnativewindow.map.txt | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index a1c9eb806b..98b76fd667 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -165,6 +165,14 @@ int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) { return native_window_set_frame_rate(window, frameRate); } +void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { + if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { + return; + } + window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); +} + + /************************************************************************************************** * vndk-stable **************************************************************************************************/ @@ -328,10 +336,6 @@ int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data); } -void ANativeWindow_allocateBuffers(ANativeWindow* window) { - window->perform(window, NATIVE_WINDOW_ALLOCATE_BUFFERS); -} - int64_t ANativeWindow_getNextFrameId(ANativeWindow* window) { return query64(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID); } diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index 262aee3501..4b426c518a 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -261,6 +261,17 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) __INTRODUCED_IN */ int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) __INTRODUCED_IN(30); +/** + * Provides a hint to the window that buffers should be preallocated ahead of + * time. Note that the window implementation is not guaranteed to preallocate + * any buffers, for instance if an implementation disallows allocation of new + * buffers, or if there is insufficient memory in the system to preallocate + * additional buffers + * + * Available since API level 30. + */ +void ANativeWindow_tryAllocateBuffers(ANativeWindow* window); + #endif // __ANDROID_API__ >= 30 #ifdef __cplusplus diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index e0e20c3ae2..154eb8eb52 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -17,7 +17,6 @@ LIBNATIVEWINDOW { ANativeWindow_OemStorageGet; # llndk ANativeWindow_OemStorageSet; # llndk ANativeWindow_acquire; - ANativeWindow_allocateBuffers; # apex # introduced=30 ANativeWindow_cancelBuffer; # llndk ANativeWindow_dequeueBuffer; # llndk ANativeWindow_getBuffersDataSpace; # introduced=28 @@ -51,6 +50,7 @@ LIBNATIVEWINDOW { ANativeWindow_setSwapInterval; # llndk ANativeWindow_setFrameRate; # introduced=30 ANativeWindow_setUsage; # llndk + ANativeWindow_tryAllocateBuffers; # introduced=30 ANativeWindow_unlockAndPost; local: *; -- cgit v1.2.3-59-g8ed1b From d41a1be2d7a0a46be45c7f6338b739c49bef824e Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Fri, 14 Feb 2020 15:18:11 -0800 Subject: [ANativeWindow] Apply remaining API feedback * move ANativeWindow_getFrameId to a platform api, as native_window_get_frame_timestamps is not stable and therefore the associated api surface is not complete enough to be stable. * Adjust documentation for returned errors. In most cases errors aren't returned in practice. In the case of ANativeWindow_setDequeueTimeout the errors are enumerated explicitly. Bug: 148962594 Test: builds Change-Id: I1ff5113d91fdcfc4679b2862af72fbf811171253 --- libs/nativewindow/ANativeWindow.cpp | 4 ---- libs/nativewindow/include/apex/window.h | 34 ++++++++++--------------------- libs/nativewindow/include/system/window.h | 11 ++++++++++ libs/nativewindow/libnativewindow.map.txt | 1 - 4 files changed, 22 insertions(+), 28 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 98b76fd667..d0d1114d30 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -335,7 +335,3 @@ int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, void* data) { return window->perform(window, NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR, interceptor, data); } - -int64_t ANativeWindow_getNextFrameId(ANativeWindow* window) { - return query64(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID); -} diff --git a/libs/nativewindow/include/apex/window.h b/libs/nativewindow/include/apex/window.h index 02b886c4f0..2d1354cdf1 100644 --- a/libs/nativewindow/include/apex/window.h +++ b/libs/nativewindow/include/apex/window.h @@ -173,25 +173,22 @@ int ANativeWindow_setQueueBufferInterceptor(ANativeWindow* window, /** * Retrieves how long it took for the last time a buffer was dequeued. * - * \return a negative value on error, otherwise returns the duration in - * nanoseconds + * \return the dequeue duration in nanoseconds */ int64_t ANativeWindow_getLastDequeueDuration(ANativeWindow* window); /** * Retrieves how long it took for the last time a buffer was queued. * - * \return a negative value on error, otherwise returns the duration in - * nanoseconds. + * \return the queue duration in nanoseconds */ int64_t ANativeWindow_getLastQueueDuration(ANativeWindow* window); /** * Retrieves the system time in nanoseconds when the last time a buffer - * was dequeued. + * started to be dequeued. * - * \return a negative value on error, otherwise returns the duration in - * nanoseconds. + * \return the start time in nanoseconds */ int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window); @@ -200,23 +197,14 @@ int64_t ANativeWindow_getLastDequeueStartTime(ANativeWindow* window); * made by the window will return -ETIMEDOUT after the timeout if the dequeue * takes too long. * - * \return NO_ERROR on success, -errno on error. - */ -int ANativeWindow_setDequeueTimeout(ANativeWindow* window, int64_t timeout); - -/** - * Provides a hint to the window that buffers should be preallocated ahead of - * time. Note that the window implementation is not guaranteed to preallocate - * any buffers, for instance if a private API disallows allocation of new - * buffers. As such no success/error status is returned. - */ -void ANativeWindow_allocateBuffers(ANativeWindow* window); - -/** - * Retrieves an identifier for the next frame to be queued by this window. + * If the provided timeout is negative, hen this removes the previously configured + * timeout. The window then behaves as if ANativeWindow_setDequeueTimeout was + * never called. * - * \return -errno on error, otherwise returns the next frame id. + * \return NO_ERROR on success + * \return BAD_VALUE if the dequeue timeout was unabled to be updated, as + * updating the dequeue timeout may change internals of the underlying window. */ -int64_t ANativeWindow_getNextFrameId(ANativeWindow* window); +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 f686147a5f..c791b61753 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1049,4 +1049,15 @@ static inline int ANativeWindow_getLastQueuedBuffer(ANativeWindow* window, outTransformMatrix); } +/** + * Retrieves an identifier for the next frame to be queued by this window. + * + * \return the next frame id. + */ +static inline int64_t ANativeWindow_getNextFrameId(ANativeWindow* window) { + int64_t value; + window->perform(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID, &value); + return value; +} + __END_DECLS diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 154eb8eb52..35f0627e90 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -25,7 +25,6 @@ LIBNATIVEWINDOW { ANativeWindow_getLastDequeueDuration; # apex # introduced=30 ANativeWindow_getLastDequeueStartTime; # apex # introduced=30 ANativeWindow_getLastQueueDuration; # apex # introduced=30 - ANativeWindow_getNextFrameId; # apex # introduced=30 ANativeWindow_getWidth; ANativeWindow_lock; ANativeWindow_query; # llndk -- cgit v1.2.3-59-g8ed1b From 62a4cf8c48647de3442808264005e093ab7704f0 Mon Sep 17 00:00:00 2001 From: Steven Thomas Date: Fri, 31 Jan 2020 12:04:03 -0800 Subject: Add compatibility param to setFrameRate() api Add a compatiblity param to the setFrameRate() api, so the system has more info to decide the device frame rate when there are multiple competing preferences. I also changed the plumbing for setFrameRate() to go directly to surface flinger, instead of through buffer queue. We're trying to avoid changes to buffer queue code, to avoid disturbing the prebuilts. Bug: 137287430 Test: Added new cts tests to verify behavior of the compatibility param. cts-tradefed run commandAndExit cts-dev --module CtsGraphicsTestCases --test android.graphics.cts.SetFrameRateTest Test: /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test --gtest_filter='SetFrameRateTest.*' Change-Id: Ibe75a778fb459d4138a1446c1b38b44798b56a99 --- include/android/surface_control.h | 9 ++- libs/gui/ISurfaceComposer.cpp | 66 ++++++++++++++++++++++ libs/gui/LayerState.cpp | 22 ++++++++ libs/gui/Surface.cpp | 16 ++++-- libs/gui/SurfaceComposerClient.cpp | 7 ++- libs/gui/include/gui/ISurfaceComposer.h | 7 +++ libs/gui/include/gui/LayerState.h | 15 ++++- libs/gui/include/gui/Surface.h | 2 +- libs/gui/include/gui/SurfaceComposerClient.h | 3 +- libs/gui/tests/Surface_test.cpp | 5 ++ libs/nativewindow/ANativeWindow.cpp | 6 +- libs/nativewindow/include/android/native_window.h | 29 +++++++++- libs/nativewindow/include/system/window.h | 6 +- libs/nativewindow/libnativewindow.map.txt | 2 +- services/surfaceflinger/BufferQueueLayer.cpp | 13 ----- services/surfaceflinger/BufferQueueLayer.h | 5 -- services/surfaceflinger/Layer.cpp | 13 +++++ services/surfaceflinger/Layer.h | 6 +- services/surfaceflinger/Scheduler/LayerHistory.cpp | 1 - services/surfaceflinger/SurfaceFlinger.cpp | 35 +++++++++++- services/surfaceflinger/SurfaceFlinger.h | 2 + .../surfaceflinger/tests/SetFrameRate_test.cpp | 14 +++-- 22 files changed, 236 insertions(+), 48 deletions(-) (limited to 'libs/nativewindow/ANativeWindow.cpp') diff --git a/include/android/surface_control.h b/include/android/surface_control.h index eeb8330efd..c30dcfee09 100644 --- a/include/android/surface_control.h +++ b/include/android/surface_control.h @@ -425,12 +425,15 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio * valid refresh rate for this device's display - e.g., it's fine to pass 30fps to a device that can * only run the display at 60fps. * + * |compatibility| The frame rate compatibility of this surface. The compatibility value may + * influence the system's choice of display frame rate. To specify a compatibility use the + * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum. + * * Available since API level 30. */ void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction, - ASurfaceControl* surface_control, - float frameRate) - __INTRODUCED_IN(30); + ASurfaceControl* surface_control, float frameRate, + int8_t compatibility) __INTRODUCED_IN(30); #endif // __ANDROID_API__ >= 30 diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 2f27fd20fd..ce41eaba1d 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -1112,6 +1112,42 @@ public: } return NO_ERROR; } + + virtual status_t setFrameRate(const sp& surface, float frameRate, + int8_t compatibility) { + Parcel data, reply; + status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed writing interface token: %s (%d)", strerror(-err), -err); + return err; + } + + err = data.writeStrongBinder(IInterface::asBinder(surface)); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed writing strong binder: %s (%d)", strerror(-err), -err); + return err; + } + + err = data.writeFloat(frameRate); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed writing float: %s (%d)", strerror(-err), -err); + return err; + } + + err = data.writeByte(compatibility); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed writing byte: %s (%d)", strerror(-err), -err); + return err; + } + + err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply, + IBinder::FLAG_ONEWAY); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err); + return err; + } + return NO_ERROR; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -1877,6 +1913,36 @@ status_t BnSurfaceComposer::onTransact( return setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius); } + case SET_FRAME_RATE: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp binder; + status_t err = data.readStrongBinder(&binder); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed to read strong binder: %s (%d)", strerror(-err), -err); + return err; + } + sp surface = interface_cast(binder); + if (!surface) { + ALOGE("setFrameRate: failed to cast to IGraphicBufferProducer: %s (%d)", + strerror(-err), -err); + return err; + } + float frameRate; + err = data.readFloat(&frameRate); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed to read float: %s (%d)", strerror(-err), -err); + return err; + } + int8_t compatibility; + err = data.readByte(&compatibility); + if (err != NO_ERROR) { + ALOGE("setFrameRate: failed to read byte: %s (%d)", strerror(-err), -err); + return err; + } + status_t result = setFrameRate(surface, frameRate, compatibility); + reply->writeInt32(result); + return NO_ERROR; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 5547efc3ad..a9c9b7460b 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -24,6 +24,8 @@ #include #include +#include + namespace android { status_t layer_state_t::write(Parcel& output) const @@ -113,6 +115,7 @@ status_t layer_state_t::write(Parcel& output) const output.writeFloat(shadowRadius); output.writeInt32(frameRateSelectionPriority); output.writeFloat(frameRate); + output.writeByte(frameRateCompatibility); return NO_ERROR; } @@ -194,6 +197,7 @@ status_t layer_state_t::read(const Parcel& input) shadowRadius = input.readFloat(); frameRateSelectionPriority = input.readInt32(); frameRate = input.readFloat(); + frameRateCompatibility = input.readByte(); return NO_ERROR; } @@ -427,6 +431,7 @@ void layer_state_t::merge(const layer_state_t& other) { if (other.what & eFrameRateChanged) { what |= eFrameRateChanged; frameRate = other.frameRate; + frameRateCompatibility = other.frameRateCompatibility; } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " @@ -474,4 +479,21 @@ void InputWindowCommands::read(const Parcel& input) { syncInputWindows = input.readBool(); } +bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName) { + const char* functionName = inFunctionName != nullptr ? inFunctionName : "call"; + int floatClassification = std::fpclassify(frameRate); + if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) { + ALOGE("%s failed - invalid frame rate %f", functionName, frameRate); + return false; + } + + if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT && + compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) { + ALOGE("%s failed - invalid compatibility value %d", functionName, compatibility); + return false; + } + + return true; +} + }; // namespace android diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 278cc593b7..f911e70ebf 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -43,6 +43,7 @@ #include #include +#include #include namespace android { @@ -1413,7 +1414,8 @@ int Surface::dispatchGetLastQueueDuration(va_list args) { int Surface::dispatchSetFrameRate(va_list args) { float frameRate = static_cast(va_arg(args, double)); - return setFrameRate(frameRate); + int8_t compatibility = static_cast(va_arg(args, int)); + return setFrameRate(frameRate, compatibility); } int Surface::dispatchAddCancelInterceptor(va_list args) { @@ -2222,11 +2224,15 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vectoronBuffersDiscarded(discardedBufs); } -status_t Surface::setFrameRate(float frameRate) { +status_t Surface::setFrameRate(float frameRate, int8_t compatibility) { ATRACE_CALL(); - ALOGV("Surface::setTargetFrameRate"); - Mutex::Autolock lock(mMutex); - return mGraphicBufferProducer->setFrameRate(frameRate); + ALOGV("Surface::setFrameRate"); + + if (!ValidateFrameRate(frameRate, compatibility, "Surface::setFrameRate")) { + return BAD_VALUE; + } + + return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility); } }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 7017b7c8f3..7f28c6c230 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1402,14 +1402,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate( - const sp& sc, float frameRate) { + const sp& sc, float frameRate, int8_t compatibility) { layer_state_t* s = getLayerState(sc); if (!s) { mStatus = BAD_INDEX; return *this; } + if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate")) { + mStatus = BAD_VALUE; + return *this; + } s->what |= layer_state_t::eFrameRateChanged; s->frameRate = frameRate; + s->frameRateCompatibility = compatibility; return *this; } diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index e860f61c22..0659f0de06 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -500,6 +500,12 @@ public: virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) = 0; + + /* + * Sets the intended frame rate for a surface. See ANativeWindow_setFrameRate() for more info. + */ + virtual status_t setFrameRate(const sp& surface, float frameRate, + int8_t compatibility) = 0; }; // ---------------------------------------------------------------------------- @@ -557,6 +563,7 @@ public: SET_AUTO_LOW_LATENCY_MODE, GET_GAME_CONTENT_TYPE_SUPPORT, SET_GAME_CONTENT_TYPE, + SET_FRAME_RATE, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 2d53b48475..7e3d5d50d3 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -20,8 +20,7 @@ #include #include -#include - +#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include namespace android { @@ -135,7 +135,8 @@ struct layer_state_t { colorSpaceAgnostic(false), shadowRadius(0.0f), frameRateSelectionPriority(-1), - frameRate(0.0f) { + frameRate(0.0f), + frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -221,7 +222,9 @@ struct layer_state_t { // Priority of the layer assigned by Window Manager. int32_t frameRateSelectionPriority; + // Layer frame rate and compatibility. See ANativeWindow_setFrameRate(). float frameRate; + int8_t frameRateCompatibility; }; struct ComposerState { @@ -292,6 +295,12 @@ static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs) return compare_type(lhs.token, rhs.token); } +// Returns true if the frameRate and compatibility are valid values, false +// othwerise. If either of the params are invalid, an error log is printed, and +// functionName is added to the log to indicate which function call failed. +// functionName can be null. +bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* functionName); + }; // namespace android #endif // ANDROID_SF_LAYER_STATE_H diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 4a353fc659..ad7cbfe914 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -179,7 +179,7 @@ public: status_t getConsumerUsage(uint64_t* outUsage) const; // See IGraphicBufferProducer::setFrameRate - status_t setFrameRate(float frameRate); + status_t setFrameRate(float frameRate, int8_t compatibility); protected: virtual ~Surface(); diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index d0bb6a39ec..fe3dec5ee5 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -525,7 +525,8 @@ public: const Rect& source, const Rect& dst, int transform); Transaction& setShadowRadius(const sp& sc, float cornerRadius); - Transaction& setFrameRate(const sp& sc, float frameRate); + Transaction& setFrameRate(const sp& sc, float frameRate, + int8_t compatibility); status_t setDisplaySurface(const sp& token, const sp& bufferProducer); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 70fd888aaf..8c0f8f8de9 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -854,6 +854,11 @@ public: return NO_ERROR; } + status_t setFrameRate(const sp& /*surface*/, float /*frameRate*/, + int8_t /*compatibility*/) override { + return NO_ERROR; + } + protected: IBinder* onAsBinder() override { return nullptr; } diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index 98b76fd667..f09decf21a 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -158,11 +158,11 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) { return query(window, NATIVE_WINDOW_DATASPACE); } -int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) { - if (!window || !query(window, NATIVE_WINDOW_IS_VALID) || frameRate < 0) { +int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) { + if (!window || !query(window, NATIVE_WINDOW_IS_VALID)) { return -EINVAL; } - return native_window_set_frame_rate(window, frameRate); + return native_window_set_frame_rate(window, frameRate, compatibility); } void ANativeWindow_tryAllocateBuffers(ANativeWindow* window) { diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h index 4b426c518a..59aa6655b8 100644 --- a/libs/nativewindow/include/android/native_window.h +++ b/libs/nativewindow/include/android/native_window.h @@ -33,6 +33,7 @@ #ifndef ANDROID_NATIVE_WINDOW_H #define ANDROID_NATIVE_WINDOW_H +#include #include #include @@ -232,6 +233,24 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) __INTRODUCED_IN #if __ANDROID_API__ >= 30 +/* Parameter for ANativeWindow_setFrameRate */ +enum { + /** + * There are no inherent restrictions on the frame rate of this window. + */ + ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT = 0, + /** + * This window is being used to display content with an inherently fixed + * frame rate, e.g. a video that has a specific frame rate. When the system + * selects a frame rate other than what the app requested, the app will need + * to do pull down or use some other technique to adapt to the system's + * frame rate. The user experience is likely to be worse (e.g. more frame + * stuttering) than it would be if the system had chosen the app's requested + * frame rate. + */ + ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1 +}; + /** * Sets the intended frame rate for this window. * @@ -257,9 +276,15 @@ int32_t ANativeWindow_getBuffersDataSpace(ANativeWindow* window) __INTRODUCED_IN * refresh rate for this device's display - e.g., it's fine to pass 30fps to a * device that can only run the display at 60fps. * - * \return 0 for success, -EINVAL if the window or frame rate are invalid. + * \param compatibility The frame rate compatibility of this window. The + * compatibility value may influence the system's choice of display refresh + * rate. See the ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* values for more info. + * + * \return 0 for success, -EINVAL if the window, frame rate, or compatibility + * value are invalid. */ -int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate) __INTRODUCED_IN(30); +int32_t ANativeWindow_setFrameRate(ANativeWindow* window, float frameRate, int8_t compatibility) + __INTRODUCED_IN(30); /** * Provides a hint to the window that buffers should be preallocated ahead of diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index f686147a5f..0e28fb84ca 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -1015,8 +1015,10 @@ static inline int native_window_set_auto_prerotation(struct ANativeWindow* windo return window->perform(window, NATIVE_WINDOW_SET_AUTO_PREROTATION, autoPrerotation); } -static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate) { - return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate); +static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate, + int8_t compatibility) { + return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate, + (int)compatibility); } // ------------------------------------------------------------------------------------------------ diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index 154eb8eb52..e072e1145d 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -46,9 +46,9 @@ LIBNATIVEWINDOW { ANativeWindow_setBuffersTimestamp; # llndk ANativeWindow_setBuffersTransform; ANativeWindow_setDequeueTimeout; # apex # introduced=30 + ANativeWindow_setFrameRate; # introduced=30 ANativeWindow_setSharedBufferMode; # llndk ANativeWindow_setSwapInterval; # llndk - ANativeWindow_setFrameRate; # introduced=30 ANativeWindow_setUsage; # llndk ANativeWindow_tryAllocateBuffers; # introduced=30 ANativeWindow_unlockAndPost; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index e65064bebf..f5a99cadd7 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -124,18 +124,6 @@ bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const { return isDue || !isPlausible; } -bool BufferQueueLayer::setFrameRate(FrameRate frameRate) { - float oldFrameRate = 0.f; - status_t result = mConsumer->getFrameRate(&oldFrameRate); - bool frameRateChanged = result < 0 || frameRate.rate != oldFrameRate; - mConsumer->setFrameRate(frameRate.rate); - return frameRateChanged; -} - -Layer::FrameRate BufferQueueLayer::getFrameRate() const { - return FrameRate(mLatchedFrameRate, Layer::FrameRateCompatibility::Default); -} - // ----------------------------------------------------------------------- // Interface implementation for BufferLayer // ----------------------------------------------------------------------- @@ -578,7 +566,6 @@ void BufferQueueLayer::gatherBufferInfo() { mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse(); float latchedFrameRate; mConsumer->getFrameRate(&latchedFrameRate); - mLatchedFrameRate = latchedFrameRate; } sp BufferQueueLayer::createClone() { diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index 626af4b6f1..5f7587c547 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -56,9 +56,6 @@ public: bool shouldPresentNow(nsecs_t expectedPresentTime) const override; - bool setFrameRate(FrameRate frameRate) override; - FrameRate getFrameRate() const override; - // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- @@ -155,8 +152,6 @@ private: std::atomic mSidebandStreamChanged{false}; sp mContentsChangedListener; - - std::atomic mLatchedFrameRate = 0.f; }; } // namespace android diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index da26a374db..d7647d76d3 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -26,6 +26,7 @@ #include "Layer.h" #include +#include #include #include #include @@ -2446,6 +2447,18 @@ void Layer::addChildToDrawing(const sp& layer) { layer->mDrawingParent = this; } +Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t compatibility) { + switch (compatibility) { + case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT: + return FrameRateCompatibility::Default; + case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE: + return FrameRateCompatibility::ExactOrMultiple; + default: + LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility); + return FrameRateCompatibility::Default; + } +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 37ae340653..5d2144aed4 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -161,6 +161,10 @@ public: } bool operator!=(const FrameRate& other) const { return !(*this == other); } + + // Convert an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value to a + // Layer::FrameRateCompatibility. Logs fatal if the compatibility value is invalid. + static FrameRateCompatibility convertCompatibility(int8_t compatibility); }; struct State { @@ -795,7 +799,7 @@ public: */ Rect getCroppedBufferSize(const Layer::State& s) const; - virtual bool setFrameRate(FrameRate frameRate); + bool setFrameRate(FrameRate frameRate); virtual FrameRate getFrameRate() const; protected: diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index b313777253..b851fc6ebb 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -179,4 +179,3 @@ void LayerHistory::clear() { mActiveLayersEnd = 0; } } // namespace android::scheduler::impl - diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a98ff4fe7c..2701c3e6c9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include @@ -58,6 +60,7 @@ #include #include #include +#include #include #include