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

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

Merge "Support screenshots of HDR content" into udc-dev

parents 6b567cad 3e5965f3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -897,11 +897,11 @@ status_t CaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace));
    SAFE_PARCEL(output->writeBool, allowProtected);
    SAFE_PARCEL(output->writeBool, grayscale);

    SAFE_PARCEL(output->writeInt32, excludeHandles.size());
    for (auto& excludeHandle : excludeHandles) {
        SAFE_PARCEL(output->writeStrongBinder, excludeHandle);
    }
    SAFE_PARCEL(output->writeBool, hintForSeamlessTransition);
    return NO_ERROR;
}

@@ -918,7 +918,6 @@ status_t CaptureArgs::readFromParcel(const Parcel* input) {
    dataspace = static_cast<ui::Dataspace>(value);
    SAFE_PARCEL(input->readBool, &allowProtected);
    SAFE_PARCEL(input->readBool, &grayscale);

    int32_t numExcludeHandles = 0;
    SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
    excludeHandles.reserve(numExcludeHandles);
@@ -927,6 +926,7 @@ status_t CaptureArgs::readFromParcel(const Parcel* input) {
        SAFE_PARCEL(input->readStrongBinder, &binder);
        excludeHandles.emplace(binder);
    }
    SAFE_PARCEL(input->readBool, &hintForSeamlessTransition);
    return NO_ERROR;
}

+4 −0
Original line number Diff line number Diff line
@@ -230,6 +230,10 @@ interface ISurfaceComposer {
     */
    void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener);

    /**
     * Capture the specified screen. This requires the READ_FRAME_BUFFER
     * permission.
     */
    void captureDisplayById(long displayId, IScreenCaptureListener listener);

    /**
+10 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ struct CaptureArgs : public Parcelable {
    bool captureSecureLayers{false};
    int32_t uid{UNSET_UID};
    // Force capture to be in a color space. If the value is ui::Dataspace::UNKNOWN, the captured
    // result will be in the display's colorspace.
    // result will be in a colorspace appropriate for capturing the display contents
    // The display may use non-RGB dataspace (ex. displayP3) that could cause pixel data could be
    // different from SRGB (byte per color), and failed when checking colors in tests.
    // NOTE: In normal cases, we want the screen to be captured in display's colorspace.
@@ -59,6 +59,15 @@ struct CaptureArgs : public Parcelable {

    std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;

    // Hint that the caller will use the screenshot animation as part of a transition animation.
    // The canonical example would be screen rotation - in such a case any color shift in the
    // screenshot is a detractor so composition in the display's colorspace is required.
    // Otherwise, the system may choose a colorspace that is more appropriate for use-cases
    // such as file encoding or for blending HDR content into an ap's UI, where the display's
    // exact colorspace is not an appropriate intermediate result.
    // Note that if the caller is requesting a specific dataspace, this hint does nothing.
    bool hintForSeamlessTransition = false;

    virtual status_t writeToParcel(Parcel* output) const;
    virtual status_t readFromParcel(const Parcel* input);
};
+4 −2
Original line number Diff line number Diff line
@@ -517,16 +517,18 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader(
        } else {
            runtimeEffect = effectIter->second;
        }

        mat4 colorTransform = parameters.layer.colorTransform;

        colorTransform *=
                mat4::scale(vec4(parameters.layerDimmingRatio, parameters.layerDimmingRatio,
                                 parameters.layerDimmingRatio, 1.f));

        const auto targetBuffer = parameters.layer.source.buffer.buffer;
        const auto graphicBuffer = targetBuffer ? targetBuffer->getBuffer() : nullptr;
        const auto hardwareBuffer = graphicBuffer ? graphicBuffer->toAHardwareBuffer() : nullptr;
        return createLinearEffectShader(parameters.shader, effect, runtimeEffect, colorTransform,
                                        parameters.display.maxLuminance,
        return createLinearEffectShader(parameters.shader, effect, runtimeEffect,
                                        std::move(colorTransform), parameters.display.maxLuminance,
                                        parameters.display.currentLuminanceNits,
                                        parameters.layer.source.buffer.maxLuminanceNits,
                                        hardwareBuffer, parameters.display.renderIntent);
+39 −19
Original line number Diff line number Diff line
@@ -191,19 +191,22 @@ void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace, ui::Dataspace
                )");
            break;
        default:
            // Input is SDR so map to its white point luminance
            switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) {
                case HAL_DATASPACE_TRANSFER_ST2084:
                // Max HLG output is nominally 1000 nits, but BT. 2100-2 allows
                // for gamma correcting the HLG OOTF for displays with a different
                // dynamic range. Scale to 1000 nits to apply an inverse OOTF against
                // a reference display correctly.
                // TODO: Use knowledge of the dimming ratio here to prevent
                // unintended gamma shaft.
                case HAL_DATASPACE_TRANSFER_HLG:
                    // SDR -> HDR tonemap
                    shader.append(R"(
                            float3 ScaleLuminance(float3 xyz) {
                                return xyz * in_libtonemap_inputMaxLuminance;
                                return xyz * 1000.0;
                            }
                        )");
                    break;
                default:
                    // Input and output are both SDR, so no tone-mapping is expected so
                    // no-op the luminance normalization.
                    shader.append(R"(
                            float3 ScaleLuminance(float3 xyz) {
                                return xyz * in_libtonemap_displayMaxLuminance;
@@ -215,7 +218,8 @@ void generateLuminanceScalesForOOTF(ui::Dataspace inputDataspace, ui::Dataspace
}

// Normalizes from absolute light back to relative light (maps from [0, maxNits] back to [0, 1])
static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace,
static void generateLuminanceNormalizationForOOTF(ui::Dataspace inputDataspace,
                                                  ui::Dataspace outputDataspace,
                                                  std::string& shader) {
    switch (outputDataspace & HAL_DATASPACE_TRANSFER_MASK) {
        case HAL_DATASPACE_TRANSFER_ST2084:
@@ -225,6 +229,8 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace,
                    }
                )");
            break;
        case HAL_DATASPACE_TRANSFER_HLG:
            switch (inputDataspace & HAL_DATASPACE_TRANSFER_MASK) {
                case HAL_DATASPACE_TRANSFER_HLG:
                    shader.append(R"(
                            float3 NormalizeLuminance(float3 xyz) {
@@ -232,6 +238,21 @@ static void generateLuminanceNormalizationForOOTF(ui::Dataspace outputDataspace,
                            }
                        )");
                    break;
                default:
                    // Transcoding to HLG requires applying the inverse OOTF
                    // with the expectation that the OOTF is then applied during
                    // tonemapping downstream.
                    shader.append(R"(
                            float3 NormalizeLuminance(float3 xyz) {
                                // BT. 2100-2 operates on normalized luminances,
                                // so renormalize to the input
                                float ootfGain = pow(xyz.y / 1000.0, -0.2 / 1.2) / 1000.0;
                                return xyz * ootfGain;
                            }
                        )");
                    break;
            }
            break;
        default:
            shader.append(R"(
                    float3 NormalizeLuminance(float3 xyz) {
@@ -250,7 +271,7 @@ void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace,
                          .c_str());

    generateLuminanceScalesForOOTF(inputDataspace, outputDataspace, shader);
    generateLuminanceNormalizationForOOTF(outputDataspace, shader);
    generateLuminanceNormalizationForOOTF(inputDataspace, outputDataspace, shader);

    shader.append(R"(
            float3 OOTF(float3 linearRGB, float3 xyz) {
@@ -501,9 +522,8 @@ std::vector<tonemap::ShaderUniform> buildLinearEffectUniforms(

    tonemap::Metadata metadata{.displayMaxLuminance = maxDisplayLuminance,
                               // If the input luminance is unknown, use display luminance (aka,
                               // no-op any luminance changes)
                               // This will be the case for eg screenshots in addition to
                               // uncalibrated displays
                               // no-op any luminance changes).
                               // This is expected to only be meaningful for PQ content
                               .contentMaxLuminance =
                                       maxLuminance > 0 ? maxLuminance : maxDisplayLuminance,
                               .currentDisplayLuminance = currentDisplayLuminanceNits > 0
Loading