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

Commit e965b80a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Rework how SF generates gainmapped screenshots" into main

parents b32db4a7 e57f9e4d
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -69,10 +69,5 @@ 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;
}
+4 −5
Original line number Diff line number Diff line
@@ -107,16 +107,15 @@ ftl::Future<FenceResult> RenderEngine::drawLayers(const DisplaySettings& display
    return resultFuture;
}

ftl::Future<FenceResult> RenderEngine::drawGainmap(
        const std::shared_ptr<ExternalTexture>& sdr, base::borrowed_fd&& sdrFence,
ftl::Future<FenceResult> RenderEngine::tonemapAndDrawGainmap(
        const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
        float hdrSdrRatio, ui::Dataspace dataspace,
        float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr,
        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);
    tonemapAndDrawGainmapInternal(std::move(resultPromise), hdr, std::move(hdrFence), hdrSdrRatio,
                                  dataspace, sdr, gainmap);
    return resultFuture;
}

+13 −9
Original line number Diff line number Diff line
@@ -217,11 +217,16 @@ public:
                                                const std::shared_ptr<ExternalTexture>& buffer,
                                                base::unique_fd&& bufferFence);

    virtual ftl::Future<FenceResult> 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,
    // Tonemaps an HDR input image and draws an SDR rendition, plus a gainmap
    // describing how to recover the HDR image.
    //
    // The HDR input image is ALWAYS encoded with an sRGB transfer function and
    // is a floating point format. Accordingly, the hdrSdrRatio describes the
    // max luminance in the HDR input image above SDR, and the dataspace
    // describes the input primaries.
    virtual ftl::Future<FenceResult> tonemapAndDrawGainmap(
            const std::shared_ptr<ExternalTexture>& hdr, base::borrowed_fd&& hdrFence,
            float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr,
            const std::shared_ptr<ExternalTexture>& gainmap);

    // Clean-up method that should be called on the main thread after the
@@ -310,11 +315,10 @@ protected:
            const DisplaySettings& display, const std::vector<LayerSettings>& layers,
            const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) = 0;

    virtual void drawGainmapInternal(
    virtual void tonemapAndDrawGainmapInternal(
            const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
            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,
            float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr,
            const std::shared_ptr<ExternalTexture>& gainmap) = 0;
};

+5 −6
Original line number Diff line number Diff line
@@ -46,17 +46,16 @@ public:
                 ftl::Future<FenceResult>(const DisplaySettings&, const std::vector<LayerSettings>&,
                                          const std::shared_ptr<ExternalTexture>&,
                                          base::unique_fd&&));
    MOCK_METHOD7(drawGainmap,
    MOCK_METHOD6(tonemapAndDrawGainmap,
                 ftl::Future<FenceResult>(const std::shared_ptr<ExternalTexture>&,
                                          base::borrowed_fd&&,
                                          const std::shared_ptr<ExternalTexture>&,
                                          base::borrowed_fd&&, float, ui::Dataspace,
                                          const std::shared_ptr<ExternalTexture>&,
                                          const std::shared_ptr<ExternalTexture>&));
    MOCK_METHOD8(drawGainmapInternal,
    MOCK_METHOD7(tonemapAndDrawGainmapInternal,
                 void(const std::shared_ptr<std::promise<FenceResult>>&&,
                      const std::shared_ptr<ExternalTexture>&, base::borrowed_fd&&,
                      const std::shared_ptr<ExternalTexture>&, base::borrowed_fd&&, float,
                      ui::Dataspace, const std::shared_ptr<ExternalTexture>&));
                      ui::Dataspace, const std::shared_ptr<ExternalTexture>&,
                      const std::shared_ptr<ExternalTexture>&));
    MOCK_METHOD5(drawLayersInternal,
                 void(const std::shared_ptr<std::promise<FenceResult>>&&, const DisplaySettings&,
                      const std::vector<LayerSettings>&, const std::shared_ptr<ExternalTexture>&,
+44 −26
Original line number Diff line number Diff line
@@ -567,9 +567,7 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader(
        if (usingLocalTonemap) {
            const float inputRatio =
                    hdrType == HdrRenderType::GENERIC_HDR ? 1.0f : parameters.layerDimmingRatio;
            static MouriMap kMapper;
            shader = kMapper.mouriMap(getActiveContext(), shader, inputRatio,
                                      parameters.display.targetHdrSdrRatio);
            shader = localTonemap(shader, inputRatio, parameters.display.targetHdrSdrRatio);
        }

        // disable tonemapping if we already locally tonemapped
@@ -610,6 +608,12 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader(
    return shader;
}

sk_sp<SkShader> SkiaRenderEngine::localTonemap(sk_sp<SkShader> shader, float inputMultiplier,
                                               float targetHdrSdrRatio) {
    static MouriMap kMapper;
    return kMapper.mouriMap(getActiveContext(), shader, inputMultiplier, targetHdrSdrRatio);
}

void SkiaRenderEngine::initCanvas(SkCanvas* canvas, const DisplaySettings& display) {
    if (CC_UNLIKELY(mCapture->isCaptureRunning())) {
        // Record display settings when capture is running.
@@ -1212,44 +1216,58 @@ void SkiaRenderEngine::drawLayersInternal(
    resultPromise->set_value(std::move(drawFence));
}

void SkiaRenderEngine::drawGainmapInternal(
void SkiaRenderEngine::tonemapAndDrawGainmapInternal(
        const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
        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,
        float hdrSdrRatio, ui::Dataspace dataspace, const std::shared_ptr<ExternalTexture>& sdr,
        const std::shared_ptr<ExternalTexture>& gainmap) {
    std::lock_guard<std::mutex> lock(mRenderingMutex);
    auto context = getActiveContext();
    auto surfaceTextureRef = getOrCreateBackendTexture(gainmap->getBuffer(), true);
    sk_sp<SkSurface> dstSurface =
            surfaceTextureRef->getOrCreateSurface(ui::Dataspace::V0_SRGB_LINEAR);

    waitFence(context, sdrFence);
    const auto sdrTextureRef = getOrCreateBackendTexture(sdr->getBuffer(), false);
    const auto sdrImage = sdrTextureRef->makeImage(dataspace, kPremul_SkAlphaType);
    const auto sdrShader =
            sdrImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
                                 SkSamplingOptions({SkFilterMode::kLinear, SkMipmapMode::kNone}),
                                 nullptr);
    auto gainmapTextureRef = getOrCreateBackendTexture(gainmap->getBuffer(), true);
    sk_sp<SkSurface> gainmapSurface =
            gainmapTextureRef->getOrCreateSurface(ui::Dataspace::V0_SRGB_LINEAR);

    auto sdrTextureRef = getOrCreateBackendTexture(sdr->getBuffer(), true);
    sk_sp<SkSurface> sdrSurface = sdrTextureRef->getOrCreateSurface(dataspace);

    waitFence(context, hdrFence);
    const auto hdrTextureRef = getOrCreateBackendTexture(hdr->getBuffer(), false);
    const auto hdrImage = hdrTextureRef->makeImage(dataspace, kPremul_SkAlphaType);
    const auto hdrShader =
            hdrImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
                                 SkSamplingOptions({SkFilterMode::kLinear, SkMipmapMode::kNone}),
                                 SkSamplingOptions({SkFilterMode::kNearest, SkMipmapMode::kNone}),
                                 nullptr);

    const auto tonemappedShader = localTonemap(hdrShader, 1.0f, 1.0f);

    static GainmapFactory kGainmapFactory;
    const auto gainmapShader = kGainmapFactory.createSkShader(sdrShader, hdrShader, hdrSdrRatio);
    const auto gainmapShader =
            kGainmapFactory.createSkShader(tonemappedShader, hdrShader, hdrSdrRatio);

    sp<Fence> drawFence;

    const auto canvas = dstSurface->getCanvas();
    {
        const auto canvas = sdrSurface->getCanvas();
        SkPaint paint;
    paint.setShader(gainmapShader);
        paint.setShader(tonemappedShader);
        paint.setBlendMode(SkBlendMode::kSrc);
        canvas->drawPaint(paint);

    auto drawFence = sp<Fence>::make(flushAndSubmit(context, dstSurface));
        drawFence = sp<Fence>::make(flushAndSubmit(context, sdrSurface));
        trace(drawFence);
    }

    {
        const auto canvas = gainmapSurface->getCanvas();
        SkPaint paint;
        paint.setShader(gainmapShader);
        paint.setBlendMode(SkBlendMode::kSrc);
        canvas->drawPaint(paint);

        auto gmFence = sp<Fence>::make(flushAndSubmit(context, gainmapSurface));
        trace(gmFence);
        drawFence = Fence::merge("gm-ss", drawFence, gmFence);
    }
    resultPromise->set_value(std::move(drawFence));
}

Loading