Merge "Use ALWAYS_FATAL if touchState is out of sync" into main
diff --git a/libs/binder/ndk/include_platform/android/binder_stability.h b/libs/binder/ndk/include_platform/android/binder_stability.h
index 089c775..8050205 100644
--- a/libs/binder/ndk/include_platform/android/binder_stability.h
+++ b/libs/binder/ndk/include_platform/android/binder_stability.h
@@ -27,6 +27,10 @@
#if defined(__ANDROID_VENDOR__)
+#if defined(__ANDROID_PRODUCT__)
+#error "build bug: product is not part of the vendor half of the Treble system/vendor split"
+#endif
+
/**
* Private addition to binder_flag_t.
*/
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index c770db9..310f781 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -222,8 +222,6 @@
ComposerServiceAIDL::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
mCurrentMaxAcquiredBufferCount = mMaxAcquiredBuffers;
- mNumAcquired = 0;
- mNumFrameAvailable = 0;
TransactionCompletedListener::getInstance()->addQueueStallListener(
[&](const std::string& reason) {
@@ -439,7 +437,7 @@
void BLASTBufferQueue::flushShadowQueue() {
BQA_LOGV("flushShadowQueue");
- int numFramesToFlush = mNumFrameAvailable;
+ int32_t numFramesToFlush = mNumFrameAvailable;
while (numFramesToFlush > 0) {
acquireNextBufferLocked(std::nullopt);
numFramesToFlush--;
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 3ad0e52..67de742 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -385,6 +385,26 @@
}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t ConsumerBase::addReleaseFence(const sp<GraphicBuffer> buffer, const sp<Fence>& fence) {
+ CB_LOGV("addReleaseFence");
+ Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ CB_LOGE("addReleaseFence: ConsumerBase is abandoned!");
+ return NO_INIT;
+ }
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+
+ int slotIndex = getSlotForBufferLocked(buffer);
+ if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
+ return BAD_VALUE;
+ }
+
+ return addReleaseFenceLocked(slotIndex, buffer, fence);
+}
+
status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
Mutex::Autolock _l(mMutex);
if (mAbandoned) {
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index acb0006..2e347c9 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -98,6 +98,8 @@
status_t detachBuffer(const sp<GraphicBuffer>& buffer);
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ status_t addReleaseFence(const sp<GraphicBuffer> buffer, const sp<Fence>& fence);
+
// See IGraphicBufferConsumer::setDefaultBufferSize
status_t setDefaultBufferSize(uint32_t width, uint32_t height);
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index d04b861..c2680a4 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -502,12 +502,18 @@
Rect layerStackSpaceRect = Rect::EMPTY_RECT;
Rect orientedDisplaySpaceRect = Rect::EMPTY_RECT;
- // Exclusive to virtual displays: The sink surface into which the virtual display is rendered,
- // and an optional resolution that overrides its default dimensions.
- sp<IGraphicBufferProducer> surface;
+ // For physical displays, this is the resolution, which must match the active display mode. To
+ // change the resolution, the client must first call SurfaceControl.setDesiredDisplayModeSpecs
+ // with the new DesiredDisplayModeSpecs#defaultMode, then commit the matching width and height.
+ //
+ // For virtual displays, this is an optional resolution that overrides its default dimensions.
+ //
uint32_t width = 0;
uint32_t height = 0;
+ // For virtual displays, this is the sink surface into which the virtual display is rendered.
+ sp<IGraphicBufferProducer> surface;
+
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 57041ee..3b0f036 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -337,17 +337,17 @@
LayerSettings layer{
.geometry =
Geometry{
+ .boundaries = rect,
// The position transform doesn't matter when the reduced shader mode
// in in effect. A matrix transform stage is always included.
.positionTransform = mat4(),
- .boundaries = rect,
- .roundedCornersCrop = rect,
.roundedCornersRadius = {0.f, 0.f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
- .isOpaque = true}},
+ .isOpaque = true,
+ .maxLuminanceNits = 1000.f}},
.alpha = 1.f,
.sourceDataspace = kDestDataSpace,
};
@@ -370,16 +370,16 @@
LayerSettings layer{
.geometry =
Geometry{
- .positionTransform = mat4(),
.boundaries = rect,
+ .positionTransform = mat4(),
.roundedCornersCrop = rect,
},
.source = PixelSource{.buffer =
Buffer{
.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
.isOpaque = false,
+ .maxLuminanceNits = 1000.f,
}},
.sourceDataspace = kDestDataSpace,
};
@@ -421,17 +421,17 @@
LayerSettings layer{
.geometry =
Geometry{
- .positionTransform = mat4(),
.boundaries = boundary,
- .roundedCornersCrop = rect,
+ .positionTransform = mat4(),
.roundedCornersRadius = {27.f, 27.f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer =
Buffer{
.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
.isOpaque = false,
+ .maxLuminanceNits = 1000.f,
}},
.alpha = 1.f,
.sourceDataspace = kDestDataSpace,
@@ -489,17 +489,17 @@
LayerSettings layer{
.geometry =
Geometry{
+ .boundaries = rect,
// The position transform doesn't matter when the reduced shader mode
// in in effect. A matrix transform stage is always included.
.positionTransform = mat4(),
- .boundaries = rect,
- .roundedCornersCrop = rect,
.roundedCornersRadius = {0.f, 0.f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
- .isOpaque = true}},
+ .isOpaque = true,
+ .maxLuminanceNits = 1000.f}},
.alpha = 1.f,
.sourceDataspace = kBT2020DataSpace,
};
@@ -527,17 +527,17 @@
LayerSettings layer{
.geometry =
Geometry{
- .positionTransform = kScaleAsymmetric,
.boundaries = boundary,
- .roundedCornersCrop = rect,
+ .positionTransform = kScaleAsymmetric,
.roundedCornersRadius = {64.1f, 64.1f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer =
Buffer{
.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
.isOpaque = true,
+ .maxLuminanceNits = 1000.f,
}},
.alpha = 0.5f,
.sourceDataspace = kBT2020DataSpace,
@@ -556,17 +556,17 @@
LayerSettings layer{
.geometry =
Geometry{
+ .boundaries = rect,
// The position transform doesn't matter when the reduced shader mode
// in in effect. A matrix transform stage is always included.
.positionTransform = mat4(),
- .boundaries = rect,
- .roundedCornersCrop = rect,
.roundedCornersRadius = {50.f, 50.f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
- .isOpaque = true}},
+ .isOpaque = true,
+ .maxLuminanceNits = 1000.f}},
.alpha = 0.5f,
.sourceDataspace = kExtendedHdrDataSpce,
};
@@ -594,17 +594,17 @@
LayerSettings layer{
.geometry =
Geometry{
+ .boundaries = rect,
// The position transform doesn't matter when the reduced shader mode
// in in effect. A matrix transform stage is always included.
.positionTransform = mat4(),
- .boundaries = rect,
- .roundedCornersCrop = rect,
.roundedCornersRadius = {50.f, 50.f},
+ .roundedCornersCrop = rect,
},
.source = PixelSource{.buffer = Buffer{.buffer = srcTexture,
- .maxLuminanceNits = 1000.f,
.usePremultipliedAlpha = true,
- .isOpaque = false}},
+ .isOpaque = false,
+ .maxLuminanceNits = 1000.f}},
.alpha = 0.5f,
.sourceDataspace = kOtherDataSpace,
};
diff --git a/libs/renderengine/skia/debug/CaptureTimer.cpp b/libs/renderengine/skia/debug/CaptureTimer.cpp
index 11bcdb8..1c1ee0a 100644
--- a/libs/renderengine/skia/debug/CaptureTimer.cpp
+++ b/libs/renderengine/skia/debug/CaptureTimer.cpp
@@ -30,7 +30,7 @@
void CaptureTimer::setTimeout(TimeoutCallback function, std::chrono::milliseconds delay) {
this->clear = false;
- CommonPool::post([=]() {
+ CommonPool::post([=,this]() {
if (this->clear) return;
std::this_thread::sleep_for(delay);
if (this->clear) return;
diff --git a/services/gpuservice/feature_override/FeatureOverrideParser.cpp b/services/gpuservice/feature_override/FeatureOverrideParser.cpp
index 1ad637c..a16bfa8 100644
--- a/services/gpuservice/feature_override/FeatureOverrideParser.cpp
+++ b/services/gpuservice/feature_override/FeatureOverrideParser.cpp
@@ -90,7 +90,6 @@
}
void FeatureOverrideParser::forceFileRead() {
- resetFeatureOverrides(mFeatureOverrides);
mLastProtobufReadTime = 0;
}
@@ -98,6 +97,9 @@
const feature_override::FeatureOverrideProtos overridesProtos = readFeatureConfigProtos(
getFeatureOverrideFilePath());
+ // Clear out the stale values before adding the newly parsed data.
+ resetFeatureOverrides(mFeatureOverrides);
+
// Global feature overrides.
for (const auto &featureConfigProto: overridesProtos.global_features()) {
FeatureConfig featureConfig;
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 7ab000b..845cab0 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -196,9 +196,8 @@
if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (now >= mNextTimeout) {
- if (debugRawEvents()) {
- ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
- }
+ ALOGD_IF(debugRawEvents(), "Timeout expired, latency=%0.3fms",
+ (now - mNextTimeout) * 0.000001f);
mNextTimeout = LLONG_MAX;
mPendingArgs += timeoutExpiredLocked(now);
}
@@ -263,9 +262,7 @@
}
batchSize += 1;
}
- if (debugRawEvents()) {
- ALOGD("BatchSize: %zu Count: %zu", batchSize, count);
- }
+ ALOGD_IF(debugRawEvents(), "BatchSize: %zu Count: %zu", batchSize, count);
out += processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp
index 7434ae4..df22890 100644
--- a/services/inputflinger/reader/controller/PeripheralController.cpp
+++ b/services/inputflinger/reader/controller/PeripheralController.cpp
@@ -78,10 +78,8 @@
if (rawMaxBrightness != MAX_BRIGHTNESS) {
brightness = brightness * ratio;
}
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("getRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", rawLightId,
- brightness, ratio);
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "getRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f",
+ rawLightId, brightness, ratio);
return brightness;
}
@@ -97,10 +95,8 @@
if (rawMaxBrightness != MAX_BRIGHTNESS) {
brightness = ceil(brightness / ratio);
}
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("setRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f", rawLightId,
- brightness, ratio);
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "setRawLightBrightness rawLightId %d brightness 0x%x ratio %.2f",
+ rawLightId, brightness, ratio);
context.setLightBrightness(rawLightId, brightness);
}
@@ -453,10 +449,9 @@
if (rawInfo->flags.test(InputLightClass::GLOBAL)) {
rawGlobalId = rawId;
}
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("Light rawId %d name %s max %d flags %s \n", rawInfo->id, rawInfo->name.c_str(),
- rawInfo->maxBrightness.value_or(MAX_BRIGHTNESS), rawInfo->flags.string().c_str());
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "Light rawId %d name %s max %d flags %s\n", rawInfo->id,
+ rawInfo->name.c_str(), rawInfo->maxBrightness.value_or(MAX_BRIGHTNESS),
+ rawInfo->flags.string().c_str());
}
// Construct a player ID light
@@ -473,10 +468,8 @@
}
// Construct a RGB light for composed RGB light
if (hasRedLed && hasGreenLed && hasBlueLed) {
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("Rgb light ids [%d, %d, %d] \n", rawRgbIds.at(LightColor::RED),
- rawRgbIds.at(LightColor::GREEN), rawRgbIds.at(LightColor::BLUE));
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "Rgb light ids [%d, %d, %d]\n", rawRgbIds.at(LightColor::RED),
+ rawRgbIds.at(LightColor::GREEN), rawRgbIds.at(LightColor::BLUE));
bool isKeyboardBacklight = keyboardBacklightIds.find(rawRgbIds.at(LightColor::RED)) !=
keyboardBacklightIds.end() &&
keyboardBacklightIds.find(rawRgbIds.at(LightColor::GREEN)) !=
@@ -518,9 +511,8 @@
// If the node is multi-color led, construct a MULTI_COLOR light
if (rawInfo.flags.test(InputLightClass::MULTI_INDEX) &&
rawInfo.flags.test(InputLightClass::MULTI_INTENSITY)) {
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("Multicolor light Id %d name %s \n", rawInfo.id, rawInfo.name.c_str());
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "Multicolor light Id %d name %s\n", rawInfo.id,
+ rawInfo.name.c_str());
std::unique_ptr<Light> light =
std::make_unique<MultiColorLight>(getDeviceContext(), rawInfo.name, ++mNextId,
type, rawInfo.id);
@@ -528,9 +520,8 @@
continue;
}
// Construct a Mono LED light
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("Mono light Id %d name %s \n", rawInfo.id, rawInfo.name.c_str());
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "Mono light Id %d name %s\n", rawInfo.id,
+ rawInfo.name.c_str());
std::unique_ptr<Light> light = std::make_unique<MonoLight>(getDeviceContext(), rawInfo.name,
++mNextId, type, rawInfo.id);
@@ -552,10 +543,8 @@
return false;
}
auto& light = it->second;
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("setLightColor lightId %d type %s color 0x%x", lightId,
- ftl::enum_string(light->type).c_str(), color);
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "setLightColor lightId %d type %s color 0x%x", lightId,
+ ftl::enum_string(light->type).c_str(), color);
return light->setLightColor(color);
}
@@ -566,10 +555,8 @@
}
auto& light = it->second;
std::optional<int32_t> color = light->getLightColor();
- if (DEBUG_LIGHT_DETAILS) {
- ALOGD("getLightColor lightId %d type %s color 0x%x", lightId,
- ftl::enum_string(light->type).c_str(), color.value_or(0));
- }
+ ALOGD_IF(DEBUG_LIGHT_DETAILS, "getLightColor lightId %d type %s color 0x%x", lightId,
+ ftl::enum_string(light->type).c_str(), color.value_or(0));
return color;
}
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index fd8224a..4d08f19 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -79,19 +79,17 @@
if (id) {
outState->rawPointerData.canceledIdBits.markBit(id.value());
}
- if (DEBUG_POINTERS) {
- ALOGI("Stop processing slot %zu for it received a palm event from device %s",
- inIndex, getDeviceName().c_str());
- }
+ ALOGI_IF(DEBUG_POINTERS,
+ "Stop processing slot %zu for it received a palm event from device %s",
+ inIndex, getDeviceName().c_str());
continue;
}
if (outCount >= MAX_POINTERS) {
- if (DEBUG_POINTERS) {
- ALOGD("MultiTouch device %s emitted more than maximum of %zu pointers; "
- "ignoring the rest.",
- getDeviceName().c_str(), MAX_POINTERS);
- }
+ ALOGD_IF(DEBUG_POINTERS,
+ "MultiTouch device %s emitted more than maximum of %zu pointers; ignoring the "
+ "rest.",
+ getDeviceName().c_str(), MAX_POINTERS);
break; // too many fingers!
}
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 1f6600d..0d1d884 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -235,9 +235,8 @@
// else calculate difference between previous and current MSC_TIMESTAMP
if (mPrevMscTime == 0) {
mHardwareTimestamp = evTime;
- if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Initialize hardware timestamp = %" PRId64, mHardwareTimestamp);
- }
+ ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Initialize hardware timestamp = %" PRId64,
+ mHardwareTimestamp);
} else {
// Calculate the difference between current msc_timestamp and
// previous msc_timestamp, including when msc_timestamp wraps around.
@@ -330,11 +329,10 @@
bool SensorInputMapper::enableSensor(InputDeviceSensorType sensorType,
std::chrono::microseconds samplingPeriod,
std::chrono::microseconds maxBatchReportLatency) {
- if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld",
- ftl::enum_string(sensorType).c_str(), samplingPeriod.count(),
- maxBatchReportLatency.count());
- }
+ ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS,
+ "Enable Sensor %s samplingPeriod %lld maxBatchReportLatency %lld",
+ ftl::enum_string(sensorType).c_str(), samplingPeriod.count(),
+ maxBatchReportLatency.count());
if (!setSensorEnabled(sensorType, /*enabled=*/true)) {
return false;
@@ -355,9 +353,7 @@
}
void SensorInputMapper::disableSensor(InputDeviceSensorType sensorType) {
- if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Disable Sensor %s", ftl::enum_string(sensorType).c_str());
- }
+ ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Disable Sensor %s", ftl::enum_string(sensorType).c_str());
if (!setSensorEnabled(sensorType, /*enabled=*/false)) {
return;
@@ -389,15 +385,12 @@
}
nsecs_t timestamp = mHasHardwareTimestamp ? mHardwareTimestamp : when;
- if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Sensor %s timestamp %" PRIu64 " values [%f %f %f]",
- ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]);
- }
+ ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Sensor %s timestamp %" PRIu64 " values [%f %f %f]",
+ ftl::enum_string(sensorType).c_str(), timestamp, values[0], values[1], values[2]);
if (sensor.lastSampleTimeNs.has_value() &&
timestamp - sensor.lastSampleTimeNs.value() < sensor.samplingPeriod.count()) {
- if (DEBUG_SENSOR_EVENT_DETAILS) {
- ALOGD("Sensor %s Skip a sample.", ftl::enum_string(sensorType).c_str());
- }
+ ALOGD_IF(DEBUG_SENSOR_EVENT_DETAILS, "Sensor %s Skip a sample.",
+ ftl::enum_string(sensorType).c_str());
} else {
// Convert to Android unit
convertFromLinuxToAndroid(values, sensorType);
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index a3a48ef..264ef6f 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -43,10 +43,8 @@
std::list<NotifyArgs> VibratorInputMapper::vibrate(const VibrationSequence& sequence,
ssize_t repeat, int32_t token) {
- if (DEBUG_VIBRATOR) {
- ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%zd, token=%d", getDeviceId(),
- sequence.toString().c_str(), repeat, token);
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "vibrate: deviceId=%d, pattern=[%s], repeat=%zd, token=%d",
+ getDeviceId(), sequence.toString().c_str(), repeat, token);
std::list<NotifyArgs> out;
mVibrating = true;
@@ -63,9 +61,7 @@
}
std::list<NotifyArgs> VibratorInputMapper::cancelVibrate(int32_t token) {
- if (DEBUG_VIBRATOR) {
- ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
std::list<NotifyArgs> out;
if (mVibrating && mToken == token) {
@@ -95,9 +91,7 @@
}
std::list<NotifyArgs> VibratorInputMapper::nextStep() {
- if (DEBUG_VIBRATOR) {
- ALOGD("nextStep: index=%d, vibrate deviceId=%d", (int)mIndex, getDeviceId());
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "nextStep: index=%d, vibrate deviceId=%d", (int)mIndex, getDeviceId());
std::list<NotifyArgs> out;
mIndex += 1;
if (size_t(mIndex) >= mSequence.pattern.size()) {
@@ -111,16 +105,11 @@
const VibrationElement& element = mSequence.pattern[mIndex];
if (element.isOn()) {
- if (DEBUG_VIBRATOR) {
- std::string description = element.toString();
- ALOGD("nextStep: sending vibrate deviceId=%d, element=%s", getDeviceId(),
- description.c_str());
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "nextStep: sending vibrate deviceId=%d, element=%s", getDeviceId(),
+ element.toString().c_str());
getDeviceContext().vibrate(element);
} else {
- if (DEBUG_VIBRATOR) {
- ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
getDeviceContext().cancelVibrate();
}
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -128,17 +117,13 @@
std::chrono::duration_cast<std::chrono::nanoseconds>(element.duration);
mNextStepTime = now + duration.count();
getContext()->requestTimeoutAtTime(mNextStepTime);
- if (DEBUG_VIBRATOR) {
- ALOGD("nextStep: scheduled timeout in %lldms", element.duration.count());
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "nextStep: scheduled timeout in %lldms", element.duration.count());
return out;
}
NotifyVibratorStateArgs VibratorInputMapper::stopVibrating() {
mVibrating = false;
- if (DEBUG_VIBRATOR) {
- ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
- }
+ ALOGD_IF(DEBUG_VIBRATOR, "stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
getDeviceContext().cancelVibrate();
// Request InputReader to notify InputManagerService for vibration complete.
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7cc4ff7..e0a4afb 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -9924,6 +9924,9 @@
virtual void SetUp() override {
InputDispatcherTest::SetUp();
+ // Use current time as start time otherwise events may be dropped due to being stale.
+ mGestureStartTime = std::chrono::nanoseconds(systemTime(SYSTEM_TIME_MONOTONIC));
+
std::shared_ptr<FakeApplicationHandle> application =
std::make_shared<FakeApplicationHandle>();
application->setDispatchingTimeout(100ms);
@@ -9941,82 +9944,81 @@
mWindow->consumeFocusEvent(true);
}
- void notifyAndConsumeMotion(int32_t action, uint32_t source, ui::LogicalDisplayId displayId,
- nsecs_t eventTime) {
- mDispatcher->notifyMotion(MotionArgsBuilder(action, source)
- .displayId(displayId)
- .eventTime(eventTime)
- .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
- .build());
+ NotifyMotionArgs notifyAndConsumeMotion(int32_t action, uint32_t source,
+ ui::LogicalDisplayId displayId,
+ std::chrono::nanoseconds timeDelay) {
+ const NotifyMotionArgs motionArgs =
+ MotionArgsBuilder(action, source)
+ .displayId(displayId)
+ .eventTime((mGestureStartTime + timeDelay).count())
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .build();
+ mDispatcher->notifyMotion(motionArgs);
mWindow->consumeMotionEvent(WithMotionAction(action));
+ return motionArgs;
}
private:
sp<FakeWindowHandle> mWindow;
+ std::chrono::nanoseconds mGestureStartTime;
};
TEST_F_WITH_FLAGS(
InputDispatcherUserActivityPokeTests, MinPokeTimeObserved,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
- // Use current time otherwise events may be dropped due to being stale.
- const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
-
mDispatcher->setMinTimeBetweenUserActivityPokes(50ms);
// First event of type TOUCH. Should poke.
- notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(50));
+ NotifyMotionArgs motionArgs =
+ notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(50));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(50), USER_ACTIVITY_EVENT_TOUCH,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}});
// 80ns > 50ns has passed since previous TOUCH event. Should poke.
- notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(130));
+ motionArgs =
+ notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(130));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(130), USER_ACTIVITY_EVENT_TOUCH,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}});
// First event of type OTHER. Should poke (despite being within 50ns of previous TOUCH event).
- notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(135));
+ motionArgs =
+ notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(135));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(135), USER_ACTIVITY_EVENT_OTHER,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_OTHER, ui::LogicalDisplayId::DEFAULT}});
// Within 50ns of previous TOUCH event. Should NOT poke.
notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(140));
+ std::chrono::milliseconds(140));
mFakePolicy->assertUserActivityNotPoked();
// Within 50ns of previous OTHER event. Should NOT poke.
notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(150));
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(150));
mFakePolicy->assertUserActivityNotPoked();
// Within 50ns of previous TOUCH event (which was at time 130). Should NOT poke.
// Note that STYLUS is mapped to TOUCH user activity, since it's a pointer-type source.
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(160));
+ std::chrono::milliseconds(160));
mFakePolicy->assertUserActivityNotPoked();
// 65ns > 50ns has passed since previous OTHER event. Should poke.
- notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
- ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(200));
+ motionArgs =
+ notifyAndConsumeMotion(ACTION_SCROLL, AINPUT_SOURCE_ROTARY_ENCODER,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(200));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_OTHER,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_OTHER, ui::LogicalDisplayId::DEFAULT}});
// 170ns > 50ns has passed since previous TOUCH event. Should poke.
- notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(300));
+ motionArgs =
+ notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_STYLUS, ui::LogicalDisplayId::DEFAULT,
+ std::chrono::milliseconds(300));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(300), USER_ACTIVITY_EVENT_TOUCH,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}});
// Assert that there's no more user activity poke event.
mFakePolicy->assertUserActivityNotPoked();
@@ -10026,39 +10028,35 @@
InputDispatcherUserActivityPokeTests, DefaultMinPokeTimeOf100MsUsed,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
- // Use current time otherwise events may be dropped due to being stale.
- const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
- notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(200));
+ NotifyMotionArgs motionArgs =
+ notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(200));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(200), USER_ACTIVITY_EVENT_TOUCH,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}});
notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(280));
+ std::chrono::milliseconds(280));
mFakePolicy->assertUserActivityNotPoked();
- notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + milliseconds_to_nanoseconds(340));
+ motionArgs =
+ notifyAndConsumeMotion(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
+ ui::LogicalDisplayId::DEFAULT, std::chrono::milliseconds(340));
mFakePolicy->assertUserActivityPoked(
- {{currentTime + milliseconds_to_nanoseconds(340), USER_ACTIVITY_EVENT_TOUCH,
- ui::LogicalDisplayId::DEFAULT}});
+ {{motionArgs.eventTime, USER_ACTIVITY_EVENT_TOUCH, ui::LogicalDisplayId::DEFAULT}});
}
TEST_F_WITH_FLAGS(
InputDispatcherUserActivityPokeTests, ZeroMinPokeTimeDisablesRateLimiting,
REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(com::android::input::flags,
rate_limit_user_activity_poke_in_dispatcher))) {
- // Use current time otherwise events may be dropped due to being stale.
- const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
mDispatcher->setMinTimeBetweenUserActivityPokes(0ms);
notifyAndConsumeMotion(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + 20);
+ std::chrono::milliseconds(20));
mFakePolicy->assertUserActivityPoked();
notifyAndConsumeMotion(ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, ui::LogicalDisplayId::DEFAULT,
- currentTime + 30);
+ std::chrono::milliseconds(30));
mFakePolicy->assertUserActivityPoked();
}
diff --git a/services/surfaceflinger/Display/DisplayModeRequest.h b/services/surfaceflinger/Display/DisplayModeRequest.h
index ec3ec52..2e9dc1e 100644
--- a/services/surfaceflinger/Display/DisplayModeRequest.h
+++ b/services/surfaceflinger/Display/DisplayModeRequest.h
@@ -26,7 +26,8 @@
struct DisplayModeRequest {
scheduler::FrameRateMode mode;
- // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE.
+ // Whether to emit DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE for a change in refresh rate
+ // or render rate. Ignored for resolution changes, which always emit the event.
bool emitEvent = false;
// Whether to force the request to be applied, even if the mode is unchanged.
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c743ea2..e8b09b0 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -223,9 +223,7 @@
mFlags = flags;
}
-void DisplayDevice::setDisplaySize(int width, int height) {
- LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
- const auto size = ui::Size(width, height);
+void DisplayDevice::setDisplaySize(ui::Size size) {
mCompositionDisplay->setDisplaySize(size);
if (mRefreshRateOverlay) {
mRefreshRateOverlay->setViewport(size);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 23b3637..b5a543a 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -98,7 +98,7 @@
ui::Size getSize() const { return {getWidth(), getHeight()}; }
void setLayerFilter(ui::LayerFilter);
- void setDisplaySize(int width, int height);
+ void setDisplaySize(ui::Size);
void setProjection(ui::Rotation orientation, Rect viewport, Rect frame);
void stageBrightness(float brightness) REQUIRES(kMainThreadContext);
void persistBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h
index f2be316..4dd3ab6 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameRateMode.h
@@ -33,6 +33,10 @@
}
bool operator!=(const FrameRateMode& other) const { return !(*this == other); }
+
+ bool matchesResolution(const FrameRateMode& other) const {
+ return modePtr->getResolution() == other.modePtr->getResolution();
+ }
};
inline std::string to_string(const FrameRateMode& mode) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 574d39a..f3db4c5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1363,7 +1363,8 @@
const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
if (!selectorPtr) break;
- const Fps renderRate = selectorPtr->getActiveMode().fps;
+ const auto activeMode = selectorPtr->getActiveMode();
+ const Fps renderRate = activeMode.fps;
// DisplayModeController::setDesiredMode updated the render rate, so inform Scheduler.
mScheduler->setRenderRate(displayId, renderRate, true /* applyImmediately */);
@@ -1382,6 +1383,15 @@
mScheduler->updatePhaseConfiguration(displayId, mode.fps);
mScheduler->setModeChangePending(true);
+
+ // The mode set to switch resolution is not initiated until the display transaction that
+ // resizes the display. DM sends this transaction in response to a mode change event, so
+ // emit the event now, not when finalizing the mode change as for a refresh rate switch.
+ if (FlagManager::getInstance().synced_resolution_switch() &&
+ !mode.matchesResolution(activeMode)) {
+ mScheduler->onDisplayModeChanged(displayId, mode,
+ /*clearContentRequirements*/ true);
+ }
break;
}
case DesiredModeAction::InitiateRenderRateSwitch:
@@ -1460,19 +1470,25 @@
}
const auto& activeMode = pendingModeOpt->mode;
+ const bool resolutionMatch = !FlagManager::getInstance().synced_resolution_switch() ||
+ activeMode.matchesResolution(mDisplayModeController.getActiveMode(displayId));
- if (const auto oldResolution =
- mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
- oldResolution != activeMode.modePtr->getResolution()) {
- auto& state = mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
- // We need to generate new sequenceId in order to recreate the display (and this
- // way the framebuffer).
- state.sequenceId = DisplayDeviceState{}.sequenceId;
- state.physical->activeMode = activeMode.modePtr.get();
- processDisplayChangesLocked();
+ if (!FlagManager::getInstance().synced_resolution_switch()) {
+ if (const auto oldResolution =
+ mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
+ oldResolution != activeMode.modePtr->getResolution()) {
+ auto& state =
+ mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
+ // We need to generate new sequenceId in order to recreate the display (and this
+ // way the framebuffer).
+ state.sequenceId = DisplayDeviceState{}.sequenceId;
+ state.physical->activeMode = activeMode.modePtr.get();
+ processDisplayChangesLocked();
- // The DisplayDevice has been destroyed, so abort the commit for the now dead FrameTargeter.
- return false;
+ // The DisplayDevice has been destroyed, so abort the commit for the now dead
+ // FrameTargeter.
+ return false;
+ }
}
mDisplayModeController.finalizeModeChange(displayId, activeMode.modePtr->getId(),
@@ -1480,7 +1496,8 @@
mScheduler->updatePhaseConfiguration(displayId, activeMode.fps);
- if (pendingModeOpt->emitEvent) {
+ // Skip for resolution changes, since the event was already emitted on setting the desired mode.
+ if (resolutionMatch && pendingModeOpt->emitEvent) {
mScheduler->onDisplayModeChanged(displayId, activeMode, /*clearContentRequirements*/ true);
}
@@ -1532,8 +1549,9 @@
to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(),
to_string(displayId).c_str());
- if ((!FlagManager::getInstance().connected_display() || !desiredModeOpt->force) &&
- mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
+ const auto activeMode = mDisplayModeController.getActiveMode(displayId);
+
+ if (!desiredModeOpt->force && desiredModeOpt->mode == activeMode) {
applyActiveMode(displayId);
continue;
}
@@ -1554,6 +1572,15 @@
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline outTimeline;
+ // When initiating a resolution change, wait until the commit that resizes the display.
+ if (FlagManager::getInstance().synced_resolution_switch() &&
+ !activeMode.matchesResolution(desiredModeOpt->mode)) {
+ const auto display = getDisplayDeviceLocked(displayId);
+ if (display->getSize() != desiredModeOpt->mode.modePtr->getResolution()) {
+ continue;
+ }
+ }
+
const auto error =
mDisplayModeController.initiateModeChange(displayId, std::move(*desiredModeOpt),
constraints, outTimeline);
@@ -3459,13 +3486,7 @@
mTimeStats->setPresentFenceGlobal(pacesetterPresentFenceTime);
for (auto&& [id, presentFence] : presentFences) {
- ftl::FakeGuard guard(mStateLock);
- const bool isInternalDisplay =
- mPhysicalDisplays.get(id).transform(&PhysicalDisplay::isInternal).value_or(false);
-
- if (isInternalDisplay) {
- mScheduler->addPresentFence(id, std::move(presentFence));
- }
+ mScheduler->addPresentFence(id, std::move(presentFence));
}
const bool hasPacesetterDisplay =
@@ -4130,6 +4151,35 @@
if (currentState.flags != drawingState.flags) {
display->setFlags(currentState.flags);
}
+
+ const auto updateDisplaySize = [&]() {
+ if (currentState.width != drawingState.width ||
+ currentState.height != drawingState.height) {
+ const ui::Size resolution = ui::Size(currentState.width, currentState.height);
+
+ // Resize the framebuffer. For a virtual display, always do so. For a physical
+ // display, only do so if it has a pending modeset for the matching resolution.
+ if (!currentState.physical ||
+ (FlagManager::getInstance().synced_resolution_switch() &&
+ mDisplayModeController.getDesiredMode(display->getPhysicalId())
+ .transform([resolution](const auto& request) {
+ return resolution == request.mode.modePtr->getResolution();
+ })
+ .value_or(false))) {
+ display->setDisplaySize(resolution);
+ }
+
+ if (display->getId() == mActiveDisplayId) {
+ onActiveDisplaySizeChanged(*display);
+ }
+ }
+ };
+
+ if (FlagManager::getInstance().synced_resolution_switch()) {
+ // Update display size first, as display projection below depends on it.
+ updateDisplaySize();
+ }
+
if ((currentState.orientation != drawingState.orientation) ||
(currentState.layerStackSpaceRect != drawingState.layerStackSpaceRect) ||
(currentState.orientedDisplaySpaceRect != drawingState.orientedDisplaySpaceRect)) {
@@ -4141,13 +4191,9 @@
ui::Transform::toRotationFlags(display->getOrientation());
}
}
- if (currentState.width != drawingState.width ||
- currentState.height != drawingState.height) {
- display->setDisplaySize(currentState.width, currentState.height);
- if (display->getId() == mActiveDisplayId) {
- onActiveDisplaySizeChanged(*display);
- }
+ if (!FlagManager::getInstance().synced_resolution_switch()) {
+ updateDisplaySize();
}
}
}
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index b1552e6..f9aba9f 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -171,6 +171,7 @@
DUMP_ACONFIG_FLAG(restore_blur_step);
DUMP_ACONFIG_FLAG(skip_invisible_windows_in_input);
DUMP_ACONFIG_FLAG(stable_edid_ids);
+ DUMP_ACONFIG_FLAG(synced_resolution_switch);
DUMP_ACONFIG_FLAG(trace_frame_rate_override);
DUMP_ACONFIG_FLAG(true_hdr_screenshots);
DUMP_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency);
@@ -295,6 +296,7 @@
FLAG_MANAGER_ACONFIG_FLAG(begone_bright_hlg, "debug.sf.begone_bright_hlg");
FLAG_MANAGER_ACONFIG_FLAG(window_blur_kawase2, "");
FLAG_MANAGER_ACONFIG_FLAG(reject_dupe_layerstacks, "");
+FLAG_MANAGER_ACONFIG_FLAG(synced_resolution_switch, "");
/// Trunk stable server (R/W) flags ///
FLAG_MANAGER_ACONFIG_FLAG(refresh_rate_overlay_on_external_display, "")
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 073302e..de3f359 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -107,6 +107,7 @@
bool restore_blur_step() const;
bool skip_invisible_windows_in_input() const;
bool stable_edid_ids() const;
+ bool synced_resolution_switch() const;
bool trace_frame_rate_override() const;
bool true_hdr_screenshots() const;
bool use_known_refresh_rate_for_fps_consistency() const;
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index 96ab7ab..fa1da45 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -265,6 +265,13 @@
} # stable_edid_ids
flag {
+ name: "synced_resolution_switch"
+ namespace: "core_graphics"
+ description: "Synchronize resolution modeset with framebuffer resizing"
+ bug: "355427258"
+} # synced_resolution_switch
+
+flag {
name: "true_hdr_screenshots"
namespace: "core_graphics"
description: "Enables screenshotting display content in HDR, sans tone mapping"