Merge "transactions: fix mutex deadlock on layer death" into qt-dev
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 96d7568..9c311a3 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -886,7 +886,7 @@
item.mFence = acquireFence;
item.mFenceTime = acquireFenceTime;
item.mIsDroppable = mCore->mAsyncMode ||
- (!mCore->mLegacyBufferDrop && mConsumerIsSurfaceFlinger) ||
+ (mConsumerIsSurfaceFlinger && mCore->mQueueBufferCanDrop) ||
(mCore->mLegacyBufferDrop && mCore->mQueueBufferCanDrop) ||
(mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
item.mSurfaceDamage = surfaceDamage;
@@ -1497,7 +1497,9 @@
BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
std::lock_guard<std::mutex> lock(mCore->mMutex);
- int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
+ bool dequeueBufferCannotBlock =
+ timeout >= 0 ? false : mCore->mDequeueBufferCannotBlock;
+ int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, dequeueBufferCannotBlock,
mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
if (!mCore->adjustAvailableSlotsLocked(delta)) {
BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
@@ -1506,11 +1508,9 @@
}
mDequeueTimeout = timeout;
- if (timeout >= 0) {
- mCore->mDequeueBufferCannotBlock = false;
- if (timeout != 0) {
- mCore->mQueueBufferCanDrop = false;
- }
+ mCore->mDequeueBufferCannotBlock = dequeueBufferCannotBlock;
+ if (timeout > 0) {
+ mCore->mQueueBufferCanDrop = false;
}
VALIDATE_CONSISTENCY();
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 9c0ee99..690a85f 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -233,7 +233,8 @@
// mLegacyBufferDrop indicates whether mQueueBufferCanDrop is in effect.
// If this flag is set mQueueBufferCanDrop is working as explained. If not
- // queueBuffer will not drop buffers unless consumer is SurfaceFlinger.
+ // queueBuffer will not drop buffers unless consumer is SurfaceFlinger and
+ // mQueueBufferCanDrop is set.
bool mLegacyBufferDrop;
// mDefaultBufferFormat can be set so it will override the buffer format
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 3012ed8..c463c4e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -261,22 +261,6 @@
mId(id),
mIsConnected(false),
mType(type) {
- std::vector<Hwc2::DisplayCapability> tmpCapabilities;
- auto error = static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
- if (error == Error::None) {
- for (auto capability : tmpCapabilities) {
- mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
- }
- } else if (error == Error::Unsupported) {
- if (capabilities.count(Capability::SkipClientColorTransform)) {
- mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform);
- }
- bool dozeSupport = false;
- error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
- if (error == Error::None && dozeSupport) {
- mDisplayCapabilities.emplace(DisplayCapability::Doze);
- }
- }
ALOGV("Created display %" PRIu64, id);
}
@@ -660,6 +644,29 @@
{
auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
auto intError = mComposer.setPowerMode(mId, intMode);
+
+ if (mode == PowerMode::On) {
+ std::call_once(mDisplayCapabilityQueryFlag, [this]() {
+ std::vector<Hwc2::DisplayCapability> tmpCapabilities;
+ auto error =
+ static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
+ if (error == Error::None) {
+ for (auto capability : tmpCapabilities) {
+ mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
+ }
+ } else if (error == Error::Unsupported) {
+ if (mCapabilities.count(Capability::SkipClientColorTransform)) {
+ mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform);
+ }
+ bool dozeSupport = false;
+ error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
+ if (error == Error::None && dozeSupport) {
+ mDisplayCapabilities.emplace(DisplayCapability::Doze);
+ }
+ }
+ });
+ }
+
return static_cast<Error>(intError);
}
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index e0a5ef1..b7cdf7f 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -356,6 +356,7 @@
DisplayType mType;
std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
+ std::once_flag mDisplayCapabilityQueryFlag;
std::unordered_set<DisplayCapability> mDisplayCapabilities;
};
} // namespace impl
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 7c0ecb3..4f8ed1a 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -253,13 +253,16 @@
static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
static void setupPreconditions(CompositionTest* test) {
- EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
- Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ setPowerMode(HWC_DISPLAY,
+ static_cast<Hwc2::IComposerClient::PowerMode>(
+ Derived::INIT_POWER_MODE)))
+ .WillOnce(Return(Error::NONE));
FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, HWC2::DisplayType::Physical,
true /* isPrimary */)
.setCapabilities(&test->mDefaultCapabilities)
+ .setPowerMode(Derived::INIT_POWER_MODE)
.inject(&test->mFlinger, test->mComposer);
Mock::VerifyAndClear(test->mComposer);
@@ -282,6 +285,13 @@
}
template <typename Case>
+ static void setupPreconditionCallExpectations(CompositionTest* test) {
+ EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY, _))
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
+ Return(Error::NONE)));
+ }
+
+ template <typename Case>
static void setupCommonCompositionCallExpectations(CompositionTest* test) {
EXPECT_CALL(*test->mComposer,
setColorTransform(HWC_DISPLAY, _, Hwc2::ColorTransform::IDENTITY))
@@ -393,6 +403,9 @@
static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_OFF;
template <typename Case>
+ static void setupPreconditionCallExpectations(CompositionTest*) {}
+
+ template <typename Case>
static void setupCommonCompositionCallExpectations(CompositionTest* test) {
EXPECT_CALL(*test->mRenderEngine, useNativeFenceSync()).WillRepeatedly(Return(true));
@@ -1022,6 +1035,7 @@
using CompositionResult = CompositionResultCase;
static void setupCommon(CompositionTest* test) {
+ Display::template setupPreconditionCallExpectations<ThisCase>(test);
Display::setupPreconditions(test);
auto layer = Layer::createLayer(test);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 97f9e6a..5f58e7d 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -410,6 +410,7 @@
// The HWC active configuration id
static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
+ static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
static void injectPendingHotplugEvent(DisplayTransactionTest* test,
HWC2::Connection connection) {
@@ -427,6 +428,7 @@
.setWidth(DisplayVariant::WIDTH)
.setHeight(DisplayVariant::HEIGHT)
.setActiveConfig(HWC_ACTIVE_CONFIG_ID)
+ .setPowerMode(INIT_POWER_MODE)
.inject(&test->mFlinger, test->mComposer);
}
@@ -435,6 +437,10 @@
EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
Return(Error::NONE)));
+ EXPECT_CALL(*test->mComposer,
+ setPowerMode(HWC_DISPLAY_ID,
+ static_cast<Hwc2::IComposerClient::PowerMode>(INIT_POWER_MODE)))
+ .WillOnce(Return(Error::NONE));
injectHwcDisplayWithNoDefaultCapabilities(test);
}
@@ -467,9 +473,6 @@
getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
IComposerClient::Attribute::DPI_Y, _))
.WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
- EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
- Return(Error::NONE)));
if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
@@ -1891,10 +1894,6 @@
Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
- EXPECT_CALL(*mComposer, getDisplayCapabilities(Case::Display::HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
- Return(Error::NONE)));
-
EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index df14e7e..64d34ee 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -386,6 +386,7 @@
static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
static constexpr int32_t DEFAULT_DPI = 320;
static constexpr int32_t DEFAULT_ACTIVE_CONFIG = 0;
+ static constexpr int32_t DEFAULT_POWER_MODE = 2;
FakeHwcDisplayInjector(DisplayId displayId, HWC2::DisplayType hwcDisplayType,
bool isPrimary)
@@ -431,6 +432,11 @@
return *this;
}
+ auto& setPowerMode(int mode) {
+ mPowerMode = mode;
+ return *this;
+ }
+
void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
static const std::unordered_set<HWC2::Capability> defaultCapabilities;
if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
@@ -450,6 +456,7 @@
config.setDpiY(mDpiY);
display->mutableConfigs().emplace(mActiveConfig, config.build());
display->mutableIsConnected() = true;
+ display->setPowerMode(static_cast<HWC2::PowerMode>(mPowerMode));
flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = display.get();
@@ -474,6 +481,7 @@
int32_t mDpiX = DEFAULT_DPI;
int32_t mDpiY = DEFAULT_DPI;
int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
+ int32_t mPowerMode = DEFAULT_POWER_MODE;
const std::unordered_set<HWC2::Capability>* mCapabilities = nullptr;
};