diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 111 |
1 files changed, 91 insertions, 20 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0aad2828cb..7590d981d4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -7060,7 +7060,8 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args, displayWeak, options), getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), - captureArgs.allowProtected, captureArgs.grayscale, captureListener); + captureArgs.allowProtected, captureArgs.grayscale, + captureArgs.attachGainmap, captureListener); } void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args, @@ -7117,7 +7118,7 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args static_cast<ui::Dataspace>(args.dataspace), displayWeak, options), getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat), - kAllowProtected, kGrayscale, captureListener); + kAllowProtected, kGrayscale, args.attachGainmap, captureListener); } ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) { @@ -7228,7 +7229,8 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, options), getLayerSnapshotsFn, reqSize, static_cast<ui::PixelFormat>(captureArgs.pixelFormat), - captureArgs.allowProtected, captureArgs.grayscale, captureListener); + captureArgs.allowProtected, captureArgs.grayscale, + captureArgs.attachGainmap, captureListener); } // Creates a Future release fence for a layer and keeps track of it in a list to @@ -7281,7 +7283,7 @@ std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapsho void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, - bool allowProtected, bool grayscale, + bool allowProtected, bool grayscale, bool attachGainmap, const sp<IScreenCaptureListener>& captureListener) { SFTRACE_CALL(); @@ -7327,9 +7329,9 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), renderengine::impl::ExternalTexture::Usage:: WRITEABLE); - auto futureFence = - captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, grayscale, - isProtected, captureListener, displayState, layerFEs); + auto futureFence = captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */, + grayscale, isProtected, attachGainmap, captureListener, + displayState, layerFEs); futureFence.get(); } else { @@ -7364,7 +7366,7 @@ void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuil WRITEABLE); auto futureFence = captureScreenshotLegacy(renderAreaBuilder, getLayerSnapshotsFn, texture, false /* regionSampling */, grayscale, - isProtected, captureListener); + isProtected, attachGainmap, captureListener); futureFence.get(); } } @@ -7418,7 +7420,8 @@ std::vector<sp<LayerFE>> SurfaceFlinger::extractLayerFEs( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( const RenderAreaBuilderVariant& renderAreaBuilder, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener, + bool grayscale, bool isProtected, bool attachGainmap, + const sp<IScreenCaptureListener>& captureListener, std::optional<OutputCompositionState>& displayState, std::vector<sp<LayerFE>>& layerFEs) { SFTRACE_CALL(); @@ -7435,19 +7438,87 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( } return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share(); } + float displayBrightnessNits = displayState.value().displayBrightnessNits; + float sdrWhitePointNits = displayState.value().sdrWhitePointNits; // Empty vector needed to pass into renderScreenImpl for legacy path std::vector<std::pair<Layer*, sp<android::LayerFE>>> layers; ftl::SharedFuture<FenceResult> renderFuture = - renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale, isProtected, - captureResults, displayState, layers, layerFEs); + renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected, + attachGainmap, captureResults, displayState, layers, layerFEs); + + if (captureResults.capturedHdrLayers && attachGainmap && + FlagManager::getInstance().true_hdr_screenshots()) { + sp<GraphicBuffer> hdrBuffer = + getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), + HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */, + buffer->getUsage(), "screenshot-hdr"); + sp<GraphicBuffer> gainmapBuffer = + getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(), + buffer->getPixelFormat(), 1 /* layerCount */, + buffer->getUsage(), "screenshot-gainmap"); + + const status_t bufferStatus = hdrBuffer->initCheck(); + const status_t gainmapBufferStatus = gainmapBuffer->initCheck(); + + if (bufferStatus != OK) { + ALOGW("%s: Buffer failed to allocate for hdr: %d. Screenshoting SDR instead.", __func__, + bufferStatus); + } else if (gainmapBufferStatus != OK) { + ALOGW("%s: Buffer failed to allocate for gainmap: %d. Screenshoting SDR instead.", + __func__, gainmapBufferStatus); + } else { + captureResults.optionalGainMap = gainmapBuffer; + const auto hdrTexture = std::make_shared< + renderengine::impl::ExternalTexture>(hdrBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + const auto gainmapTexture = std::make_shared< + renderengine::impl::ExternalTexture>(gainmapBuffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::WRITEABLE); + ScreenCaptureResults unusedResults; + ftl::SharedFuture<FenceResult> hdrRenderFuture = + renderScreenImpl(renderArea.get(), hdrTexture, regionSampling, grayscale, + isProtected, attachGainmap, unusedResults, displayState, + layers, layerFEs); + + renderFuture = + ftl::Future(std::move(renderFuture)) + .then([&, hdrRenderFuture = std::move(hdrRenderFuture), + displayBrightnessNits, sdrWhitePointNits, + dataspace = captureResults.capturedDataspace, buffer, hdrTexture, + gainmapTexture](FenceResult fenceResult) -> FenceResult { + if (!fenceResult.ok()) { + return fenceResult; + } + + auto hdrFenceResult = hdrRenderFuture.get(); + + if (!hdrFenceResult.ok()) { + return hdrFenceResult; + } + + return getRenderEngine() + .drawGainmap(buffer, fenceResult.value()->get(), hdrTexture, + hdrFenceResult.value()->get(), + displayBrightnessNits / sdrWhitePointNits, + static_cast<ui::Dataspace>(dataspace), + gainmapTexture) + .get(); + }) + .share(); + }; + } 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 { + .then([captureListener, captureResults = std::move(captureResults), + displayBrightnessNits, + sdrWhitePointNits](FenceResult fenceResult) mutable -> FenceResult { captureResults.fenceResult = std::move(fenceResult); + captureResults.hdrSdrRatio = displayBrightnessNits / sdrWhitePointNits; captureListener->onScreenCaptureCompleted(captureResults); return base::unexpected(NO_ERROR); }) @@ -7459,7 +7530,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot( ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( RenderAreaBuilderVariant renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) { + bool grayscale, bool isProtected, bool attachGainmap, + const sp<IScreenCaptureListener>& captureListener) { SFTRACE_CALL(); auto takeScreenshotFn = [=, this, renderAreaBuilder = std::move(renderAreaBuilder)]() REQUIRES( @@ -7488,8 +7560,8 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( auto layerFEs = extractLayerFEs(layers); ftl::SharedFuture<FenceResult> renderFuture = - renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale, - isProtected, captureResults, displayState, layers, layerFEs); + renderScreenImpl(renderArea.get(), buffer, regionSampling, grayscale, isProtected, + attachGainmap, captureResults, displayState, layers, layerFEs); if (captureListener) { // Defer blocking on renderFuture back to the Binder thread. @@ -7519,10 +7591,9 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshotLegacy( } ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( - std::unique_ptr<const RenderArea> renderArea, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, bool isProtected, ScreenCaptureResults& captureResults, - std::optional<OutputCompositionState>& displayState, + const RenderArea* renderArea, const std::shared_ptr<renderengine::ExternalTexture>& buffer, + bool regionSampling, bool grayscale, bool isProtected, bool attachGainmap, + ScreenCaptureResults& captureResults, std::optional<OutputCompositionState>& displayState, std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, std::vector<sp<LayerFE>>& layerFEs) { SFTRACE_CALL(); |