Merge "Remove NPatchLoader observer when they request remove" into devel/master
authorEunki Hong <eunkiki.hong@samsung.com>
Mon, 25 Sep 2023 05:15:17 +0000 (05:15 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 25 Sep 2023 05:15:17 +0000 (05:15 +0000)
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 e6e07e8..0f18783 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>
@@ -1282,7 +1283,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()));