From f3052cd3c87f5e778287d96fd73a7f9aff4a7b72 Mon Sep 17 00:00:00 2001 From: p30034710 Date: Wed, 3 Sep 2025 19:31:10 +0800 Subject: [PATCH] fix Moire Pattern bug of ContourDiagnal Flow Light Signed-off-by: panjiao --- include/ge_kawase_blur_shader_filter.h | 4 ++ src/ge_contour_diagonal_flow_light_shader.cpp | 32 +++++++------- src/ge_kawase_blur_shader_filter.cpp | 10 +++-- test/unittest/BUILD.gn | 4 ++ ...ontour_diagonal_flow_light_shader_test.cpp | 43 +++++++++++++++++++ 5 files changed, 75 insertions(+), 18 deletions(-) diff --git a/include/ge_kawase_blur_shader_filter.h b/include/ge_kawase_blur_shader_filter.h index 2fc3e10..44d02b5 100644 --- a/include/ge_kawase_blur_shader_filter.h +++ b/include/ge_kawase_blur_shader_filter.h @@ -48,6 +48,9 @@ public: const std::string& Type() const override; + // set noise factor + void SetFactor(float factor); + private: static Drawing::Matrix GetShaderTransform( const Drawing::Canvas* canvas, const Drawing::Rect& blurRect, float scaleW = 1.0f, float scaleH = 1.0f); @@ -82,6 +85,7 @@ private: int radius_; float blurRadius_ = 0.0f; float blurScale_ = 0.25f; + float factor_ = 1.75f; // 1.75 from experience static const std::string type_; }; diff --git a/src/ge_contour_diagonal_flow_light_shader.cpp b/src/ge_contour_diagonal_flow_light_shader.cpp index 1e52750..fcb8d4c 100755 --- a/src/ge_contour_diagonal_flow_light_shader.cpp +++ b/src/ge_contour_diagonal_flow_light_shader.cpp @@ -54,7 +54,8 @@ constexpr int XMIN_I = 0; constexpr int XMAX_I = 1; constexpr int YMIN_I = 2; constexpr int YMAX_I = 3; - +constexpr ColorType RGBA_F16 = ColorType::COLORTYPE_RGBA_F16; +constexpr bool NOT_BUDGETED = false; // shader static constexpr char FLOW_LIGHT_PROG[] = R"( uniform shader precalculationImage; @@ -585,6 +586,8 @@ static constexpr char BLEND_IMG_PROG[] = R"( uniform float weight1; uniform float weight2; uniform float blurRadius; + uniform float headRoom; + float DecodeFloat(vec2 rg) { return rg.x + rg.y / 255.0; // 255.0 = maximum value representable in 8-bit channel @@ -600,7 +603,10 @@ static constexpr char BLEND_IMG_PROG[] = R"( if (precalculationImage.eval(fragCoord).a < 0.5) { // 0.5: discard the transparent pixels contourWeight = 0.0; } - return c1 + c2 * weight2 * weight2 / (totalWeight * weight1) * contourWeight; + vec4 blendColor = c1 + c2 * weight2 * weight2 / (totalWeight * weight1) * contourWeight; + vec4 lnValue = log(blendColor + vec4(1.0, 1.0, 1.0, 1.0)); + vec4 c_out = max(2.0, headRoom) * 2.0 * lnValue / (lnValue + 1); + return vec4(c_out.rgb, clamp(c_out.a, 0.0, 1.0)); } )"; @@ -664,6 +670,7 @@ GEContourDiagonalFlowLightShader::GEContourDiagonalFlowLightShader(GEContentDiag contourDiagonalFlowLightParams_ = param; Drawing::GEKawaseBlurShaderFilterParams blurParas{contourDiagonalFlowLightParams_.radius_}; blurShader_ = std::make_shared(blurParas); + blurShader_->SetFactor(0.0f); // Set zero noise } std::shared_ptr GEContourDiagonalFlowLightShader::CreateFlowLightShader( @@ -1009,8 +1016,7 @@ std::shared_ptr GEContourDiagonalFlowLightShader::DrawRuntimeSha std::clamp(contourDiagonalFlowLightParams_.line2Color_[NUM1], 0.0f, 1.0f), std::clamp(contourDiagonalFlowLightParams_.line2Color_[NUM2], 0.0f, 1.0f)); builder_->SetUniform("lineThickness", std::clamp(contourDiagonalFlowLightParams_.thickness_, 0.0f, 1.0f)); - Drawing::ImageInfo imageInfo(rect.GetWidth(), rect.GetHeight(), - Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_OPAQUE); + Drawing::ImageInfo imageInfo(rect.GetWidth(), rect.GetHeight(), RGBA_F16, Drawing::AlphaType::ALPHATYPE_OPAQUE); auto img = builder_->MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); return img; } @@ -1116,12 +1122,12 @@ void GEContourDiagonalFlowLightShader::ConvertImg(Drawing::Canvas& canvas, const void GEContourDiagonalFlowLightShader::CreateSurfaceAndCanvas(Drawing::Canvas& canvas, const Drawing::Rect& rect) { - auto surface = canvas.GetSurface(); - if (surface == nullptr) { - GE_LOGE("GEContourDiagonalFlowLightShader::ProcessImage surface is invalid"); + if (!rect.IsValid()) { + GE_LOGE("GEContourDiagonalFlowLightShader::CreateSurfaceAndCanvas rect is invalid."); return; } - offscreenSurface_ = surface->MakeSurface(rect.GetWidth(), rect.GetHeight()); + Drawing::ImageInfo imageInfo(rect.GetWidth(), rect.GetHeight(), RGBA_F16, Drawing::AlphaType::ALPHATYPE_OPAQUE); + offscreenSurface_ = Drawing::Surface::MakeRenderTarget(canvas.GetGPUContext().get(), NOT_BUDGETED, imageInfo); if (offscreenSurface_ == nullptr) { GE_LOGE("GEContourDiagonalFlowLightShader::ProcessImage offscreenSurface is invalid"); return; @@ -1129,7 +1135,6 @@ void GEContourDiagonalFlowLightShader::CreateSurfaceAndCanvas(Drawing::Canvas& c offscreenCanvas_ = offscreenSurface_->GetCanvas(); if (offscreenCanvas_ == nullptr) { GE_LOGE("GEContourDiagonalFlowLightShader::ProcessImage offscreenCanvas is invalid"); - return; } } @@ -1140,12 +1145,8 @@ std::shared_ptr GEContourDiagonalFlowLightShader::CreateImg(Draw GE_LOGE("GEContourDiagonalFlowLightShader::CreateImg rect is invalid"); return nullptr; } - auto surface = canvas.GetSurface(); - if (surface == nullptr) { - GE_LOGE("GEContourDiagonalFlowLightShader::CreateImg surface is invalid"); - return nullptr; - } - auto offscreenSurface = surface->MakeSurface(rect.GetWidth(), rect.GetHeight()); + Drawing::ImageInfo imageInfo(rect.GetWidth(), rect.GetHeight(), RGBA_F16, Drawing::AlphaType::ALPHATYPE_OPAQUE); + auto offscreenSurface = Drawing::Surface::MakeRenderTarget(canvas.GetGPUContext().get(), NOT_BUDGETED, imageInfo); if (offscreenSurface == nullptr) { GE_LOGE("GEContourDiagonalFlowLightShader::CreateImg offscreenSurface is invalid"); return nullptr; @@ -1231,6 +1232,7 @@ std::shared_ptr GEContourDiagonalFlowLightShader::BlendImg(Drawi blendBuilder->SetUniform("weight1", contourDiagonalFlowLightParams_.weight1); blendBuilder->SetUniform("weight2", contourDiagonalFlowLightParams_.weight2); blendBuilder->SetUniform("blurRadius", contourDiagonalFlowLightParams_.radius_); + blendBuilder->SetUniform("headRoom", std::max(supportHeadroom_, 1.0f)); auto imageInfo = img1->GetImageInfo(); return blendBuilder->MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false); } diff --git a/src/ge_kawase_blur_shader_filter.cpp b/src/ge_kawase_blur_shader_filter.cpp index 3832ca2..78acadc 100644 --- a/src/ge_kawase_blur_shader_filter.cpp +++ b/src/ge_kawase_blur_shader_filter.cpp @@ -501,9 +501,8 @@ std::shared_ptr GEKawaseBlurShaderFilter::ScaleAndAddRandomColor float mixFactor = (abs(MAX_CROSS_FADE_RADIUS) <= 1e-6) ? 1.f : (blurRadius_ / MAX_CROSS_FADE_RADIUS); mixBuilder.SetUniform("mixFactor", std::min(1.0f, mixFactor)); - static auto factor = 1.75; // 1.75 from experience - mixBuilder.SetUniform("inColorFactor", factor); - LOGD("GEKawaseBlurShaderFilter::kawase random color factor : %{public}f", factor); + mixBuilder.SetUniform("inColorFactor", factor_); + LOGD("GEKawaseBlurShaderFilter::kawase random color factor : %{public}f", factor_); auto scaledInfo = Drawing::ImageInfo(width, height, blurImage->GetImageInfo().GetColorType(), blurImage->GetImageInfo().GetAlphaType(), blurImage->GetImageInfo().GetColorSpace()); @@ -515,6 +514,11 @@ std::shared_ptr GEKawaseBlurShaderFilter::ScaleAndAddRandomColor return output; } +void GEKawaseBlurShaderFilter::SetFactor(float factor) +{ + factor_ = std::max(0.0f, factor); +} + void GEKawaseBlurShaderFilter::ComputeRadiusAndScale(int radius) { static constexpr int noiseFactor = 3; // 3 : smooth the radius change diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 04c5dcd..54e7734 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -180,6 +180,10 @@ ohos_unittest("GraphicsEffectTest") { "c_utils:utils", "graphic_2d:2d_graphics", "hilog:libhilog", + "graphic_surface:surface", + "egl:libEGL", + "opengles:libGLES", + "graphic_2d:librender_service_base", ] part_name = "graphics_effect" diff --git a/test/unittest/ge_contour_diagonal_flow_light_shader_test.cpp b/test/unittest/ge_contour_diagonal_flow_light_shader_test.cpp index 88b289d..f8b52f4 100644 --- a/test/unittest/ge_contour_diagonal_flow_light_shader_test.cpp +++ b/test/unittest/ge_contour_diagonal_flow_light_shader_test.cpp @@ -22,6 +22,7 @@ #include "draw/color.h" #include "draw/path.h" #include "ge_shader_filter_params.h" +#include "render_context/render_context.h" using namespace testing; using namespace testing::ext; @@ -106,6 +107,48 @@ HWTEST_F(GEContourDiagonalFlowLightShaderTest, MakeDrawingShader_001, TestSize.L EXPECT_EQ(shader->GetDrawingShader(), nullptr); // no cache } +HWTEST_F(GEContourDiagonalFlowLightShaderTest, CreateSurfaceAndCanvas_001, TestSize.Level1) +{ + // Test case for MakeDrawingShader method + Drawing::Rect rect(0, 0, 100, 100); + GEContentDiagonalFlowLightShaderParams params{}; + auto shader = GEContourDiagonalFlowLightShader::CreateFlowLightShader(params); + shader->CreateSurfaceAndCanvas(canvas_, Drawing::Rect{0.0f, 0.0f, 0.0f, 0.0f}); + canvas_.gpuContext_ = nullptr; + shader->CreateSurfaceAndCanvas(canvas_, rect); + + auto renderContext = std::make_shared(); + renderContext->InitializeEglContext(); + renderContext->SetUpGpuContext(); + canvas_.gpuContext_ = renderContext->GetSharedDrGPUContext(); + + shader->CreateSurfaceAndCanvas(canvas_, rect); + EXPECT_NE(shader->offscreenSurface_, nullptr); + canvas_.gpuContext_ = nullptr; +} + +HWTEST_F(GEContourDiagonalFlowLightShaderTest, CreateImg_001, TestSize.Level1) +{ + // Test case for MakeDrawingShader method + Drawing::Rect rect(0, 0, 100, 100); + GEContentDiagonalFlowLightShaderParams params{}; + auto shader = GEContourDiagonalFlowLightShader::CreateFlowLightShader(params); + auto img = shader->CreateImg(canvas_, Drawing::Rect{0.0f, 0.0f, 0.0f, 0.0f}); + EXPECT_EQ(img, nullptr); + canvas_.gpuContext_ = nullptr; + img = shader->CreateImg(canvas_, rect); + EXPECT_EQ(img, nullptr); + + auto renderContext = std::make_shared(); + renderContext->InitializeEglContext(); + renderContext->SetUpGpuContext(); + canvas_.gpuContext_ = renderContext->GetSharedDrGPUContext(); + + img = shader->CreateImg(canvas_, rect); + EXPECT_NE(img, nullptr); + canvas_.gpuContext_ = nullptr; +} + HWTEST_F(GEContourDiagonalFlowLightShaderTest, Preprocess_001, TestSize.Level1) { // Test case for Preprocess method -- Gitee