ImageVisualShaderFactory refactoring 87/299087/2
authorseungho baek <sbsh.baek@samsung.com>
Tue, 19 Sep 2023 07:36:33 +0000 (16:36 +0900)
committerseungho baek <sbsh.baek@samsung.com>
Wed, 20 Sep 2023 01:25:21 +0000 (10:25 +0900)
 ImageVisualShaderFactory::GetShader method is too long and complex.
 The method uses same logic for two different purpose in a method
 that makes difficult to understand.
 And the method also has too many braces depth.

 This patch moves some features that to create shaderType and
 to retrive shaderPreFix to ImageVisualShaderFeatureBuilder.
 Now ImageVisualShaderFeatureBuilder manages all responsibility
 to define shader codes following its options.
 And slides some codes for readability and it make possible remove
 unnecessary comments.

Change-Id: I09a725d4e101cb65badffe3a897572971e2c336b
Signed-off-by: seungho baek <sbsh.baek@samsung.com>
12 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-ImageVisualShaderFeatureBuilder.cpp [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.cpp
dali-toolkit/internal/visuals/image-visual-shader-factory.h
dali-toolkit/internal/visuals/image-visual-shader-feature-builder.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h [new file with mode: 0644]
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp

index ee58ab6..582d39c 100755 (executable)
@@ -15,6 +15,7 @@ SET(TC_SOURCES
  utc-Dali-DebugRendering.cpp
  utc-Dali-Dictionary.cpp
  utc-Dali-FeedbackStyle.cpp
+ utc-Dali-ImageVisualShaderFeatureBuilder.cpp
  utc-Dali-ItemView-internal.cpp
  utc-Dali-LineHelperFunctions.cpp
  utc-Dali-LogicalModel.cpp
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-ImageVisualShaderFeatureBuilder.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-ImageVisualShaderFeatureBuilder.cpp
new file mode 100644 (file)
index 0000000..4041450
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-event-thread-callback.h>
+#include <toolkit-text-utils.h>
+
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
+
+#include <../dali-toolkit/dali-toolkit-test-utils/dummy-control.h>
+#include <dummy-visual.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+int UtcImageVisualShaderFeatureBuilderSetGetProperty01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Register an ImageVisual and and perform an Action on Visual directly");
+  auto featureBuilder = Dali::Toolkit::Internal::ImageVisualShaderFeatureBuilder()
+                          .EnableTextureAtlas(Dali::Toolkit::Internal::ImageVisualShaderFeature::TextureAtlas::ENABLED)
+                          .ApplyDefaultTextureWrapMode(true);
+
+  std::string vertexPrefixList;
+  std::string fragmentPrefixList;
+  featureBuilder.GetVertexShaderPrefixList(vertexPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentPrefixList);
+
+  DALI_TEST_EQUALS(vertexPrefixList, std::string(""), TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefixList, std::string("#define ATLAS_DEFAULT_WARP\n"), TEST_LOCATION);
+
+  featureBuilder = featureBuilder.ApplyDefaultTextureWrapMode(false);
+
+  vertexPrefixList.clear();
+  fragmentPrefixList.clear();
+  featureBuilder.GetVertexShaderPrefixList(vertexPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentPrefixList);
+
+  DALI_TEST_EQUALS(vertexPrefixList, std::string(""), TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefixList, std::string("#define ATLAS_CUSTOM_WARP\n"), TEST_LOCATION);
+  END_TEST;
+}
+
+int UtcImageVisualShaderFeatureBuilderSetGetProperty02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Register an ImageVisual and and perform an Action on Visual directly");
+  auto featureBuilder = Dali::Toolkit::Internal::ImageVisualShaderFeatureBuilder()
+                          .EnableRoundedCorner(true)
+                          .EnableBorderline(true)
+                          .EnableAlphaMaskingOnRendering(true)
+                          .EnableYuvToRgb(true, false);
+
+  std::string vertexPrefixList;
+  std::string fragmentPrefixList;
+  featureBuilder.GetVertexShaderPrefixList(vertexPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentPrefixList);
+
+  std::string vertexPrefixListResult;
+  vertexPrefixListResult += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+  vertexPrefixListResult += "#define IS_REQUIRED_BORDERLINE\n";
+  vertexPrefixListResult += "#define IS_REQUIRED_ALPHA_MASKING\n";
+
+  std::string fragmentPrefixListResult;
+  fragmentPrefixListResult += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_BORDERLINE\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_ALPHA_MASKING\n";
+
+  DALI_TEST_EQUALS(vertexPrefixList, vertexPrefixListResult, TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefixList, fragmentPrefixListResult, TEST_LOCATION);
+
+  featureBuilder = featureBuilder.EnableAlphaMaskingOnRendering(false);
+
+  vertexPrefixList.clear();
+  fragmentPrefixList.clear();
+  featureBuilder.GetVertexShaderPrefixList(vertexPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentPrefixList);
+
+  vertexPrefixListResult.clear();
+  vertexPrefixListResult += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+  vertexPrefixListResult += "#define IS_REQUIRED_BORDERLINE\n";
+
+  fragmentPrefixListResult.clear();
+  fragmentPrefixListResult += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_BORDERLINE\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_YUV_TO_RGB\n";
+
+  DALI_TEST_EQUALS(vertexPrefixList, vertexPrefixListResult, TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefixList, fragmentPrefixListResult, TEST_LOCATION);
+
+  featureBuilder = featureBuilder.EnableYuvToRgb(true, true);
+
+  vertexPrefixList.clear();
+  fragmentPrefixList.clear();
+  featureBuilder.GetVertexShaderPrefixList(vertexPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentPrefixList);
+
+  fragmentPrefixListResult.clear();
+  fragmentPrefixListResult += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_BORDERLINE\n";
+  fragmentPrefixListResult += "#define IS_REQUIRED_UNIFIED_YUV_AND_RGB\n";
+
+  DALI_TEST_EQUALS(vertexPrefixList, vertexPrefixListResult, TEST_LOCATION);
+  DALI_TEST_EQUALS(fragmentPrefixList, fragmentPrefixListResult, TEST_LOCATION);
+  END_TEST;
+}
index 9933e1a..7274e9c 100644 (file)
@@ -54,6 +54,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/visuals/text/text-visual.cpp
    ${toolkit_src_dir}/visuals/transition-data-impl.cpp
    ${toolkit_src_dir}/visuals/image-visual-shader-factory.cpp
+   ${toolkit_src_dir}/visuals/image-visual-shader-feature-builder.cpp
    ${toolkit_src_dir}/visuals/visual-base-data-impl.cpp
    ${toolkit_src_dir}/visuals/visual-base-impl.cpp
    ${toolkit_src_dir}/visuals/visual-factory-cache.cpp
index 897accc..60d992c 100644 (file)
@@ -32,6 +32,7 @@
 #include <dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h>
 #include <dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
@@ -815,7 +816,7 @@ Shader AnimatedImageVisual::GenerateShader() const
   Shader shader;
   shader = mImageVisualShaderFactory.GetShader(
     mFactoryCache,
-    ImageVisualShaderFeature::FeatureBuilder()
+    ImageVisualShaderFeatureBuilder()
       .ApplyDefaultTextureWrapMode(defaultWrapMode)
       .EnableRoundedCorner(IsRoundedCornerRequired())
       .EnableBorderline(IsBorderlineRequired())
index 8da0313..b9a8f87 100644 (file)
@@ -32,6 +32,7 @@
 #include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -799,7 +800,7 @@ Shader AnimatedVectorImageVisual::GenerateShader() const
   {
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
-      ImageVisualShaderFeature::FeatureBuilder()
+      ImageVisualShaderFeatureBuilder()
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired()));
   }
index 53810b1..9761015 100644 (file)
@@ -36,85 +36,8 @@ namespace
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
 const int NATIVE_SHADER_TYPE_OFFSET = VisualFactoryCache::ShaderType::NATIVE_IMAGE_SHADER - VisualFactoryCache::ShaderType::IMAGE_SHADER;
-
-// enum of required list when we select shader
-enum class ImageVisualRequireFlag : uint32_t
-{
-  DEFAULT          = 0,
-  ROUNDED_CORNER   = 1 << 0,
-  BORDERLINE       = 1 << 1,
-  ALPHA_MASKING    = 1 << 2,
-  COLOR_CONVERSION = 1 << 3,
-
-  UNIFIED_YUV_AND_RGB = 1 << 2, // Special enum to trick unified YUV and RGB.
-};
-
-static constexpr auto          SHADER_TYPE_COUNT = 16u;
-VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[SHADER_TYPE_COUNT] =
-  {
-    VisualFactoryCache::IMAGE_SHADER,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER,
-    VisualFactoryCache::IMAGE_SHADER_BORDERLINE,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE,
-    VisualFactoryCache::IMAGE_SHADER_MASKING,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_MASKING,
-    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_MASKING,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING,
-    VisualFactoryCache::IMAGE_SHADER_YUV_TO_RGB,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_TO_RGB,
-    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_YUV_TO_RGB,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_YUV_TO_RGB,
-    VisualFactoryCache::IMAGE_SHADER_YUV_AND_RGB,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_AND_RGB,
-    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_YUV_AND_RGB,
-    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_YUV_AND_RGB};
 } // unnamed namespace
 
-namespace ImageVisualShaderFeature
-{
-FeatureBuilder& FeatureBuilder::EnableTextureAtlas(bool enableAtlas)
-{
-  mTextureAtlas = (enableAtlas ? TextureAtlas::ENABLED : TextureAtlas::DISABLED);
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode)
-{
-  mDefaultTextureWrapMode = (applyDefaultTextureWrapMode ? DefaultTextureWrapMode::APPLY : DefaultTextureWrapMode::DO_NOT_APPLY);
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::EnableRoundedCorner(bool enableRoundedCorner)
-{
-  mRoundedCorner = (enableRoundedCorner ? RoundedCorner::ENABLED : RoundedCorner::DISABLED);
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::EnableBorderline(bool enableBorderline)
-{
-  mBorderline = (enableBorderline ? Borderline::ENABLED : Borderline::DISABLED);
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::SetTextureForFragmentShaderCheck(const Dali::Texture& texture)
-{
-  mTexture = texture;
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering)
-{
-  mAlphaMaskingOnRendering = (enableAlphaMaskingOnRendering ? AlphaMaskingOnRendering::ENABLED : AlphaMaskingOnRendering::DISABLED);
-  return *this;
-}
-
-FeatureBuilder& FeatureBuilder::EnableYuvToRgb(bool enableYuvToRgb, bool enableUnifiedYuvAndRgb)
-{
-  mColorConversion = (enableUnifiedYuvAndRgb ? ColorConversion::UNIFIED_YUV_AND_RGB : (enableYuvToRgb ? ColorConversion::YUV_TO_RGB : ColorConversion::DONT_NEED));
-  return *this;
-}
-} // namespace ImageVisualShaderFeature
-
 ImageVisualShaderFactory::ImageVisualShaderFactory()
 : mFragmentShaderNeedChange(ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED)
 {
@@ -124,60 +47,12 @@ ImageVisualShaderFactory::~ImageVisualShaderFactory()
 {
 }
 
-Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const ImageVisualShaderFeature::FeatureBuilder& featureBuilder)
+Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, ImageVisualShaderFeatureBuilder& featureBuilder)
 {
   Shader                         shader;
-  VisualFactoryCache::ShaderType shaderType = VisualFactoryCache::IMAGE_SHADER;
-
-  const auto& atlasing                = featureBuilder.mTextureAtlas;
-  const auto& defaultTextureWrapping  = featureBuilder.mDefaultTextureWrapMode;
-  const auto& roundedCorner           = featureBuilder.mRoundedCorner;
-  const auto& borderline              = featureBuilder.mBorderline;
-  const auto& alphaMaskingOnRendering = featureBuilder.mAlphaMaskingOnRendering;
-  const auto& colorConversion         = featureBuilder.mColorConversion;
-  const auto& changeFragmentShader    = (featureBuilder.mTexture && DevelTexture::IsNative(featureBuilder.mTexture))
-                                          ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE
-                                          : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
-
-  if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED)
-  {
-    if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY)
-    {
-      shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP;
-    }
-    else
-    {
-      shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP;
-    }
-  }
-  else
-  {
-    uint32_t shaderTypeFlag = static_cast<uint32_t>(ImageVisualRequireFlag::DEFAULT);
-    if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
-    {
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ROUNDED_CORNER);
-    }
-    if(borderline == ImageVisualShaderFeature::Borderline::ENABLED)
-    {
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::BORDERLINE);
-    }
-    if(alphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
-    {
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ALPHA_MASKING);
-    }
-    else if(colorConversion == ImageVisualShaderFeature::ColorConversion::YUV_TO_RGB) // Not support gpu masking and color conversion at the same time now
-    {
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::COLOR_CONVERSION);
-    }
-    else if(colorConversion == ImageVisualShaderFeature::ColorConversion::UNIFIED_YUV_AND_RGB)
-    {
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::COLOR_CONVERSION);
-      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::UNIFIED_YUV_AND_RGB);
-    }
-    shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
-  }
+  VisualFactoryCache::ShaderType shaderType = featureBuilder.GetShaderType();
 
-  if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE &&
+  if(featureBuilder.NeedToChangeFragmentShader() == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE &&
      (mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED ||
       mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE))
   {
@@ -185,104 +60,47 @@ Shader ImageVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, con
   }
 
   shader = factoryCache.GetShader(shaderType);
-  if(!shader)
+  if(shader)
   {
-    std::string vertexShaderPrefixList;
-    std::string fragmentShaderPrefixList;
-    if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED)
-    {
-      if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY)
-      {
-        fragmentShaderPrefixList += "#define ATLAS_DEFAULT_WARP\n";
-      }
-      else
-      {
-        fragmentShaderPrefixList += "#define ATLAS_CUSTOM_WARP\n";
-      }
-    }
-    else
-    {
-      if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
-      {
-        vertexShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER\n";
-        fragmentShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER\n";
-      }
-      if(borderline == ImageVisualShaderFeature::Borderline::ENABLED)
-      {
-        vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
-        fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
-      }
-      if(alphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
-      {
-        vertexShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING\n";
-        fragmentShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING\n";
-      }
-      else if(colorConversion == ImageVisualShaderFeature::ColorConversion::YUV_TO_RGB)
-      {
-        fragmentShaderPrefixList += "#define IS_REQUIRED_YUV_TO_RGB\n";
-      }
-      else if(colorConversion == ImageVisualShaderFeature::ColorConversion::UNIFIED_YUV_AND_RGB)
-      {
-        fragmentShaderPrefixList += "#define IS_REQUIRED_UNIFIED_YUV_AND_RGB\n";
-      }
-    }
-
-    std::string vertexShader   = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_VERT.data());
-    std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_FRAG.data());
+    return shader;
+  }
 
-    if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)
-    {
-      if(DALI_UNLIKELY(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED))
-      {
-        // NOTE : This routine will run exist one times.
-        //
-        // First, we will run ApplyNativeFragmentShader
-        //  - If fragment shader is modified, then current platform allow to change fragment shader.
-        //    We cache this result mFragmentShaderNeedChange = ChangeFragmentShader::NEED_CHANGE.
-        //  - If fragment shader is not modified, then current platform will always don't change fragment shader.
-        //    We cache this result mFragmentShaderNeedChange = ChangeFragmentShader::DONT_CHANGE.
-        //    And change current shaderType into normal image range.
-        //    After cached the result, shaderType never become NATIVE_IMAGE_SHADER anymore.
-        // Second, save shader result.
+  std::string vertexShaderPrefixList;
+  std::string fragmentShaderPrefixList;
+  featureBuilder.GetVertexShaderPrefixList(vertexShaderPrefixList);
+  featureBuilder.GetFragmentShaderPrefixList(fragmentShaderPrefixList);
 
-        // Try to apply fragmentShader
-        bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.mTexture, fragmentShader);
-        if(modified)
-        {
-          // Now we know that fragment shader need to change.
-          mFragmentShaderNeedChange = ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE;
-        }
-        else
-        {
-          // Now we know that fragment shader even don't need to change.
-          // We can skip ApplyNativeFragmentShader routine after now.
-          mFragmentShaderNeedChange = ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
+  std::string vertexShader   = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_VERT.data());
+  std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_IMAGE_VISUAL_SHADER_FRAG.data());
 
-          // Now we need normal shader type
-          // So decrease NATIVE_SHADER_TYPE_OFFSET.
-          shaderType = static_cast<VisualFactoryCache::ShaderType>(static_cast<int>(shaderType) - NATIVE_SHADER_TYPE_OFFSET);
+  if(featureBuilder.NeedToChangeFragmentShader() == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)
+  {
+    bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.GetTexture(), fragmentShader);
+    if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)
+    {
+      DALI_ASSERT_ALWAYS(modified && "NativeImageTexture need to change fragment shader. But DALI default image shader doesn't changed!");
+    }
+    else if(DALI_UNLIKELY(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED))
+    {
+      mFragmentShaderNeedChange = (modified) ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
 
-          // If we already compiled this type already, just use that cached shader.
-          // Else, just go forward.
-          shader = factoryCache.GetShader(shaderType);
-          if(shader)
-          {
-            return shader;
-          }
-        }
-      }
-      else if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)
+      if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE)
       {
-        // Always need to apply fragmentShader
-        bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.mTexture, fragmentShader);
-        DALI_ASSERT_ALWAYS(modified && "NativeImageTexture need to change fragment shader. But DALI default image shader doesn't changed!");
+        shaderType = static_cast<VisualFactoryCache::ShaderType>(static_cast<int>(shaderType) - NATIVE_SHADER_TYPE_OFFSET);
+        shader     = factoryCache.GetShader(shaderType);
       }
     }
-    shader = Shader::New(vertexShader, fragmentShader);
-    shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
-    factoryCache.SaveShader(shaderType, shader);
   }
 
+  if(shader)
+  {
+    return shader;
+  }
+
+  shader = Shader::New(vertexShader, fragmentShader);
+  shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
+  factoryCache.SaveShader(shaderType, shader);
+
   return shader;
 }
 
index 02ea83e..cf1c25b 100644 (file)
@@ -21,6 +21,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <string_view>
 
 namespace Dali
@@ -29,131 +30,6 @@ namespace Toolkit
 {
 namespace Internal
 {
-/**
- * ImageVisualShaderFeature contains feature lists what image visual shader need to know.
- */
-namespace ImageVisualShaderFeature
-{
-namespace TextureAtlas
-{
-/**
- * @brief Whether use texture with atlas, or not
- */
-enum Type
-{
-  DISABLED = 0, ///< Image visual doesn't use ATLAS
-  ENABLED       ///< Image visual uses ATLAS
-};
-} // namespace TextureAtlas
-
-namespace DefaultTextureWrapMode
-{
-/**
- * @brief Whether apply to texture wraping in default, or not
- */
-enum Type
-{
-  APPLY = 0,   ///< Image visual applies to wraping texture in default
-  DO_NOT_APPLY ///< Image visual doesn't apply to wraping texture in default
-};
-} // namespace DefaultTextureWrapMode
-
-namespace RoundedCorner
-{
-/**
- * @brief Whether use rounded corner, or not
- */
-enum Type
-{
-  DISABLED = 0, ///< Image visual doesn't use rounded corner
-  ENABLED       ///< Image visual uses rounded corner
-};
-} // namespace RoundedCorner
-
-namespace Borderline
-{
-/**
- * @brief Whether use borderline, or not
- */
-enum Type
-{
-  DISABLED = 0, ///< Image visual doesn't use borderline
-  ENABLED       ///< Image visual uses borderline
-};
-} // namespace Borderline
-
-namespace ChangeFragmentShader
-{
-/**
- * @brief Whether native image change the default fragment shader, or not
- */
-enum Type
-{
-  DONT_CHANGE = 0, ///< Native image doesn't change default fragment shader.
-  NEED_CHANGE,     ///< Native image changes default fragment shader. We need another shader cache.
-  UNDECIDED,       ///< Undecided.
-};
-} // namespace ChangeFragmentShader
-
-namespace AlphaMaskingOnRendering
-{
-/**
- * @brief Whether use runtime alpha masking in shader, or not
- */
-enum Type
-{
-  DISABLED = 0, ///< Image visual doesn't use runtime alpha masking
-  ENABLED       ///< Image visual uses runtime alpha masking
-};
-} // namespace AlphaMaskingOnRendering
-
-namespace ColorConversion
-{
-/**
- * @brief Whether the color format conversion is needed or not
- */
-enum Type
-{
-  DONT_NEED = 0,      ///< Not need to convert
-  YUV_TO_RGB,         ///< Need yuv to rgb conversion
-  UNIFIED_YUV_AND_RGB ///< Need to support both yuv conversion case and normal case.
-};
-} // namespace ColorConversion
-
-/**
- * @brief Collection of current image visual feature. Only use for ImageVisualShaderFactory::GetShader()
- */
-struct FeatureBuilder
-{
-  FeatureBuilder()
-  : mTextureAtlas(TextureAtlas::DISABLED),
-    mDefaultTextureWrapMode(DefaultTextureWrapMode::APPLY),
-    mRoundedCorner(RoundedCorner::DISABLED),
-    mBorderline(Borderline::DISABLED),
-    mAlphaMaskingOnRendering(AlphaMaskingOnRendering::DISABLED),
-    mColorConversion(ColorConversion::DONT_NEED),
-    mTexture()
-  {
-  }
-
-  FeatureBuilder& EnableTextureAtlas(bool enableTextureAtlas);
-  FeatureBuilder& ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode);
-  FeatureBuilder& EnableRoundedCorner(bool enableRoundedCorner);
-  FeatureBuilder& EnableBorderline(bool enableBorderline);
-  FeatureBuilder& SetTextureForFragmentShaderCheck(const Dali::Texture& texture);
-  FeatureBuilder& EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering);
-  FeatureBuilder& EnableYuvToRgb(bool enableYuvToRgb, bool enableUnifiedYuvAndRgb = false);
-
-  TextureAtlas::Type            mTextureAtlas : 2;            ///< Whether use texture with atlas, or not. default as TextureAtlas::DISABLED
-  DefaultTextureWrapMode::Type  mDefaultTextureWrapMode : 2;  ///< Whether apply to texture wraping in default, or not. default as DefaultTextureWrapMode::APPLY
-  RoundedCorner::Type           mRoundedCorner : 2;           ///< Whether use rounded corner, or not. default as RoundedCorner::DISABLED
-  Borderline::Type              mBorderline : 2;              ///< Whether use borderline, or not. default as Borderline::DISABLED
-  AlphaMaskingOnRendering::Type mAlphaMaskingOnRendering : 2; ///< Whether use runtime alpha masking, or not. default as AlphaMaskingOnRendering::DISABLED
-  ColorConversion::Type         mColorConversion : 2;         ///< Whether the color format conversion is needed or not
-  Dali::Texture                 mTexture;                     ///< Texture to check whether we need to change fragment shader or not
-};
-
-} // namespace ImageVisualShaderFeature
 
 /**
  * ImageVisualShaderFactory is an object that provides and shares shaders between image visuals
@@ -177,7 +53,7 @@ public:
    * @param[in] featureBuilder Collection of current image shader's features
    * @return The standard image rendering shader with features.
    */
-  Shader GetShader(VisualFactoryCache& factoryCache, const ImageVisualShaderFeature::FeatureBuilder& featureBuilder);
+  Shader GetShader(VisualFactoryCache& factoryCache, ImageVisualShaderFeatureBuilder& featureBuilder);
 
   /**
    * @brief Request the default vertex shader source.
diff --git a/dali-toolkit/internal/visuals/image-visual-shader-feature-builder.cpp b/dali-toolkit/internal/visuals/image-visual-shader-feature-builder.cpp
new file mode 100644 (file)
index 0000000..9b3eb8c
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+namespace
+{
+// enum of required list when we select shader
+enum class ImageVisualRequireFlag : uint32_t
+{
+  DEFAULT          = 0,
+  ROUNDED_CORNER   = 1 << 0,
+  BORDERLINE       = 1 << 1,
+  ALPHA_MASKING    = 1 << 2,
+  COLOR_CONVERSION = 1 << 3,
+
+  UNIFIED_YUV_AND_RGB = 1 << 2, // Special enum to trick unified YUV and RGB.
+};
+
+static constexpr auto          SHADER_TYPE_COUNT = 16u;
+VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[SHADER_TYPE_COUNT] =
+  {
+    VisualFactoryCache::IMAGE_SHADER,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER,
+    VisualFactoryCache::IMAGE_SHADER_BORDERLINE,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE,
+    VisualFactoryCache::IMAGE_SHADER_MASKING,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_MASKING,
+    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_MASKING,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_MASKING,
+    VisualFactoryCache::IMAGE_SHADER_YUV_TO_RGB,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_TO_RGB,
+    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_YUV_TO_RGB,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_YUV_TO_RGB,
+    VisualFactoryCache::IMAGE_SHADER_YUV_AND_RGB,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_AND_RGB,
+    VisualFactoryCache::IMAGE_SHADER_BORDERLINE_YUV_AND_RGB,
+    VisualFactoryCache::IMAGE_SHADER_ROUNDED_BORDERLINE_YUV_AND_RGB};
+} // unnamed namespace
+
+ImageVisualShaderFeatureBuilder::ImageVisualShaderFeatureBuilder()
+: mTextureAtlas(ImageVisualShaderFeature::TextureAtlas::DISABLED),
+  mDefaultTextureWrapMode(ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY),
+  mRoundedCorner(ImageVisualShaderFeature::RoundedCorner::DISABLED),
+  mBorderline(ImageVisualShaderFeature::Borderline::DISABLED),
+  mAlphaMaskingOnRendering(ImageVisualShaderFeature::AlphaMaskingOnRendering::DISABLED),
+  mColorConversion(ImageVisualShaderFeature::ColorConversion::DONT_NEED),
+  mTexture()
+{
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::EnableTextureAtlas(bool enableTextureAtlas)
+{
+  mTextureAtlas = (enableTextureAtlas ? ImageVisualShaderFeature::TextureAtlas::ENABLED : ImageVisualShaderFeature::TextureAtlas::DISABLED);
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode)
+{
+  mDefaultTextureWrapMode = (applyDefaultTextureWrapMode ? ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY : ImageVisualShaderFeature::DefaultTextureWrapMode::DO_NOT_APPLY);
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::EnableRoundedCorner(bool enableRoundedCorner)
+{
+  mRoundedCorner = (enableRoundedCorner ? ImageVisualShaderFeature::RoundedCorner::ENABLED : ImageVisualShaderFeature::RoundedCorner::DISABLED);
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::EnableBorderline(bool enableBorderline)
+{
+  mBorderline = (enableBorderline ? ImageVisualShaderFeature::Borderline::ENABLED : ImageVisualShaderFeature::Borderline::DISABLED);
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::SetTextureForFragmentShaderCheck(const Dali::Texture& texture)
+{
+  mTexture = texture;
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering)
+{
+  mAlphaMaskingOnRendering = (enableAlphaMaskingOnRendering ? ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED : ImageVisualShaderFeature::AlphaMaskingOnRendering::DISABLED);
+  return *this;
+}
+
+ImageVisualShaderFeatureBuilder& ImageVisualShaderFeatureBuilder::EnableYuvToRgb(bool enableYuvToRgb, bool enableUnifiedYuvAndRgb)
+{
+  mColorConversion = (enableUnifiedYuvAndRgb ? ImageVisualShaderFeature::ColorConversion::UNIFIED_YUV_AND_RGB : (enableYuvToRgb ? ImageVisualShaderFeature::ColorConversion::YUV_TO_RGB : ImageVisualShaderFeature::ColorConversion::DONT_NEED));
+  return *this;
+}
+
+VisualFactoryCache::ShaderType ImageVisualShaderFeatureBuilder::GetShaderType()
+{
+  VisualFactoryCache::ShaderType shaderType = VisualFactoryCache::IMAGE_SHADER;
+  if(mTextureAtlas == ImageVisualShaderFeature::TextureAtlas::ENABLED)
+  {
+    if(mDefaultTextureWrapMode == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY)
+    {
+      shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP;
+    }
+    else
+    {
+      shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP;
+    }
+  }
+  else
+  {
+    uint32_t shaderTypeFlag = static_cast<uint32_t>(ImageVisualRequireFlag::DEFAULT);
+    if(mRoundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
+    {
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ROUNDED_CORNER);
+    }
+    if(mBorderline == ImageVisualShaderFeature::Borderline::ENABLED)
+    {
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::BORDERLINE);
+    }
+    if(mAlphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
+    {
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::ALPHA_MASKING);
+    }
+    else if(mColorConversion == ImageVisualShaderFeature::ColorConversion::YUV_TO_RGB) // Not support gpu masking and color conversion at the same time now
+    {
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::COLOR_CONVERSION);
+    }
+    else if(mColorConversion == ImageVisualShaderFeature::ColorConversion::UNIFIED_YUV_AND_RGB)
+    {
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::COLOR_CONVERSION);
+      shaderTypeFlag |= static_cast<uint32_t>(ImageVisualRequireFlag::UNIFIED_YUV_AND_RGB);
+    }
+    shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
+  }
+
+  return shaderType;
+}
+
+ImageVisualShaderFeature::ChangeFragmentShader::Type ImageVisualShaderFeatureBuilder::NeedToChangeFragmentShader()
+{
+  return (mTexture && DevelTexture::IsNative(mTexture))
+           ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE
+           : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE;
+}
+
+void ImageVisualShaderFeatureBuilder::GetVertexShaderPrefixList(std::string& vertexShaderPrefixList)
+{
+  if(mTextureAtlas != ImageVisualShaderFeature::TextureAtlas::ENABLED)
+  {
+    if(mRoundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
+    {
+      vertexShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+    }
+    if(mBorderline == ImageVisualShaderFeature::Borderline::ENABLED)
+    {
+      vertexShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
+    }
+    if(mAlphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
+    {
+      vertexShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING\n";
+    }
+  }
+}
+
+void ImageVisualShaderFeatureBuilder::GetFragmentShaderPrefixList(std::string& fragmentShaderPrefixList)
+{
+  if(mTextureAtlas == ImageVisualShaderFeature::TextureAtlas::ENABLED)
+  {
+    if(mDefaultTextureWrapMode == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY)
+    {
+      fragmentShaderPrefixList += "#define ATLAS_DEFAULT_WARP\n";
+    }
+    else
+    {
+      fragmentShaderPrefixList += "#define ATLAS_CUSTOM_WARP\n";
+    }
+  }
+  else
+  {
+    if(mRoundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED)
+    {
+      fragmentShaderPrefixList += "#define IS_REQUIRED_ROUNDED_CORNER\n";
+    }
+    if(mBorderline == ImageVisualShaderFeature::Borderline::ENABLED)
+    {
+      fragmentShaderPrefixList += "#define IS_REQUIRED_BORDERLINE\n";
+    }
+    if(mAlphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED)
+    {
+      fragmentShaderPrefixList += "#define IS_REQUIRED_ALPHA_MASKING\n";
+    }
+    else if(mColorConversion == ImageVisualShaderFeature::ColorConversion::YUV_TO_RGB)
+    {
+      fragmentShaderPrefixList += "#define IS_REQUIRED_YUV_TO_RGB\n";
+    }
+    else if(mColorConversion == ImageVisualShaderFeature::ColorConversion::UNIFIED_YUV_AND_RGB)
+    {
+      fragmentShaderPrefixList += "#define IS_REQUIRED_UNIFIED_YUV_AND_RGB\n";
+    }
+  }
+}
+
+Dali::Texture ImageVisualShaderFeatureBuilder::GetTexture()
+{
+  return mTexture;
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h b/dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h
new file mode 100644 (file)
index 0000000..d757f70
--- /dev/null
@@ -0,0 +1,173 @@
+#ifndef DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FEATURE_BUILDER_H
+#define DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FEATURE_BUILDER_H
+
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/rendering/texture.h>
+#include <dali/devel-api/rendering/texture-devel.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+/**
+ * ImageVisualShaderFeature contains feature lists what image visual shader need to know.
+ */
+namespace ImageVisualShaderFeature
+{
+namespace TextureAtlas
+{
+/**
+ * @brief Whether use texture with atlas, or not
+ */
+enum Type
+{
+  DISABLED = 0, ///< Image visual doesn't use ATLAS
+  ENABLED       ///< Image visual uses ATLAS
+};
+} // namespace TextureAtlas
+
+namespace DefaultTextureWrapMode
+{
+/**
+ * @brief Whether apply to texture wraping in default, or not
+ */
+enum Type
+{
+  APPLY = 0,   ///< Image visual applies to wraping texture in default
+  DO_NOT_APPLY ///< Image visual doesn't apply to wraping texture in default
+};
+} // namespace DefaultTextureWrapMode
+
+namespace RoundedCorner
+{
+/**
+ * @brief Whether use rounded corner, or not
+ */
+enum Type
+{
+  DISABLED = 0, ///< Image visual doesn't use rounded corner
+  ENABLED       ///< Image visual uses rounded corner
+};
+} // namespace RoundedCorner
+
+namespace Borderline
+{
+/**
+ * @brief Whether use borderline, or not
+ */
+enum Type
+{
+  DISABLED = 0, ///< Image visual doesn't use borderline
+  ENABLED       ///< Image visual uses borderline
+};
+} // namespace Borderline
+
+namespace ChangeFragmentShader
+{
+/**
+ * @brief Whether native image change the default fragment shader, or not
+ */
+enum Type
+{
+  DONT_CHANGE = 0, ///< Native image doesn't change default fragment shader.
+  NEED_CHANGE,     ///< Native image changes default fragment shader. We need another shader cache.
+  UNDECIDED,       ///< Undecided.
+};
+} // namespace ChangeFragmentShader
+
+namespace AlphaMaskingOnRendering
+{
+/**
+ * @brief Whether use runtime alpha masking in shader, or not
+ */
+enum Type
+{
+  DISABLED = 0, ///< Image visual doesn't use runtime alpha masking
+  ENABLED       ///< Image visual uses runtime alpha masking
+};
+} // namespace AlphaMaskingOnRendering
+
+namespace ColorConversion
+{
+/**
+ * @brief Whether the color format conversion is needed or not
+ */
+enum Type
+{
+  DONT_NEED = 0,      ///< Not need to convert
+  YUV_TO_RGB,         ///< Need yuv to rgb conversion
+  UNIFIED_YUV_AND_RGB ///< Need to support both yuv conversion case and normal case.
+};
+} // namespace ColorConversion
+
+} // namespace ImageVisualShaderFeature
+
+/**
+ * @brief Collection of current image visual feature. Only use for ImageVisualShaderFactory::GetShader()
+ */
+class ImageVisualShaderFeatureBuilder
+{
+public:
+  ImageVisualShaderFeatureBuilder();
+
+  ImageVisualShaderFeatureBuilder& EnableTextureAtlas(bool enableTextureAtlas);
+
+  ImageVisualShaderFeatureBuilder& ApplyDefaultTextureWrapMode(bool applyDefaultTextureWrapMode);
+
+  ImageVisualShaderFeatureBuilder& EnableRoundedCorner(bool enableRoundedCorner);
+
+  ImageVisualShaderFeatureBuilder& EnableBorderline(bool enableBorderline);
+
+  ImageVisualShaderFeatureBuilder& SetTextureForFragmentShaderCheck(const Dali::Texture& texture);
+
+  ImageVisualShaderFeatureBuilder& EnableAlphaMaskingOnRendering(bool enableAlphaMaskingOnRendering);
+
+  ImageVisualShaderFeatureBuilder& EnableYuvToRgb(bool enableYuvToRgb, bool enableUnifiedYuvAndRgb = false);
+
+  VisualFactoryCache::ShaderType GetShaderType();
+
+  ImageVisualShaderFeature::ChangeFragmentShader::Type NeedToChangeFragmentShader();
+
+  void GetVertexShaderPrefixList(std::string& vertexShaderPrefixList);
+  void GetFragmentShaderPrefixList(std::string& fragmentShaderPrefixList);
+
+  Dali::Texture GetTexture();
+
+private:
+  ImageVisualShaderFeature::TextureAtlas::Type            mTextureAtlas : 2;            ///< Whether use texture with atlas, or not. default as TextureAtlas::DISABLED
+  ImageVisualShaderFeature::DefaultTextureWrapMode::Type  mDefaultTextureWrapMode : 2;  ///< Whether apply to texture wraping in default, or not. default as DefaultTextureWrapMode::APPLY
+  ImageVisualShaderFeature::RoundedCorner::Type           mRoundedCorner : 2;           ///< Whether use rounded corner, or not. default as RoundedCorner::DISABLED
+  ImageVisualShaderFeature::Borderline::Type              mBorderline : 2;              ///< Whether use borderline, or not. default as Borderline::DISABLED
+  ImageVisualShaderFeature::AlphaMaskingOnRendering::Type mAlphaMaskingOnRendering : 2; ///< Whether use runtime alpha masking, or not. default as AlphaMaskingOnRendering::DISABLED
+  ImageVisualShaderFeature::ColorConversion::Type         mColorConversion : 2;         ///< Whether the color format conversion is needed or not
+  Dali::Texture                                           mTexture;                     ///< Texture to check whether we need to change fragment shader or not
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FACTORY_H
index 2f0e800..15c9077 100644 (file)
@@ -36,6 +36,7 @@
 #include <dali-toolkit/internal/texture-manager/texture-manager-impl.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
@@ -1264,7 +1265,7 @@ Shader ImageVisual::GenerateShader() const
     // Create and cache the standard shader
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
-      ImageVisualShaderFeature::FeatureBuilder()
+      ImageVisualShaderFeatureBuilder()
         .EnableTextureAtlas(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED && !useNativeImage)
         .ApplyDefaultTextureWrapMode(mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE)
         .EnableRoundedCorner(IsRoundedCornerRequired())
index c9367a5..090968c 100644 (file)
@@ -30,6 +30,7 @@
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/npatch-loader.h>
 #include <dali-toolkit/internal/visuals/rendering-addon.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
@@ -338,9 +339,10 @@ void NPatchVisual::OnInitialize()
 {
   // Get basic geometry and shader
   Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
+  auto imageVisualShaderFeatureBuilder = ImageVisualShaderFeatureBuilder();
   Shader   shader   = mImageVisualShaderFactory.GetShader(
     mFactoryCache,
-    ImageVisualShaderFeature::FeatureBuilder());
+    imageVisualShaderFeatureBuilder);
 
   mImpl->mRenderer = VisualRenderer::New(geometry, shader);
   mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
index 8f9919d..c6e471c 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
+#include <dali-toolkit/internal/visuals/image-visual-shader-feature-builder.h>
 #include <dali-toolkit/internal/visuals/svg/svg-task.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -484,7 +485,7 @@ Shader SvgVisual::GenerateShader() const
   {
     shader = mImageVisualShaderFactory.GetShader(
       mFactoryCache,
-      ImageVisualShaderFeature::FeatureBuilder()
+      ImageVisualShaderFeatureBuilder()
         .EnableTextureAtlas(mAttemptAtlasing)
         .EnableRoundedCorner(IsRoundedCornerRequired())
         .EnableBorderline(IsBorderlineRequired()));