Loading libs/gui/LayerState.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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); Loading @@ -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; } Loading libs/gui/aidl/android/gui/ISurfaceComposer.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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); /** Loading libs/gui/include/gui/DisplayCaptureArgs.h +10 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); }; Loading libs/renderengine/skia/SkiaRenderEngine.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -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); Loading libs/shaders/shaders.cpp +39 −19 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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 Loading
libs/gui/LayerState.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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); Loading @@ -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; } Loading
libs/gui/aidl/android/gui/ISurfaceComposer.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -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); /** Loading
libs/gui/include/gui/DisplayCaptureArgs.h +10 −1 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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); }; Loading
libs/renderengine/skia/SkiaRenderEngine.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/shaders/shaders.cpp +39 −19 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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: Loading @@ -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) { Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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