Merge "SF: Introduce VsyncTimeline to VsyncPredictor" into main
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 3af9ec7..bf7a0ba 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -258,24 +258,11 @@
}
}
-void ABBinder::addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& /* recipient */,
- void* /* cookie */) {
- LOG_ALWAYS_FATAL("Should not reach this. Can't linkToDeath local binders.");
-}
-
ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder)
: AIBinder(nullptr /*clazz*/), mRemote(binder) {
LOG_ALWAYS_FATAL_IF(binder == nullptr, "binder == nullptr");
}
-
-ABpBinder::~ABpBinder() {
- for (auto& recip : mDeathRecipients) {
- sp<AIBinder_DeathRecipient> strongRecip = recip.recipient.promote();
- if (strongRecip) {
- strongRecip->pruneThisTransferEntry(getBinder(), recip.cookie);
- }
- }
-}
+ABpBinder::~ABpBinder() {}
sp<AIBinder> ABpBinder::lookupOrCreateFromBinder(const ::android::sp<::android::IBinder>& binder) {
if (binder == nullptr) {
@@ -314,11 +301,6 @@
return ret;
}
-void ABpBinder::addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& recipient,
- void* cookie) {
- mDeathRecipients.emplace_back(recipient, cookie);
-}
-
struct AIBinder_Weak {
wp<AIBinder> binder;
};
@@ -444,17 +426,6 @@
LOG_ALWAYS_FATAL_IF(onDied == nullptr, "onDied == nullptr");
}
-void AIBinder_DeathRecipient::pruneThisTransferEntry(const sp<IBinder>& who, void* cookie) {
- std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
- mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
- [&](const sp<TransferDeathRecipient>& tdr) {
- auto tdrWho = tdr->getWho();
- return tdrWho != nullptr && tdrWho.promote() == who &&
- cookie == tdr->getCookie();
- }),
- mDeathRecipients.end());
-}
-
void AIBinder_DeathRecipient::pruneDeadTransferEntriesLocked() {
mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(),
[](const sp<TransferDeathRecipient>& tdr) {
@@ -583,11 +554,8 @@
return STATUS_UNEXPECTED_NULL;
}
- binder_status_t ret = recipient->linkToDeath(binder->getBinder(), cookie);
- if (ret == STATUS_OK) {
- binder->addDeathRecipient(recipient, cookie);
- }
- return ret;
+ // returns binder_status_t
+ return recipient->linkToDeath(binder->getBinder(), cookie);
}
binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index a2682d8..9d5368f 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -51,8 +51,6 @@
::android::sp<::android::IBinder> binder = const_cast<AIBinder*>(this)->getBinder();
return binder->remoteBinder() != nullptr;
}
- virtual void addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& recipient,
- void* cookie) = 0;
private:
// AIBinder instance is instance of this class for a local object. In order to transact on a
@@ -80,8 +78,6 @@
::android::status_t dump(int fd, const ::android::Vector<::android::String16>& args) override;
::android::status_t onTransact(uint32_t code, const ::android::Parcel& data,
::android::Parcel* reply, binder_flags_t flags) override;
- void addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& /* recipient */,
- void* /* cookie */) override;
private:
ABBinder(const AIBinder_Class* clazz, void* userData);
@@ -110,19 +106,12 @@
bool isServiceFuzzing() const { return mServiceFuzzing; }
void setServiceFuzzing() { mServiceFuzzing = true; }
- void addDeathRecipient(const ::android::sp<AIBinder_DeathRecipient>& recipient,
- void* cookie) override;
private:
friend android::sp<ABpBinder>;
explicit ABpBinder(const ::android::sp<::android::IBinder>& binder);
::android::sp<::android::IBinder> mRemote;
bool mServiceFuzzing = false;
- struct DeathRecipientInfo {
- android::wp<AIBinder_DeathRecipient> recipient;
- void* cookie;
- };
- std::vector<DeathRecipientInfo> mDeathRecipients;
};
struct AIBinder_Class {
@@ -194,7 +183,6 @@
binder_status_t linkToDeath(const ::android::sp<::android::IBinder>&, void* cookie);
binder_status_t unlinkToDeath(const ::android::sp<::android::IBinder>& binder, void* cookie);
void setOnUnlinked(AIBinder_DeathRecipient_onBinderUnlinked onUnlinked);
- void pruneThisTransferEntry(const ::android::sp<::android::IBinder>&, void* cookie);
private:
// When the user of this API deletes a Bp object but not the death recipient, the
diff --git a/libs/binder/ndk/tests/iface.cpp b/libs/binder/ndk/tests/iface.cpp
index ca92727..3ee36cd 100644
--- a/libs/binder/ndk/tests/iface.cpp
+++ b/libs/binder/ndk/tests/iface.cpp
@@ -25,7 +25,6 @@
const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
const char* IFoo::kInstanceNameToDieFor = "libbinder_ndk-test-IFoo-to-die";
-const char* IFoo::kInstanceNameToDieFor2 = "libbinder_ndk-test-IFoo-to-die2";
const char* IFoo::kIFooDescriptor = "my-special-IFoo-class";
struct IFoo_Class_Data {
diff --git a/libs/binder/ndk/tests/include/iface/iface.h b/libs/binder/ndk/tests/include/iface/iface.h
index 0cdd50b..0a562f0 100644
--- a/libs/binder/ndk/tests/include/iface/iface.h
+++ b/libs/binder/ndk/tests/include/iface/iface.h
@@ -27,7 +27,6 @@
public:
static const char* kSomeInstanceName;
static const char* kInstanceNameToDieFor;
- static const char* kInstanceNameToDieFor2;
static const char* kIFooDescriptor;
static AIBinder_Class* kClass;
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index ce63b82..966ec95 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -536,7 +536,6 @@
bool deathReceived = false;
std::function<void(void)> onDeath = [&] {
- std::unique_lock<std::mutex> lockDeath(deathMutex);
std::cerr << "Binder died (as requested)." << std::endl;
deathReceived = true;
deathCv.notify_one();
@@ -548,7 +547,6 @@
bool wasDeathReceivedFirst = false;
std::function<void(void)> onUnlink = [&] {
- std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
std::cerr << "Binder unlinked (as requested)." << std::endl;
wasDeathReceivedFirst = deathReceived;
unlinkReceived = true;
@@ -562,6 +560,7 @@
EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(cookie)));
+ // the binder driver should return this if the service dies during the transaction
EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
foo = nullptr;
@@ -580,123 +579,6 @@
binder = nullptr;
}
-TEST(NdkBinder, DeathRecipientDropBinderNoDeath) {
- using namespace std::chrono_literals;
-
- std::mutex deathMutex;
- std::condition_variable deathCv;
- bool deathReceived = false;
-
- std::function<void(void)> onDeath = [&] {
- std::unique_lock<std::mutex> lockDeath(deathMutex);
- std::cerr << "Binder died (as requested)." << std::endl;
- deathReceived = true;
- deathCv.notify_one();
- };
-
- std::mutex unlinkMutex;
- std::condition_variable unlinkCv;
- bool unlinkReceived = false;
- bool wasDeathReceivedFirst = false;
-
- std::function<void(void)> onUnlink = [&] {
- std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
- std::cerr << "Binder unlinked (as requested)." << std::endl;
- wasDeathReceivedFirst = deathReceived;
- unlinkReceived = true;
- unlinkCv.notify_one();
- };
-
- // keep the death recipient around
- ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
- AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlink);
-
- {
- AIBinder* binder;
- sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor2, &binder);
- ASSERT_NE(nullptr, foo.get());
- ASSERT_NE(nullptr, binder);
-
- DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
-
- EXPECT_EQ(STATUS_OK,
- AIBinder_linkToDeath(binder, recipient.get(), static_cast<void*>(cookie)));
- // let the sp<IFoo> and AIBinder fall out of scope
- AIBinder_decStrong(binder);
- binder = nullptr;
- }
-
- {
- std::unique_lock<std::mutex> lockDeath(deathMutex);
- EXPECT_FALSE(deathCv.wait_for(lockDeath, 100ms, [&] { return deathReceived; }));
- EXPECT_FALSE(deathReceived);
- }
-
- {
- std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
- EXPECT_TRUE(deathCv.wait_for(lockUnlink, 1s, [&] { return unlinkReceived; }));
- EXPECT_TRUE(unlinkReceived);
- EXPECT_FALSE(wasDeathReceivedFirst);
- }
-}
-
-TEST(NdkBinder, DeathRecipientDropBinderOnDied) {
- using namespace std::chrono_literals;
-
- std::mutex deathMutex;
- std::condition_variable deathCv;
- bool deathReceived = false;
-
- sp<IFoo> foo;
- AIBinder* binder;
- std::function<void(void)> onDeath = [&] {
- std::unique_lock<std::mutex> lockDeath(deathMutex);
- std::cerr << "Binder died (as requested)." << std::endl;
- deathReceived = true;
- AIBinder_decStrong(binder);
- binder = nullptr;
- deathCv.notify_one();
- };
-
- std::mutex unlinkMutex;
- std::condition_variable unlinkCv;
- bool unlinkReceived = false;
- bool wasDeathReceivedFirst = false;
-
- std::function<void(void)> onUnlink = [&] {
- std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
- std::cerr << "Binder unlinked (as requested)." << std::endl;
- wasDeathReceivedFirst = deathReceived;
- unlinkReceived = true;
- unlinkCv.notify_one();
- };
-
- ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
- AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlink);
-
- foo = IFoo::getService(IFoo::kInstanceNameToDieFor2, &binder);
- ASSERT_NE(nullptr, foo.get());
- ASSERT_NE(nullptr, binder);
-
- DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
- EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient.get(), static_cast<void*>(cookie)));
-
- EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
-
- {
- std::unique_lock<std::mutex> lockDeath(deathMutex);
- EXPECT_TRUE(deathCv.wait_for(lockDeath, 1s, [&] { return deathReceived; }));
- EXPECT_TRUE(deathReceived);
- }
-
- {
- std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
- EXPECT_TRUE(deathCv.wait_for(lockUnlink, 100ms, [&] { return unlinkReceived; }));
- EXPECT_TRUE(unlinkReceived);
- EXPECT_TRUE(wasDeathReceivedFirst);
- }
-}
-
TEST(NdkBinder, RetrieveNonNdkService) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -1076,10 +958,6 @@
}
if (fork() == 0) {
prctl(PR_SET_PDEATHSIG, SIGHUP);
- return manualThreadPoolService(IFoo::kInstanceNameToDieFor2);
- }
- if (fork() == 0) {
- prctl(PR_SET_PDEATHSIG, SIGHUP);
return manualPollingService(IFoo::kSomeInstanceName);
}
if (fork() == 0) {
diff --git a/libs/gui/FrameRateUtils.cpp b/libs/gui/FrameRateUtils.cpp
index 11524e2..01aa7ed 100644
--- a/libs/gui/FrameRateUtils.cpp
+++ b/libs/gui/FrameRateUtils.cpp
@@ -42,6 +42,7 @@
if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE &&
+ compatibility != ANATIVEWINDOW_FRAME_RATE_GTE &&
(!privileged ||
(compatibility != ANATIVEWINDOW_FRAME_RATE_EXACT &&
compatibility != ANATIVEWINDOW_FRAME_RATE_NO_VOTE))) {
diff --git a/libs/gui/tests/FrameRateUtilsTest.cpp b/libs/gui/tests/FrameRateUtilsTest.cpp
index 5fe22b0..04bfb28 100644
--- a/libs/gui/tests/FrameRateUtilsTest.cpp
+++ b/libs/gui/tests/FrameRateUtilsTest.cpp
@@ -34,6 +34,8 @@
ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS, ""));
EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
+ EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_GTE,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, ""));
// Privileged APIs.
EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT,
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index b43ab6c..eb7a9d5 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -378,6 +378,11 @@
BAIL("Could not find a Vulkan 1.1+ physical device");
}
+ if (physDevProps.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+ // TODO: b/326633110 - SkiaVK is not working correctly on swiftshader path.
+ BAIL("CPU implementations of Vulkan is not supported");
+ }
+
// Check for syncfd support. Bail if we cannot both import and export them.
VkPhysicalDeviceExternalSemaphoreInfo semInfo = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp
index e60db93..91c2d1f 100644
--- a/services/sensorservice/AidlSensorHalWrapper.cpp
+++ b/services/sensorservice/AidlSensorHalWrapper.cpp
@@ -178,6 +178,11 @@
if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) {
ALOGD("Event FMQ internal wake, returning from poll with no events");
return DEAD_OBJECT;
+ } else if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mInHalBypassMode &&
+ availableEvents == 0) {
+ ALOGD("Event FMQ internal wake due to HAL Bypass Mode, returning from poll with no "
+ "events");
+ return OK;
}
}
@@ -221,6 +226,17 @@
status_t AidlSensorHalWrapper::setOperationMode(SensorService::Mode mode) {
if (mSensors == nullptr) return NO_INIT;
+ if (mode == SensorService::Mode::HAL_BYPASS_REPLAY_DATA_INJECTION) {
+ if (!mInHalBypassMode) {
+ mInHalBypassMode = true;
+ mEventQueueFlag->wake(asBaseType(INTERNAL_WAKE));
+ }
+ return OK;
+ } else {
+ if (mInHalBypassMode) {
+ mInHalBypassMode = false;
+ }
+ }
return convertToStatus(mSensors->setOperationMode(static_cast<ISensors::OperationMode>(mode)));
}
diff --git a/services/sensorservice/HidlSensorHalWrapper.cpp b/services/sensorservice/HidlSensorHalWrapper.cpp
index c55c9b4..8c867bd 100644
--- a/services/sensorservice/HidlSensorHalWrapper.cpp
+++ b/services/sensorservice/HidlSensorHalWrapper.cpp
@@ -203,6 +203,11 @@
if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) {
ALOGD("Event FMQ internal wake, returning from poll with no events");
return DEAD_OBJECT;
+ } else if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mInHalBypassMode &&
+ availableEvents == 0) {
+ ALOGD("Event FMQ internal wake due to HAL Bypass Mode, returning from poll with no "
+ "events");
+ return OK;
}
}
@@ -251,6 +256,17 @@
status_t HidlSensorHalWrapper::setOperationMode(SensorService::Mode mode) {
if (mSensors == nullptr) return NO_INIT;
+ if (mode == SensorService::Mode::HAL_BYPASS_REPLAY_DATA_INJECTION) {
+ if (!mInHalBypassMode) {
+ mInHalBypassMode = true;
+ mEventQueueFlag->wake(asBaseType(INTERNAL_WAKE));
+ }
+ return OK;
+ } else {
+ if (mInHalBypassMode) {
+ mInHalBypassMode = false;
+ }
+ }
return checkReturnAndGetStatus(
mSensors->setOperationMode(static_cast<hardware::sensors::V1_0::OperationMode>(mode)));
}
diff --git a/services/sensorservice/ISensorHalWrapper.h b/services/sensorservice/ISensorHalWrapper.h
index 3d33540..891dfe5 100644
--- a/services/sensorservice/ISensorHalWrapper.h
+++ b/services/sensorservice/ISensorHalWrapper.h
@@ -97,6 +97,8 @@
virtual void writeWakeLockHandled(uint32_t count) = 0;
std::atomic_bool mReconnecting = false;
+
+ std::atomic_bool mInHalBypassMode = false;
};
} // namespace android
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 8e9dfea..f62562c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -812,7 +812,6 @@
}
mInHalBypassMode = true;
}
- return OK;
} else {
if (mInHalBypassMode) {
// We are transitioning out of HAL Bypass mode. We need to notify the reader thread
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index c888ccc..77e045d 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -377,8 +377,8 @@
constexpr bool kIsProtected = false;
if (const auto fenceResult =
- mFlinger.captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, buffer,
- kRegionSampling, kGrayscale, kIsProtected, nullptr)
+ mFlinger.captureScreenshot(std::move(renderAreaFuture), getLayerSnapshots, buffer,
+ kRegionSampling, kGrayscale, kIsProtected, nullptr)
.get();
fenceResult.ok()) {
fenceResult.value()->waitForever(LOG_TAG);
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index e696e8c..93350b5 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -972,6 +972,7 @@
LOG_ALWAYS_FATAL_IF(layer->vote != LayerVoteType::ExplicitDefault &&
layer->vote != LayerVoteType::ExplicitExactOrMultiple &&
layer->vote != LayerVoteType::ExplicitExact &&
+ layer->vote != LayerVoteType::ExplicitGte &&
layer->vote != LayerVoteType::ExplicitCategory,
"Invalid layer vote type for frame rate overrides");
for (auto& [fps, score] : scoredFrameRates) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9e13144..46a2259 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -8069,6 +8069,19 @@
args.allowProtected, args.grayscale, captureListener);
}
+bool SurfaceFlinger::layersHasProtectedLayer(
+ const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const {
+ bool protectedLayerFound = false;
+ for (auto& [_, layerFe] : layers) {
+ protectedLayerFound |=
+ (layerFe->mSnapshot->isVisible && layerFe->mSnapshot->hasProtectedContent);
+ if (protectedLayerFound) {
+ break;
+ }
+ }
+ return protectedLayerFound;
+}
+
void SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
GetLayerSnapshotsFunction getLayerSnapshots,
ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
@@ -8084,6 +8097,9 @@
return;
}
+ // Snapshots must be taken from the main thread.
+ auto layers = mScheduler->schedule([=]() { return getLayerSnapshots(); }).get();
+
// Loop over all visible layers to see whether there's any protected layer. A protected layer is
// typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
// A protected layer has no implication on whether it's secure, which is explicitly set by
@@ -8091,18 +8107,7 @@
const bool supportsProtected = getRenderEngine().supportsProtectedContent();
bool hasProtectedLayer = false;
if (allowProtected && supportsProtected) {
- hasProtectedLayer = mScheduler
- ->schedule([=]() {
- bool protectedLayerFound = false;
- auto layers = getLayerSnapshots();
- for (auto& [_, layerFe] : layers) {
- protectedLayerFound |=
- (layerFe->mSnapshot->isVisible &&
- layerFe->mSnapshot->hasProtectedContent);
- }
- return protectedLayerFound;
- })
- .get();
+ hasProtectedLayer = layersHasProtectedLayer(layers);
}
const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
@@ -8127,52 +8132,53 @@
renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
renderengine::impl::ExternalTexture::Usage::
WRITEABLE);
- auto fence = captureScreenCommon(std::move(renderAreaFuture), getLayerSnapshots, texture,
- false /* regionSampling */, grayscale, isProtected,
- captureListener);
- fence.get();
+ auto futureFence =
+ captureScreenshot(std::move(renderAreaFuture), getLayerSnapshots, texture,
+ false /* regionSampling */, grayscale, isProtected, captureListener);
+ futureFence.get();
}
-ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenCommon(
+ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots,
const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
- auto future = mScheduler->schedule(
- [=, this, renderAreaFuture = std::move(renderAreaFuture)]() FTL_FAKE_GUARD(
- kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
- ScreenCaptureResults captureResults;
- std::shared_ptr<RenderArea> renderArea = renderAreaFuture.get();
- if (!renderArea) {
- ALOGW("Skipping screen capture because of invalid render area.");
- if (captureListener) {
- captureResults.fenceResult = base::unexpected(NO_MEMORY);
+ auto takeScreenshotFn = [=, this, renderAreaFuture = std::move(renderAreaFuture)]() REQUIRES(
+ kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
+ ScreenCaptureResults captureResults;
+ std::shared_ptr<RenderArea> renderArea = renderAreaFuture.get();
+ if (!renderArea) {
+ ALOGW("Skipping screen capture because of invalid render area.");
+ if (captureListener) {
+ captureResults.fenceResult = base::unexpected(NO_MEMORY);
+ captureListener->onScreenCaptureCompleted(captureResults);
+ }
+ return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share();
+ }
+
+ ftl::SharedFuture<FenceResult> renderFuture;
+ renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) {
+ renderFuture = renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling,
+ grayscale, isProtected, captureResults);
+ });
+
+ if (captureListener) {
+ // Defer blocking on renderFuture back to the Binder thread.
+ return ftl::Future(std::move(renderFuture))
+ .then([captureListener, captureResults = std::move(captureResults)](
+ FenceResult fenceResult) mutable -> FenceResult {
+ captureResults.fenceResult = std::move(fenceResult);
captureListener->onScreenCaptureCompleted(captureResults);
- }
- return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share();
- }
+ return base::unexpected(NO_ERROR);
+ })
+ .share();
+ }
+ return renderFuture;
+ };
- ftl::SharedFuture<FenceResult> renderFuture;
- renderArea->render([&]() FTL_FAKE_GUARD(kMainThreadContext) {
- renderFuture =
- renderScreenImpl(renderArea, getLayerSnapshots, buffer, regionSampling,
- grayscale, isProtected, captureResults);
- });
-
- if (captureListener) {
- // Defer blocking on renderFuture back to the Binder thread.
- return ftl::Future(std::move(renderFuture))
- .then([captureListener, captureResults = std::move(captureResults)](
- FenceResult fenceResult) mutable -> FenceResult {
- captureResults.fenceResult = std::move(fenceResult);
- captureListener->onScreenCaptureCompleted(captureResults);
- return base::unexpected(NO_ERROR);
- })
- .share();
- }
- return renderFuture;
- });
+ auto future =
+ mScheduler->schedule(FTL_FAKE_GUARD(kMainThreadContext, std::move(takeScreenshotFn)));
// Flatten nested futures.
auto chain = ftl::Future(std::move(future)).then([](ftl::SharedFuture<FenceResult> future) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 678be54..1ce8606 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -874,13 +874,17 @@
// Boot animation, on/off animations and screen capture
void startBootAnim();
+ bool layersHasProtectedLayer(const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) const;
+
void captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize,
ui::PixelFormat, bool allowProtected, bool grayscale,
const sp<IScreenCaptureListener>&);
- ftl::SharedFuture<FenceResult> captureScreenCommon(
+
+ ftl::SharedFuture<FenceResult> captureScreenshot(
RenderAreaFuture, GetLayerSnapshotsFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
bool grayscale, bool isProtected, const sp<IScreenCaptureListener>&);
+
ftl::SharedFuture<FenceResult> renderScreenImpl(
std::shared_ptr<const RenderArea>, GetLayerSnapshotsFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
index c8f4218..eda0674 100644
--- a/services/surfaceflinger/surfaceflinger_flags.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -189,6 +189,10 @@
namespace: "core_graphics"
description: "This flag is guarding the behaviour where SurfaceFlinger is trying to opportunistically present a frame when the configuration change from late to early"
bug: "273702768"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
flag {