Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de3019c8 authored by Alec Mouri's avatar Alec Mouri Committed by Android (Google) Code Review
Browse files

Merge "Support capturing a gainmapped screenshot" into main

parents 25f78d0e 1b1853f9
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -40,6 +40,13 @@ status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const {
    SAFE_PARCEL(parcel->writeBool, capturedSecureLayers);
    SAFE_PARCEL(parcel->writeBool, capturedHdrLayers);
    SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(capturedDataspace));
    if (optionalGainMap != nullptr) {
        SAFE_PARCEL(parcel->writeBool, true);
        SAFE_PARCEL(parcel->write, *optionalGainMap);
    } else {
        SAFE_PARCEL(parcel->writeBool, false);
    }
    SAFE_PARCEL(parcel->writeFloat, hdrSdrRatio);
    return NO_ERROR;
}

@@ -68,6 +75,14 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) {
    uint32_t dataspace = 0;
    SAFE_PARCEL(parcel->readUint32, &dataspace);
    capturedDataspace = static_cast<ui::Dataspace>(dataspace);

    bool hasGainmap;
    SAFE_PARCEL(parcel->readBool, &hasGainmap);
    if (hasGainmap) {
        optionalGainMap = new GraphicBuffer();
        SAFE_PARCEL(parcel->read, *optionalGainMap);
    }
    SAFE_PARCEL(parcel->readFloat, &hdrSdrRatio);
    return NO_ERROR;
}

+5 −0
Original line number Diff line number Diff line
@@ -69,5 +69,10 @@ parcelable CaptureArgs {
    // exact colorspace is not an appropriate intermediate result.
    // Note that if the caller is requesting a specific dataspace, this hint does nothing.
    boolean hintForSeamlessTransition = false;

    // Allows the screenshot to attach a gainmap, which allows for a per-pixel
    // transformation of the screenshot to another luminance range, typically
    // mapping an SDR base image into HDR.
    boolean attachGainmap = false;
}
+5 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ public:
    bool capturedSecureLayers{false};
    bool capturedHdrLayers{false};
    ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB};
    // A gainmap that can be used to "lift" the screenshot into HDR
    sp<GraphicBuffer> optionalGainMap;
    // HDR/SDR ratio value that fully applies the gainmap.
    // Note that we use 1/64 epsilon offsets to eliminate precision issues
    float hdrSdrRatio{1.0f};
};

} // namespace android::gui
+1 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ filegroup {
        "skia/debug/SkiaCapture.cpp",
        "skia/debug/SkiaMemoryReporter.cpp",
        "skia/filters/BlurFilter.cpp",
        "skia/filters/GainmapFactory.cpp",
        "skia/filters/GaussianBlurFilter.cpp",
        "skia/filters/KawaseBlurDualFilter.cpp",
        "skia/filters/KawaseBlurFilter.cpp",
+23 −5
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "skia/GraphiteVkRenderEngine.h"
#include "skia/SkiaGLRenderEngine.h"
#include "threaded/RenderEngineThreaded.h"
#include "ui/GraphicTypes.h"

#include <com_android_graphics_surfaceflinger_flags.h>
#include <cutils/properties.h>
@@ -101,17 +102,34 @@ ftl::Future<FenceResult> RenderEngine::drawLayers(const DisplaySettings& display
                                                  base::unique_fd&& bufferFence) {
    const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
    std::future<FenceResult> resultFuture = resultPromise->get_future();
    updateProtectedContext(layers, buffer);
    updateProtectedContext(layers, {buffer.get()});
    drawLayersInternal(std::move(resultPromise), display, layers, buffer, std::move(bufferFence));
    return resultFuture;
}

ftl::Future<FenceResult> RenderEngine::drawGainmap(
        const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence,
        const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
        float hdrSdrRatio, ui::Dataspace dataspace,
        const std::shared_ptr<ExternalTexture>& gainmap) {
    const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
    std::future<FenceResult> resultFuture = resultPromise->get_future();
    updateProtectedContext({}, {sdr.get(), hdr.get(), gainmap.get()});
    drawGainmapInternal(std::move(resultPromise), sdr, std::move(sdrFence), hdr,
                        std::move(hdrFence), hdrSdrRatio, dataspace, gainmap);
    return resultFuture;
}

void RenderEngine::updateProtectedContext(const std::vector<LayerSettings>& layers,
                                          const std::shared_ptr<ExternalTexture>& buffer) {
                                          vector<const ExternalTexture*> buffers) {
    const bool needsProtectedContext =
            (buffer && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED)) ||
            std::any_of(layers.begin(), layers.end(), [](const LayerSettings& layer) {
                const std::shared_ptr<ExternalTexture>& buffer = layer.source.buffer.buffer;
            std::any_of(layers.begin(), layers.end(),
                        [](const LayerSettings& layer) {
                            const std::shared_ptr<ExternalTexture>& buffer =
                                    layer.source.buffer.buffer;
                            return buffer && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
                        }) ||
            std::any_of(buffers.begin(), buffers.end(), [](const ExternalTexture* buffer) {
                return buffer && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
            });
    useProtectedContext(needsProtectedContext);
Loading