Loading libs/hwui/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ cc_defaults { target: { android: { shared_libs: [ "android.hardware.graphics.common-V3-ndk", "android.hardware.graphics.common@1.2", "liblog", "libcutils", "libutils", Loading @@ -126,9 +128,11 @@ cc_defaults { static_libs: [ "libEGL_blobCache", "libprotoutil", "libshaders", "libstatslog_hwui", "libstatspull_lazy", "libstatssocket_lazy", "libtonemap", ], }, host: { Loading libs/hwui/DeferredLayerUpdater.cpp +23 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,11 @@ // TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead. #include <surfacetexture/surface_texture_platform.h> #include "AutoBackendTextureRelease.h" #include "Matrix.h" #include "Properties.h" #include "android/hdr_metadata.h" #include "renderstate/RenderState.h" #include "renderthread/EglManager.h" #include "renderthread/RenderThread.h" Loading Loading @@ -147,6 +149,9 @@ void DeferredLayerUpdater::apply() { mUpdateTexImage = false; float transformMatrix[16]; android_dataspace dataspace; AHdrMetadataType hdrMetadataType; android_cta861_3_metadata cta861_3; android_smpte2086_metadata smpte2086; int slot; bool newContent = false; ARect currentCrop; Loading @@ -155,8 +160,9 @@ void DeferredLayerUpdater::apply() { // is necessary if the SurfaceTexture queue is in synchronous mode, and we // cannot tell which mode it is in. AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer( mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &outTransform, &newContent, createReleaseFence, fenceWait, this, ¤tCrop); mSurfaceTexture.get(), &slot, &dataspace, &hdrMetadataType, &cta861_3, &smpte2086, transformMatrix, &outTransform, &newContent, createReleaseFence, fenceWait, this, ¤tCrop); if (hardwareBuffer) { mCurrentSlot = slot; Loading @@ -173,7 +179,18 @@ void DeferredLayerUpdater::apply() { SkRect currentCropRect = SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right, currentCrop.bottom); updateLayer(forceFilter, layerImage, outTransform, currentCropRect); float maxLuminanceNits = -1.f; if (hdrMetadataType & HDR10_SMPTE2086) { maxLuminanceNits = std::max(smpte2086.maxLuminance, maxLuminanceNits); } if (hdrMetadataType & HDR10_CTA861_3) { maxLuminanceNits = std::max(cta861_3.maxContentLightLevel, maxLuminanceNits); } updateLayer(forceFilter, layerImage, outTransform, currentCropRect, maxLuminanceNits); } } } Loading @@ -186,13 +203,15 @@ void DeferredLayerUpdater::apply() { } void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform, SkRect currentCrop) { const uint32_t transform, SkRect currentCrop, float maxLuminanceNits) { mLayer->setBlend(mBlend); mLayer->setForceFilter(forceFilter); mLayer->setSize(mWidth, mHeight); mLayer->setCurrentCropRect(currentCrop); mLayer->setWindowTransform(transform); mLayer->setImage(layerImage); mLayer->setMaxLuminanceNits(maxLuminanceNits); } void DeferredLayerUpdater::detachSurfaceTexture() { Loading libs/hwui/DeferredLayerUpdater.h +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ public: void detachSurfaceTexture(); void updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform, SkRect currentCrop); SkRect currentCrop, float maxLuminanceNits = -1.f); void destroyLayer(); Loading libs/hwui/Layer.h +11 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ public: inline sk_sp<SkImage> getImage() const { return this->layerImage; } inline void setMaxLuminanceNits(float maxLuminanceNits) { mMaxLuminanceNits = maxLuminanceNits; } inline float getMaxLuminanceNits() { return mMaxLuminanceNits; } void draw(SkCanvas* canvas); protected: Loading Loading @@ -158,6 +164,11 @@ private: */ bool mBlend = false; /** * Max input luminance if the layer is HDR */ float mMaxLuminanceNits = -1; }; // struct Layer } // namespace uirenderer Loading libs/hwui/pipeline/skia/LayerDrawable.cpp +60 −2 Original line number Diff line number Diff line Loading @@ -15,12 +15,19 @@ */ #include "LayerDrawable.h" #include <shaders/shaders.h> #include <utils/Color.h> #include <utils/MathUtils.h> #include "DeviceInfo.h" #include "GrBackendSurface.h" #include "SkColorFilter.h" #include "SkRuntimeEffect.h" #include "SkSurface.h" #include "gl/GrGLTypes.h" #include "math/mat4.h" #include "system/graphics-base-v1.0.h" #include "system/window.h" namespace android { Loading Loading @@ -69,6 +76,35 @@ static bool shouldFilterRect(const SkMatrix& matrix, const SkRect& srcRect, cons isIntegerAligned(dstDevRect.y())); } static sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader, const shaders::LinearEffect& linearEffect, float maxDisplayLuminance, float maxLuminance) { auto shaderString = SkString(shaders::buildLinearEffectSkSL(linearEffect)); auto [runtimeEffect, error] = SkRuntimeEffect::MakeForShader(std::move(shaderString)); if (!runtimeEffect) { LOG_ALWAYS_FATAL("LinearColorFilter construction error: %s", error.c_str()); } SkRuntimeShaderBuilder effectBuilder(std::move(runtimeEffect)); effectBuilder.child("child") = std::move(shader); const auto uniforms = shaders::buildLinearEffectUniforms(linearEffect, mat4(), maxDisplayLuminance, maxLuminance); for (const auto& uniform : uniforms) { effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size()); } return effectBuilder.makeShader(nullptr, false); } static bool isHdrDataspace(ui::Dataspace dataspace) { const auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK; return transfer == HAL_DATASPACE_TRANSFER_ST2084 || transfer == HAL_DATASPACE_TRANSFER_HLG; } // TODO: Context arg probably doesn't belong here – do debug check at callsite instead. bool LayerDrawable::DrawLayer(GrRecordingContext* context, SkCanvas* canvas, Loading Loading @@ -150,8 +186,30 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, sampling = SkSamplingOptions(SkFilterMode::kLinear); } const auto sourceDataspace = static_cast<ui::Dataspace>( ColorSpaceToADataSpace(layerImage->colorSpace(), layerImage->colorType())); const SkImageInfo& imageInfo = canvas->imageInfo(); const auto destinationDataspace = static_cast<ui::Dataspace>( ColorSpaceToADataSpace(imageInfo.colorSpace(), imageInfo.colorType())); if (isHdrDataspace(sourceDataspace) || isHdrDataspace(destinationDataspace)) { const auto effect = shaders::LinearEffect{ .inputDataspace = sourceDataspace, .outputDataspace = destinationDataspace, .undoPremultipliedAlpha = layerImage->alphaType() == kPremul_SkAlphaType, .fakeInputDataspace = destinationDataspace}; auto shader = layerImage->makeShader(sampling, SkMatrix::RectToRect(skiaSrcRect, skiaDestRect)); constexpr float kMaxDisplayBrightess = 1000.f; shader = createLinearEffectShader(std::move(shader), effect, kMaxDisplayBrightess, layer->getMaxLuminanceNits()); paint.setShader(shader); canvas->drawRect(skiaDestRect, paint); } else { canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint, constraint); } canvas->restore(); // restore the original matrix if (useLayerTransform) { Loading Loading
libs/hwui/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ cc_defaults { target: { android: { shared_libs: [ "android.hardware.graphics.common-V3-ndk", "android.hardware.graphics.common@1.2", "liblog", "libcutils", "libutils", Loading @@ -126,9 +128,11 @@ cc_defaults { static_libs: [ "libEGL_blobCache", "libprotoutil", "libshaders", "libstatslog_hwui", "libstatspull_lazy", "libstatssocket_lazy", "libtonemap", ], }, host: { Loading
libs/hwui/DeferredLayerUpdater.cpp +23 −4 Original line number Diff line number Diff line Loading @@ -20,9 +20,11 @@ // TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead. #include <surfacetexture/surface_texture_platform.h> #include "AutoBackendTextureRelease.h" #include "Matrix.h" #include "Properties.h" #include "android/hdr_metadata.h" #include "renderstate/RenderState.h" #include "renderthread/EglManager.h" #include "renderthread/RenderThread.h" Loading Loading @@ -147,6 +149,9 @@ void DeferredLayerUpdater::apply() { mUpdateTexImage = false; float transformMatrix[16]; android_dataspace dataspace; AHdrMetadataType hdrMetadataType; android_cta861_3_metadata cta861_3; android_smpte2086_metadata smpte2086; int slot; bool newContent = false; ARect currentCrop; Loading @@ -155,8 +160,9 @@ void DeferredLayerUpdater::apply() { // is necessary if the SurfaceTexture queue is in synchronous mode, and we // cannot tell which mode it is in. AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer( mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &outTransform, &newContent, createReleaseFence, fenceWait, this, ¤tCrop); mSurfaceTexture.get(), &slot, &dataspace, &hdrMetadataType, &cta861_3, &smpte2086, transformMatrix, &outTransform, &newContent, createReleaseFence, fenceWait, this, ¤tCrop); if (hardwareBuffer) { mCurrentSlot = slot; Loading @@ -173,7 +179,18 @@ void DeferredLayerUpdater::apply() { SkRect currentCropRect = SkRect::MakeLTRB(currentCrop.left, currentCrop.top, currentCrop.right, currentCrop.bottom); updateLayer(forceFilter, layerImage, outTransform, currentCropRect); float maxLuminanceNits = -1.f; if (hdrMetadataType & HDR10_SMPTE2086) { maxLuminanceNits = std::max(smpte2086.maxLuminance, maxLuminanceNits); } if (hdrMetadataType & HDR10_CTA861_3) { maxLuminanceNits = std::max(cta861_3.maxContentLightLevel, maxLuminanceNits); } updateLayer(forceFilter, layerImage, outTransform, currentCropRect, maxLuminanceNits); } } } Loading @@ -186,13 +203,15 @@ void DeferredLayerUpdater::apply() { } void DeferredLayerUpdater::updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform, SkRect currentCrop) { const uint32_t transform, SkRect currentCrop, float maxLuminanceNits) { mLayer->setBlend(mBlend); mLayer->setForceFilter(forceFilter); mLayer->setSize(mWidth, mHeight); mLayer->setCurrentCropRect(currentCrop); mLayer->setWindowTransform(transform); mLayer->setImage(layerImage); mLayer->setMaxLuminanceNits(maxLuminanceNits); } void DeferredLayerUpdater::detachSurfaceTexture() { Loading
libs/hwui/DeferredLayerUpdater.h +1 −1 Original line number Diff line number Diff line Loading @@ -91,7 +91,7 @@ public: void detachSurfaceTexture(); void updateLayer(bool forceFilter, const sk_sp<SkImage>& layerImage, const uint32_t transform, SkRect currentCrop); SkRect currentCrop, float maxLuminanceNits = -1.f); void destroyLayer(); Loading
libs/hwui/Layer.h +11 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ public: inline sk_sp<SkImage> getImage() const { return this->layerImage; } inline void setMaxLuminanceNits(float maxLuminanceNits) { mMaxLuminanceNits = maxLuminanceNits; } inline float getMaxLuminanceNits() { return mMaxLuminanceNits; } void draw(SkCanvas* canvas); protected: Loading Loading @@ -158,6 +164,11 @@ private: */ bool mBlend = false; /** * Max input luminance if the layer is HDR */ float mMaxLuminanceNits = -1; }; // struct Layer } // namespace uirenderer Loading
libs/hwui/pipeline/skia/LayerDrawable.cpp +60 −2 Original line number Diff line number Diff line Loading @@ -15,12 +15,19 @@ */ #include "LayerDrawable.h" #include <shaders/shaders.h> #include <utils/Color.h> #include <utils/MathUtils.h> #include "DeviceInfo.h" #include "GrBackendSurface.h" #include "SkColorFilter.h" #include "SkRuntimeEffect.h" #include "SkSurface.h" #include "gl/GrGLTypes.h" #include "math/mat4.h" #include "system/graphics-base-v1.0.h" #include "system/window.h" namespace android { Loading Loading @@ -69,6 +76,35 @@ static bool shouldFilterRect(const SkMatrix& matrix, const SkRect& srcRect, cons isIntegerAligned(dstDevRect.y())); } static sk_sp<SkShader> createLinearEffectShader(sk_sp<SkShader> shader, const shaders::LinearEffect& linearEffect, float maxDisplayLuminance, float maxLuminance) { auto shaderString = SkString(shaders::buildLinearEffectSkSL(linearEffect)); auto [runtimeEffect, error] = SkRuntimeEffect::MakeForShader(std::move(shaderString)); if (!runtimeEffect) { LOG_ALWAYS_FATAL("LinearColorFilter construction error: %s", error.c_str()); } SkRuntimeShaderBuilder effectBuilder(std::move(runtimeEffect)); effectBuilder.child("child") = std::move(shader); const auto uniforms = shaders::buildLinearEffectUniforms(linearEffect, mat4(), maxDisplayLuminance, maxLuminance); for (const auto& uniform : uniforms) { effectBuilder.uniform(uniform.name.c_str()).set(uniform.value.data(), uniform.value.size()); } return effectBuilder.makeShader(nullptr, false); } static bool isHdrDataspace(ui::Dataspace dataspace) { const auto transfer = dataspace & HAL_DATASPACE_TRANSFER_MASK; return transfer == HAL_DATASPACE_TRANSFER_ST2084 || transfer == HAL_DATASPACE_TRANSFER_HLG; } // TODO: Context arg probably doesn't belong here – do debug check at callsite instead. bool LayerDrawable::DrawLayer(GrRecordingContext* context, SkCanvas* canvas, Loading Loading @@ -150,8 +186,30 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, sampling = SkSamplingOptions(SkFilterMode::kLinear); } const auto sourceDataspace = static_cast<ui::Dataspace>( ColorSpaceToADataSpace(layerImage->colorSpace(), layerImage->colorType())); const SkImageInfo& imageInfo = canvas->imageInfo(); const auto destinationDataspace = static_cast<ui::Dataspace>( ColorSpaceToADataSpace(imageInfo.colorSpace(), imageInfo.colorType())); if (isHdrDataspace(sourceDataspace) || isHdrDataspace(destinationDataspace)) { const auto effect = shaders::LinearEffect{ .inputDataspace = sourceDataspace, .outputDataspace = destinationDataspace, .undoPremultipliedAlpha = layerImage->alphaType() == kPremul_SkAlphaType, .fakeInputDataspace = destinationDataspace}; auto shader = layerImage->makeShader(sampling, SkMatrix::RectToRect(skiaSrcRect, skiaDestRect)); constexpr float kMaxDisplayBrightess = 1000.f; shader = createLinearEffectShader(std::move(shader), effect, kMaxDisplayBrightess, layer->getMaxLuminanceNits()); paint.setShader(shader); canvas->drawRect(skiaDestRect, paint); } else { canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint, constraint); } canvas->restore(); // restore the original matrix if (useLayerTransform) { Loading