Merge "SF: Flatten display containers" into tm-dev
diff --git a/cmds/installd/TEST_MAPPING b/cmds/installd/TEST_MAPPING
index 8ccab4c..fc4cfc9 100644
--- a/cmds/installd/TEST_MAPPING
+++ b/cmds/installd/TEST_MAPPING
@@ -32,7 +32,12 @@
"name": "CtsCompilationTestCases"
},
{
- "name": "SdkSandboxStorageHostTest"
+ "name": "SdkSandboxStorageHostTest",
+ "options": [
+ {
+ "exclude-annotation": "android.platform.test.annotations.LargeTest"
+ }
+ ]
}
]
}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 5003151..bdd5172 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -227,6 +227,12 @@
}
prebuilt_etc {
+ name: "android.software.opengles.deqp.level-2022-03-01.prebuilt.xml",
+ src: "android.software.opengles.deqp.level-2022-03-01.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "android.software.sip.voip.prebuilt.xml",
src: "android.software.sip.voip.xml",
defaults: ["frameworks_native_data_etc_defaults"],
@@ -245,6 +251,12 @@
}
prebuilt_etc {
+ name: "android.software.vulkan.deqp.level-2022-03-01.prebuilt.xml",
+ src: "android.software.vulkan.deqp.level-2022-03-01.xml",
+ defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
name: "aosp_excluded_hardware.prebuilt.xml",
src: "aosp_excluded_hardware.xml",
defaults: ["frameworks_native_data_etc_defaults"],
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index b3bc7f4..c8e78fc 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -324,4 +324,42 @@
} // namespace ndk
+// Once minSdkVersion is 30, we are guaranteed to be building with the
+// Android 11 AIDL compiler which supports the SharedRefBase::make API.
+#if !defined(__ANDROID_API__) || __ANDROID_API__ >= 30 || defined(__ANDROID_APEX__)
+namespace ndk::internal {
+template <typename T, typename = void>
+struct is_complete_type : std::false_type {};
+
+template <typename T>
+struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
+} // namespace ndk::internal
+
+namespace std {
+
+// Define `SharedRefBase` specific versions of `std::make_shared` and
+// `std::make_unique` to block people from using them. Using them to allocate
+// `ndk::SharedRefBase` objects results in double ownership. Use
+// `ndk::SharedRefBase::make<T>(...)` instead.
+//
+// Note: We exclude incomplete types because `std::is_base_of` is undefined in
+// that case.
+
+template <typename T, typename... Args,
+ std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
+ std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
+shared_ptr<T> make_shared(Args...) { // SEE COMMENT ABOVE.
+ static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
+}
+
+template <typename T, typename... Args,
+ std::enable_if_t<ndk::internal::is_complete_type<T>::value, bool> = true,
+ std::enable_if_t<std::is_base_of<ndk::SharedRefBase, T>::value, bool> = true>
+unique_ptr<T> make_unique(Args...) { // SEE COMMENT ABOVE.
+ static_assert(!std::is_base_of<ndk::SharedRefBase, T>::value);
+}
+
+} // namespace std
+#endif
+
/** @} */
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 357b454..1b136dc 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -231,8 +231,7 @@
}
TEST(NdkBinder, DetectNoSharedRefBaseCreated) {
- EXPECT_DEATH(std::make_shared<MyBinderNdkUnitTest>(),
- "SharedRefBase: no ref created during lifetime");
+ EXPECT_DEATH(MyBinderNdkUnitTest(), "SharedRefBase: no ref created during lifetime");
}
TEST(NdkBinder, GetServiceThatDoesntExist) {
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 57d496d..e5d32da 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -29,7 +29,6 @@
"libcutils",
"libhidlbase",
"liblog",
- "libutils",
],
target: {
@@ -37,12 +36,14 @@
shared_libs: [
"libbinder_ndk",
"libbinder",
+ "libutils",
],
},
host: {
static_libs: [
"libbinder_ndk",
"libbinder",
+ "libutils",
],
},
darwin: {
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index dc5fcec..a9a4c71 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -27,6 +27,9 @@
namespace android {
+// The default velocity control parameters that has no effect.
+static const VelocityControlParameters FLAT_VELOCITY_CONTROL_PARAMS{};
+
// --- CursorMotionAccumulator ---
CursorMotionAccumulator::CursorMotionAccumulator() {
@@ -154,8 +157,9 @@
mHWheelScale = 1.0f;
}
- if ((!changes && config->pointerCaptureRequest.enable) ||
- (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
+ const bool configurePointerCapture = (!changes && config->pointerCaptureRequest.enable) ||
+ (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ if (configurePointerCapture) {
if (config->pointerCaptureRequest.enable) {
if (mParameters.mode == Parameters::MODE_POINTER) {
mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
@@ -180,10 +184,18 @@
}
}
- if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
- mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED) ||
+ configurePointerCapture) {
+ if (config->pointerCaptureRequest.enable) {
+ // Disable any acceleration or scaling when Pointer Capture is enabled.
+ mPointerVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
+ } else {
+ mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
+ mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ }
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 8ba501c..aa188f2 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -375,6 +375,11 @@
float getPointerGestureMovementSpeedRatio() { return mConfig.pointerGestureMovementSpeedRatio; }
+ void setVelocityControlParams(const VelocityControlParameters& params) {
+ mConfig.pointerVelocityControlParameters = params;
+ mConfig.wheelVelocityControlParameters = params;
+ }
+
private:
uint32_t mNextPointerCaptureSequenceNumber = 0;
@@ -2949,7 +2954,10 @@
}
void configureDevice(uint32_t changes) {
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ if (!changes ||
+ (changes &
+ (InputReaderConfiguration::CHANGE_DISPLAY_INFO |
+ InputReaderConfiguration::CHANGE_POINTER_CAPTURE))) {
mReader->requestRefreshConfiguration(changes);
mReader->loopOnce();
}
@@ -4842,6 +4850,54 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(*mFakePointerController, 110.0f, 220.0f));
}
+/**
+ * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
+ * pointer acceleration or speed processing should not be applied.
+ */
+TEST_F(CursorInputMapperTest, PointerCaptureDisablesVelocityProcessing) {
+ addConfigurationProperty("cursor.mode", "pointer");
+ const VelocityControlParameters testParams(5.f /*scale*/, 0.f /*low threshold*/,
+ 100.f /*high threshold*/, 10.f /*acceleration*/);
+ mFakePolicy->setVelocityControlParams(testParams);
+ CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
+
+ NotifyDeviceResetArgs resetArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
+
+ NotifyMotionArgs args;
+
+ // Move and verify scale is applied.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+ const float relX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
+ const float relY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
+ ASSERT_GT(relX, 10);
+ ASSERT_GT(relY, 20);
+
+ // Enable Pointer Capture
+ mFakePolicy->setPointerCapture(true);
+ configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ NotifyPointerCaptureChangedArgs captureArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
+ ASSERT_TRUE(captureArgs.request.enable);
+
+ // Move and verify scale is not applied.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+ ASSERT_EQ(10, args.pointerCoords[0].getX());
+ ASSERT_EQ(20, args.pointerCoords[0].getY());
+}
+
TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
diff --git a/services/sensorservice/HidlSensorHalWrapper.cpp b/services/sensorservice/HidlSensorHalWrapper.cpp
index 4c64e59..c55c9b4 100644
--- a/services/sensorservice/HidlSensorHalWrapper.cpp
+++ b/services/sensorservice/HidlSensorHalWrapper.cpp
@@ -281,7 +281,7 @@
}
status_t HidlSensorHalWrapper::registerDirectChannel(const sensors_direct_mem_t* memory,
- int32_t* /*channelHandle*/) {
+ int32_t* outChannelHandle) {
if (mSensors == nullptr) return NO_INIT;
SharedMemType type;
@@ -309,14 +309,16 @@
.memoryHandle = memory->handle,
};
- status_t ret;
- checkReturn(mSensors->registerDirectChannel(mem, [&ret](auto result, auto channelHandle) {
- if (result == Result::OK) {
- ret = channelHandle;
- } else {
- ret = statusFromResult(result);
- }
- }));
+ status_t ret = OK;
+ checkReturn(mSensors->registerDirectChannel(mem,
+ [&ret, &outChannelHandle](auto result,
+ auto channelHandle) {
+ if (result == Result::OK) {
+ *outChannelHandle = channelHandle;
+ } else {
+ ret = statusFromResult(result);
+ }
+ }));
return ret;
}
diff --git a/services/sensorservice/HidlSensorHalWrapper.h b/services/sensorservice/HidlSensorHalWrapper.h
index 71c3512..d6ed178 100644
--- a/services/sensorservice/HidlSensorHalWrapper.h
+++ b/services/sensorservice/HidlSensorHalWrapper.h
@@ -112,7 +112,7 @@
virtual status_t injectSensorData(const sensors_event_t* event) override;
virtual status_t registerDirectChannel(const sensors_direct_mem_t* memory,
- int32_t* channelHandle) override;
+ int32_t* outChannelHandle) override;
virtual status_t unregisterDirectChannel(int32_t channelHandle) override;
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index a0e30ac..53a3025 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -766,7 +766,13 @@
if (mHalWrapper == nullptr) return NO_INIT;
Mutex::Autolock _l(mLock);
- return mHalWrapper->registerDirectChannel(memory, nullptr);
+ int32_t channelHandle;
+ status_t status = mHalWrapper->registerDirectChannel(memory, &channelHandle);
+ if (status != OK) {
+ channelHandle = -1;
+ }
+
+ return channelHandle;
}
void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 05f488b..cbafdd3 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -463,29 +463,41 @@
ALOGV("Failed to send actual work duration, skipping");
return;
}
-
- WorkDuration duration;
- duration.durationNanos = actualDurationNanos;
- mActualDuration = actualDurationNanos;
+ nsecs_t reportedDuration = actualDurationNanos;
// normalize the sent values to a pre-set target
if (sNormalizeTarget) {
- duration.durationNanos += mLastTargetDurationSent - mTargetDuration;
+ reportedDuration += mLastTargetDurationSent - mTargetDuration;
+ } else {
+ // when target duration change is within deviation and not updated, adjust the actual
+ // duration proportionally based on the difference, e.g. if new target is 5ms longer than
+ // last reported but actual duration is the same as last target, we want to report a smaller
+ // actual work duration now to indicate that we are overshooting
+ if (mLastTargetDurationSent != kDefaultTarget.count() && mTargetDuration != 0) {
+ reportedDuration =
+ static_cast<int64_t>(static_cast<long double>(mLastTargetDurationSent) /
+ mTargetDuration * actualDurationNanos);
+ mActualDuration = reportedDuration;
+ }
}
+ mActualDuration = reportedDuration;
+ WorkDuration duration;
+ duration.durationNanos = reportedDuration;
duration.timeStampNanos = timeStampNanos;
mPowerHintQueue.push_back(duration);
- nsecs_t targetNsec = mTargetDuration;
- nsecs_t durationNsec = actualDurationNanos;
-
if (sTraceHintSessionData) {
- ATRACE_INT64("Measured duration", durationNsec);
- ATRACE_INT64("Target error term", targetNsec - durationNsec);
+ ATRACE_INT64("Measured duration", actualDurationNanos);
+ ATRACE_INT64("Target error term", mTargetDuration - actualDurationNanos);
+
+ ATRACE_INT64("Reported duration", reportedDuration);
+ ATRACE_INT64("Reported target", mLastTargetDurationSent);
+ ATRACE_INT64("Reported target error term", mLastTargetDurationSent - reportedDuration);
}
- ALOGV("Sending actual work duration of: %" PRId64 " on target: %" PRId64
+ ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64
" with error: %" PRId64,
- durationNsec, targetNsec, targetNsec - durationNsec);
+ reportedDuration, mLastTargetDurationSent, mLastTargetDurationSent - reportedDuration);
// This rate limiter queues similar duration reports to the powerhal into
// batches to avoid excessive binder calls. The criteria to send a given batch
@@ -501,7 +513,7 @@
}
mPowerHintQueue.clear();
// we save the non-normalized value here to detect % changes
- mLastActualDurationSent = actualDurationNanos;
+ mLastActualDurationSent = reportedDuration;
}
}
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 3f47ffd..61bb32b 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -173,8 +173,8 @@
// Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%)
static constexpr double kAllowedActualDeviationPercent = 0.1;
- // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%)
- static constexpr double kAllowedTargetDeviationPercent = 0.05;
+ // Max percent the target duration can vary without causing a report (eg: 0.1 = 10%)
+ static constexpr double kAllowedTargetDeviationPercent = 0.1;
// Target used for init and normalization, the actual value does not really matter
static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms;
// Amount of time after the last message was sent before the session goes stale
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7f923d5..3bfc2cc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3603,6 +3603,23 @@
if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {
ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
ISurfaceComposer::MAX_LAYERS);
+ static_cast<void>(mScheduler->schedule([=] {
+ ALOGE("Dumping random sampling of on-screen layers: ");
+ mDrawingState.traverse([&](Layer *layer) {
+ // Aim to dump about 200 layers to avoid totally trashing
+ // logcat. On the other hand, if there really are 4096 layers
+ // something has gone totally wrong its probably the most
+ // useful information in logcat.
+ if (rand() % 20 == 13) {
+ ALOGE("Layer: %s", layer->getName().c_str());
+ }
+ });
+ for (Layer* offscreenLayer : mOffscreenLayers) {
+ if (rand() % 20 == 13) {
+ ALOGE("Offscreen-layer: %s", offscreenLayer->getName().c_str());
+ }
+ }
+ }));
return NO_MEMORY;
}
diff --git a/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp b/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp
index e25a0ae..9ab35d7 100644
--- a/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp
+++ b/services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp
@@ -17,6 +17,7 @@
#undef LOG_TAG
#define LOG_TAG "AidlPowerHalWrapperTest"
+#include <android-base/stringprintf.h>
#include <android/hardware/power/IPower.h>
#include <android/hardware/power/IPowerHintSession.h>
#include <gmock/gmock.h>
@@ -82,6 +83,15 @@
return duration;
}
+std::string printWorkDurations(const ::std::vector<WorkDuration>& durations) {
+ std::ostringstream os;
+ for (auto duration : durations) {
+ os << duration.toString();
+ os << "\n";
+ }
+ return os.str();
+}
+
namespace {
TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) {
ASSERT_TRUE(mWrapper->supportsPowerHintSession());
@@ -143,8 +153,8 @@
{-1ms, false},
{200ms, true},
{2ms, true},
- {96ms, false},
- {104ms, false}};
+ {91ms, false},
+ {109ms, false}};
for (const auto& test : testCases) {
// reset to 100ms baseline
@@ -212,6 +222,40 @@
}
}
+TEST_F(AidlPowerHalWrapperTest, sendAdjustedActualWorkDuration) {
+ ASSERT_TRUE(mWrapper->supportsPowerHintSession());
+
+ std::vector<int32_t> threadIds = {1, 2};
+ mWrapper->setPowerHintSessionThreadIds(threadIds);
+ EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _))
+ .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok())));
+ ASSERT_TRUE(mWrapper->startPowerHintSession());
+ verifyAndClearExpectations();
+
+ std::chrono::nanoseconds lastTarget = 100ms;
+ EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(lastTarget.count())).Times(1);
+ mWrapper->setTargetWorkDuration(lastTarget.count());
+ std::chrono::nanoseconds newTarget = 105ms;
+ mWrapper->setTargetWorkDuration(newTarget.count());
+ EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(newTarget.count())).Times(0);
+ std::chrono::nanoseconds actual = 21ms;
+ // 100 / 105 * 21ms = 20ms
+ std::chrono::nanoseconds expectedActualSent = 20ms;
+ std::vector<WorkDuration> expectedDurations = {toWorkDuration(expectedActualSent, 1)};
+
+ EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_))
+ .WillOnce(DoAll(
+ [expectedDurations](const ::std::vector<WorkDuration>& durationsSent) {
+ EXPECT_EQ(expectedDurations, durationsSent)
+ << base::StringPrintf("actual sent: %s vs expected: %s",
+ printWorkDurations(durationsSent).c_str(),
+ printWorkDurations(expectedDurations)
+ .c_str());
+ },
+ Return(Status::ok())));
+ mWrapper->sendActualWorkDuration(actual.count(), 1);
+}
+
TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_exceedsStaleTime) {
ASSERT_TRUE(mWrapper->supportsPowerHintSession());
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 32d57b5..5872a47 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -61,7 +61,6 @@
protected:
void setupScheduler(std::shared_ptr<scheduler::RefreshRateConfigs>);
- void testChangeRefreshRate(bool isDisplayActive, bool isRefreshRequired);
sp<DisplayDevice> mDisplay;
mock::EventThread* mAppEventThread;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 45bc4c9..c4b1487 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -299,6 +299,7 @@
}
void ReleaseSwapchainImage(VkDevice device,
+ bool shared_present,
ANativeWindow* window,
int release_fence,
Swapchain::Image& image,
@@ -330,7 +331,8 @@
}
image.dequeue_fence = -1;
- if (window) {
+ // It's invalid to call cancelBuffer on a shared buffer
+ if (window && !shared_present) {
window->cancelBuffer(window, image.buffer.get(), release_fence);
} else {
if (release_fence >= 0) {
@@ -364,9 +366,10 @@
if (swapchain->surface.swapchain_handle != HandleFromSwapchain(swapchain))
return;
for (uint32_t i = 0; i < swapchain->num_images; i++) {
- if (!swapchain->images[i].dequeued)
- ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i],
- true);
+ if (!swapchain->images[i].dequeued) {
+ ReleaseSwapchainImage(device, swapchain->shared, nullptr, -1,
+ swapchain->images[i], true);
+ }
}
swapchain->surface.swapchain_handle = VK_NULL_HANDLE;
swapchain->timing.clear();
@@ -1084,7 +1087,8 @@
}
for (uint32_t i = 0; i < swapchain->num_images; i++) {
- ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false);
+ ReleaseSwapchainImage(device, swapchain->shared, window, -1,
+ swapchain->images[i], false);
}
if (active) {
@@ -1854,7 +1858,8 @@
WorstPresentResult(swapchain_result, VK_SUBOPTIMAL_KHR);
}
} else {
- ReleaseSwapchainImage(device, nullptr, fence, img, true);
+ ReleaseSwapchainImage(device, swapchain.shared, nullptr, fence,
+ img, true);
swapchain_result = VK_ERROR_OUT_OF_DATE_KHR;
}