428 lines
23 KiB
Diff
428 lines
23 KiB
Diff
From 2ac47153cf897bfe24eab0dd5aae3ed9fdf88df4 Mon Sep 17 00:00:00 2001
|
|
From: Peter Cai <peter@typeblog.net>
|
|
Date: Sun, 15 Jun 2025 17:36:10 -0400
|
|
Subject: [PATCH 3/6] Revert "Remove flag single_hop_screenshots"
|
|
|
|
This reverts commit 16c4c32c55231dc241c386a0423710baa452b7de.
|
|
|
|
Further changes have been made to SurfaceFlinger since that commit, for
|
|
example, removal of displayState and attachGainmap. This revert has been
|
|
adjusted accordingly, though not 100% sure everything is correct.
|
|
|
|
Change-Id: Ibdea8e3dec6ad4b85c43ad059847c63f934c3d24
|
|
|
|
Conflicts:
|
|
services/surfaceflinger/RegionSamplingThread.cpp
|
|
services/surfaceflinger/SurfaceFlinger.cpp
|
|
services/surfaceflinger/SurfaceFlinger.h
|
|
services/surfaceflinger/common/FlagManager.cpp
|
|
services/surfaceflinger/common/include/common/FlagManager.h
|
|
services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
|
|
---
|
|
.../surfaceflinger/RegionSamplingThread.cpp | 19 +-
|
|
services/surfaceflinger/SurfaceFlinger.cpp | 251 ++++++++++++------
|
|
services/surfaceflinger/SurfaceFlinger.h | 10 +-
|
|
.../surfaceflinger/common/FlagManager.cpp | 2 +
|
|
.../common/include/common/FlagManager.h | 1 +
|
|
.../tests/unittests/TestableSurfaceFlinger.h | 2 +-
|
|
6 files changed, 195 insertions(+), 90 deletions(-)
|
|
|
|
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
|
|
index 615492a872..e266656b5d 100644
|
|
--- a/services/surfaceflinger/RegionSamplingThread.cpp
|
|
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
|
|
@@ -355,11 +355,20 @@ void RegionSamplingThread::captureSample() {
|
|
screenshotArgs.isSecure = true;
|
|
screenshotArgs.seamlessTransition = false;
|
|
|
|
- std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
|
|
- mFlinger.getSnapshotsFromMainThread(screenshotArgs, getLayerSnapshotsFn, layers);
|
|
- FenceResult fenceResult = mFlinger.captureScreenshot(screenshotArgs, buffer, kRegionSampling,
|
|
- kGrayscale, kIsProtected, nullptr, layers)
|
|
- .get();
|
|
+ FenceResult fenceResult;
|
|
+ if (FlagManager::getInstance().single_hop_screenshot()) {
|
|
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
|
|
+ auto displayState =
|
|
+ mFlinger.getSnapshotsFromMainThread(screenshotArgs, getLayerSnapshotsFn, layers);
|
|
+ fenceResult = mFlinger.captureScreenshot(screenshotArgs, buffer, kRegionSampling,
|
|
+ kGrayscale, kIsProtected, nullptr, layers)
|
|
+ .get();
|
|
+ } else {
|
|
+ fenceResult = mFlinger.captureScreenshotLegacy(screenshotArgs, getLayerSnapshotsFn, buffer,
|
|
+ kRegionSampling, kGrayscale,
|
|
+ kIsProtected, false /* attachGainmap */, nullptr)
|
|
+ .get();
|
|
+ }
|
|
if (fenceResult.ok()) {
|
|
fenceResult.value()->waitForever(LOG_TAG);
|
|
}
|
|
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
|
|
index 42a77fd844..d601b24cbd 100644
|
|
--- a/services/surfaceflinger/SurfaceFlinger.cpp
|
|
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
|
|
@@ -7706,87 +7706,124 @@ void SurfaceFlinger::captureScreenCommon(ScreenshotArgs& args,
|
|
return;
|
|
}
|
|
|
|
- std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
|
|
- bool hasDisplayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers);
|
|
- if (!hasDisplayState) {
|
|
- ALOGD("Display state not found");
|
|
- invokeScreenCaptureError(NO_MEMORY, captureListener);
|
|
- }
|
|
+ if (FlagManager::getInstance().single_hop_screenshot()) {
|
|
+ std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
|
|
+ bool hasDisplayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers);
|
|
+ if (!hasDisplayState) {
|
|
+ ALOGD("Display state not found");
|
|
+ invokeScreenCaptureError(NO_MEMORY, captureListener);
|
|
+ }
|
|
|
|
- const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) {
|
|
- return isHdrLayer(*(layer.second->mSnapshot.get()));
|
|
- });
|
|
+ const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) {
|
|
+ return isHdrLayer(*(layer.second->mSnapshot.get()));
|
|
+ });
|
|
|
|
- const bool supportsProtected = getRenderEngine().supportsProtectedContent();
|
|
- bool hasProtectedLayer = false;
|
|
- if (allowProtected && supportsProtected) {
|
|
- hasProtectedLayer = layersHasProtectedLayer(layers);
|
|
- }
|
|
- const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
|
|
- const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
|
|
- GRALLOC_USAGE_HW_TEXTURE |
|
|
- (isProtected ? GRALLOC_USAGE_PROTECTED
|
|
- : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
|
- sp<GraphicBuffer> buffer =
|
|
- getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
|
|
- static_cast<android_pixel_format>(reqPixelFormat),
|
|
- 1 /* layerCount */, usage, "screenshot");
|
|
-
|
|
- const status_t bufferStatus = buffer->initCheck();
|
|
- if (bufferStatus != OK) {
|
|
- // Animations may end up being really janky, but don't crash here.
|
|
- // Otherwise an irreponsible process may cause an SF crash by allocating
|
|
- // too much.
|
|
- ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
|
|
- invokeScreenCaptureError(bufferStatus, captureListener);
|
|
- return;
|
|
- }
|
|
- const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
|
|
- renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
|
|
- renderengine::impl::ExternalTexture::Usage::
|
|
- WRITEABLE);
|
|
-
|
|
- std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture;
|
|
- std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture;
|
|
-
|
|
- if (hasHdrLayer && !args.seamlessTransition &&
|
|
- FlagManager::getInstance().true_hdr_screenshots()) {
|
|
- const auto hdrBuffer =
|
|
- getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
|
|
- HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */,
|
|
- buffer->getUsage(), "screenshot-hdr");
|
|
- const auto gainmapBuffer =
|
|
- getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
|
|
- buffer->getPixelFormat(), 1 /* layerCount */,
|
|
- buffer->getUsage(), "screenshot-gainmap");
|
|
-
|
|
- const status_t hdrBufferStatus = hdrBuffer->initCheck();
|
|
- const status_t gainmapBufferStatus = gainmapBuffer->initCheck();
|
|
-
|
|
- if (hdrBufferStatus != OK || gainmapBufferStatus != -OK) {
|
|
- if (hdrBufferStatus != OK) {
|
|
- ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.",
|
|
- __func__, hdrBufferStatus);
|
|
+ const bool supportsProtected = getRenderEngine().supportsProtectedContent();
|
|
+ bool hasProtectedLayer = false;
|
|
+ if (allowProtected && supportsProtected) {
|
|
+ hasProtectedLayer = layersHasProtectedLayer(layers);
|
|
+ }
|
|
+ const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
|
|
+ const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
|
|
+ GRALLOC_USAGE_HW_TEXTURE |
|
|
+ (isProtected ? GRALLOC_USAGE_PROTECTED
|
|
+ : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
|
+ sp<GraphicBuffer> buffer =
|
|
+ getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
|
|
+ static_cast<android_pixel_format>(reqPixelFormat),
|
|
+ 1 /* layerCount */, usage, "screenshot");
|
|
+
|
|
+ const status_t bufferStatus = buffer->initCheck();
|
|
+ if (bufferStatus != OK) {
|
|
+ // Animations may end up being really janky, but don't crash here.
|
|
+ // Otherwise an irreponsible process may cause an SF crash by allocating
|
|
+ // too much.
|
|
+ ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
|
|
+ invokeScreenCaptureError(bufferStatus, captureListener);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
|
|
+ renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
|
|
+ renderengine::impl::ExternalTexture::Usage::
|
|
+ WRITEABLE);
|
|
+
|
|
+ std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture;
|
|
+ std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture;
|
|
+
|
|
+ if (hasHdrLayer && !args.seamlessTransition &&
|
|
+ FlagManager::getInstance().true_hdr_screenshots()) {
|
|
+ const auto hdrBuffer =
|
|
+ getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
|
|
+ HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */,
|
|
+ buffer->getUsage(), "screenshot-hdr");
|
|
+ const auto gainmapBuffer =
|
|
+ getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
|
|
+ buffer->getPixelFormat(), 1 /* layerCount */,
|
|
+ buffer->getUsage(), "screenshot-gainmap");
|
|
+
|
|
+ const status_t hdrBufferStatus = hdrBuffer->initCheck();
|
|
+ const status_t gainmapBufferStatus = gainmapBuffer->initCheck();
|
|
+
|
|
+ if (hdrBufferStatus != OK || gainmapBufferStatus != -OK) {
|
|
+ if (hdrBufferStatus != OK) {
|
|
+ ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.",
|
|
+ __func__, hdrBufferStatus);
|
|
+ } else {
|
|
+ ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.",
|
|
+ __func__, gainmapBufferStatus);
|
|
+ }
|
|
} else {
|
|
- ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.",
|
|
- __func__, gainmapBufferStatus);
|
|
+ hdrTexture = std::make_shared<
|
|
+ renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(),
|
|
+ renderengine::impl::ExternalTexture::
|
|
+ Usage::WRITEABLE);
|
|
+ gainmapTexture = std::make_shared<
|
|
+ renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(),
|
|
+ renderengine::impl::ExternalTexture::
|
|
+ Usage::WRITEABLE);
|
|
}
|
|
- } else {
|
|
- hdrTexture = std::make_shared<
|
|
- renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(),
|
|
- renderengine::impl::ExternalTexture::
|
|
- Usage::WRITEABLE);
|
|
- gainmapTexture = std::make_shared<
|
|
- renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(),
|
|
- renderengine::impl::ExternalTexture::
|
|
- Usage::WRITEABLE);
|
|
}
|
|
- }
|
|
|
|
- auto futureFence =
|
|
- captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected,
|
|
- captureListener, layers, hdrTexture, gainmapTexture);
|
|
- futureFence.get();
|
|
+ auto futureFence =
|
|
+ captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected,
|
|
+ captureListener, layers, hdrTexture, gainmapTexture);
|
|
+ futureFence.get();
|
|
+ } else {
|
|
+ const bool supportsProtected = getRenderEngine().supportsProtectedContent();
|
|
+ bool hasProtectedLayer = false;
|
|
+ if (allowProtected && supportsProtected) {
|
|
+ auto layers = mScheduler->schedule([=]() { return getLayerSnapshotsFn(); }).get();
|
|
+ hasProtectedLayer = layersHasProtectedLayer(layers);
|
|
+ }
|
|
+ const bool isProtected = hasProtectedLayer && allowProtected && supportsProtected;
|
|
+ const uint32_t usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER |
|
|
+ GRALLOC_USAGE_HW_TEXTURE |
|
|
+ (isProtected ? GRALLOC_USAGE_PROTECTED
|
|
+ : GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
|
|
+ sp<GraphicBuffer> buffer =
|
|
+ getFactory().createGraphicBuffer(bufferSize.getWidth(), bufferSize.getHeight(),
|
|
+ static_cast<android_pixel_format>(reqPixelFormat),
|
|
+ 1 /* layerCount */, usage, "screenshot");
|
|
+
|
|
+ const status_t bufferStatus = buffer->initCheck();
|
|
+ if (bufferStatus != OK) {
|
|
+ // Animations may end up being really janky, but don't crash here.
|
|
+ // Otherwise an irreponsible process may cause an SF crash by allocating
|
|
+ // too much.
|
|
+ ALOGE("%s: Buffer failed to allocate: %d", __func__, bufferStatus);
|
|
+ invokeScreenCaptureError(bufferStatus, captureListener);
|
|
+ return;
|
|
+ }
|
|
+ const std::shared_ptr<renderengine::ExternalTexture> texture = std::make_shared<
|
|
+ renderengine::impl::ExternalTexture>(buffer, getRenderEngine(),
|
|
+ renderengine::impl::ExternalTexture::Usage::
|
|
+ WRITEABLE);
|
|
+ auto futureFence = captureScreenshotLegacy(args, getLayerSnapshotsFn, texture,
|
|
+ false /* regionSampling */, grayscale,
|
|
+ isProtected, false, captureListener);
|
|
+ futureFence.get();
|
|
+ }
|
|
}
|
|
|
|
// Returns true if display is found and args was populated with display state
|
|
@@ -7854,7 +7891,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
|
|
if (hdrBuffer && gainmapBuffer) {
|
|
ftl::SharedFuture<FenceResult> hdrRenderFuture =
|
|
renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected,
|
|
- captureResults, layers);
|
|
+ true, captureResults, layers);
|
|
captureResults.buffer = buffer->getBuffer();
|
|
captureResults.optionalGainMap = gainmapBuffer->getBuffer();
|
|
|
|
@@ -7876,7 +7913,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
|
|
.share();
|
|
} else {
|
|
renderFuture = renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected,
|
|
- captureResults, layers);
|
|
+ false, captureResults, layers);
|
|
}
|
|
|
|
if (captureListener) {
|
|
@@ -7894,10 +7931,54 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
|
|
return renderFuture;
|
|
}
|
|
|
|
+ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy(
|
|
+ ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn,
|
|
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
|
|
+ bool grayscale, bool isProtected, bool attachGainmap,
|
|
+ const sp<IScreenCaptureListener>& captureListener) {
|
|
+ SFTRACE_CALL();
|
|
+
|
|
+ auto takeScreenshotFn = [=, this, args = std::move(args)]() REQUIRES(
|
|
+ kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
|
|
+ auto layers = getLayerSnapshotsFn();
|
|
+
|
|
+ ScreenCaptureResults captureResults;
|
|
+
|
|
+ ftl::SharedFuture<FenceResult> renderFuture =
|
|
+ renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected,
|
|
+ attachGainmap, captureResults, layers);
|
|
+
|
|
+ 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;
|
|
+ };
|
|
+
|
|
+ // TODO(b/294936197): Run takeScreenshotsFn() in a binder thread to reduce the number
|
|
+ // of calls on the main thread.
|
|
+ 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) {
|
|
+ return future;
|
|
+ });
|
|
+
|
|
+ return chain.share();
|
|
+}
|
|
+
|
|
ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
|
|
ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
|
|
- bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults,
|
|
- const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
|
|
+ bool regionSampling, bool grayscale, bool isProtected, bool attachGainmap,
|
|
+ ScreenCaptureResults& captureResults, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
|
|
SFTRACE_CALL();
|
|
|
|
for (auto& [_, layerFE] : layers) {
|
|
@@ -8038,9 +8119,15 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
|
|
//
|
|
// TODO(b/196334700) Once we use RenderEngineThreaded everywhere we can always defer the call
|
|
// to CompositionEngine::present.
|
|
- ftl::SharedFuture<FenceResult> presentFuture = mRenderEngine->isThreaded()
|
|
- ? ftl::yield(present()).share()
|
|
- : mScheduler->schedule(std::move(present)).share();
|
|
+ ftl::SharedFuture<FenceResult> presentFuture;
|
|
+ if (FlagManager::getInstance().single_hop_screenshot()) {
|
|
+ presentFuture = mRenderEngine->isThreaded()
|
|
+ ? ftl::yield(present()).share()
|
|
+ : mScheduler->schedule(std::move(present)).share();
|
|
+ } else {
|
|
+ presentFuture = mRenderEngine->isThreaded() ? ftl::defer(std::move(present)).share()
|
|
+ : ftl::yield(present()).share();
|
|
+ }
|
|
|
|
return presentFuture;
|
|
}
|
|
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
|
|
index f0298079a0..88c1701998 100644
|
|
--- a/services/surfaceflinger/SurfaceFlinger.h
|
|
+++ b/services/surfaceflinger/SurfaceFlinger.h
|
|
@@ -943,10 +943,16 @@ private:
|
|
const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer = nullptr,
|
|
const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer = nullptr);
|
|
|
|
+ ftl::SharedFuture<FenceResult> captureScreenshotLegacy(
|
|
+ ScreenshotArgs& args, GetLayerSnapshotsFunction,
|
|
+ const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
|
|
+ bool grayscale, bool isProtected, bool attachGainmap,
|
|
+ const sp<IScreenCaptureListener>&);
|
|
+
|
|
ftl::SharedFuture<FenceResult> renderScreenImpl(
|
|
ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>&,
|
|
- bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults&,
|
|
- const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers);
|
|
+ bool regionSampling, bool grayscale, bool isProtected, bool attachGainmap,
|
|
+ ScreenCaptureResults&, const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers);
|
|
|
|
void readPersistentProperties();
|
|
|
|
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
|
|
index ebf451501d..6f3a58f6ff 100644
|
|
--- a/services/surfaceflinger/common/FlagManager.cpp
|
|
+++ b/services/surfaceflinger/common/FlagManager.cpp
|
|
@@ -172,6 +172,7 @@ void FlagManager::dump(std::string& result) const {
|
|
DUMP_ACONFIG_FLAG(reject_dupe_layerstacks);
|
|
DUMP_ACONFIG_FLAG(renderable_buffer_usage);
|
|
DUMP_ACONFIG_FLAG(restore_blur_step);
|
|
+ DUMP_ACONFIG_FLAG(single_hop_screenshot);
|
|
DUMP_ACONFIG_FLAG(skip_invisible_windows_in_input);
|
|
DUMP_ACONFIG_FLAG(stable_edid_ids);
|
|
DUMP_ACONFIG_FLAG(synced_resolution_switch);
|
|
@@ -290,6 +291,7 @@ FLAG_MANAGER_ACONFIG_FLAG(local_tonemap_screenshots, "debug.sf.local_tonemap_scr
|
|
FLAG_MANAGER_ACONFIG_FLAG(override_trusted_overlay, "");
|
|
FLAG_MANAGER_ACONFIG_FLAG(flush_buffer_slots_to_uncache, "");
|
|
FLAG_MANAGER_ACONFIG_FLAG(force_compile_graphite_renderengine, "");
|
|
+FLAG_MANAGER_ACONFIG_FLAG(single_hop_screenshot, "");
|
|
FLAG_MANAGER_ACONFIG_FLAG(true_hdr_screenshots, "debug.sf.true_hdr_screenshots");
|
|
FLAG_MANAGER_ACONFIG_FLAG(display_config_error_hal, "");
|
|
FLAG_MANAGER_ACONFIG_FLAG(connected_display_hdr, "debug.sf.connected_display_hdr");
|
|
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
|
|
index 72b3bc302a..23232c381f 100644
|
|
--- a/services/surfaceflinger/common/include/common/FlagManager.h
|
|
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
|
|
@@ -107,6 +107,7 @@ public:
|
|
bool reject_dupe_layerstacks() const;
|
|
bool renderable_buffer_usage() const;
|
|
bool restore_blur_step() const;
|
|
+ bool single_hop_screenshot() const;
|
|
bool skip_invisible_windows_in_input() const;
|
|
bool stable_edid_ids() const;
|
|
bool synced_resolution_switch() const;
|
|
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
|
|
index 13c32bdf08..7e519d3842 100644
|
|
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
|
|
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
|
|
@@ -494,7 +494,7 @@ public:
|
|
|
|
return mFlinger->renderScreenImpl(screenshotArgs, buffer, regionSampling,
|
|
false /* grayscale */, false /* isProtected */,
|
|
- captureResults, layers);
|
|
+ false /*attachGainmap */, captureResults, layers);
|
|
}
|
|
|
|
auto getLayerSnapshotsForScreenshotsFn(ui::LayerStack layerStack, uint32_t uid) {
|
|
--
|
|
2.48.1
|
|
|