X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fvisuals%2Fimage-visual-shader-factory.cpp;h=ceb5848d7594c27b86f706b191e846b06d9989f1;hb=HEAD;hp=2c98a4f3feebe75f1db7cc6ece60a4b6c20300b8;hpb=c70520ff81c009acafc2a2cfd1ac38adb64ffcae;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp index 2c98a4f..f0e413c 100644 --- a/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp +++ b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -22,6 +22,7 @@ // INTERNAL INCLUDES #include +#include #include #include @@ -35,80 +36,38 @@ 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; +constexpr int NATIVE_SHADER_TYPE_OFFSET = VisualFactoryCache::ShaderType::NATIVE_IMAGE_SHADER - VisualFactoryCache::ShaderType::IMAGE_SHADER; +constexpr std::string_view Y_FLIP_MASK_TEXTURE = "uYFlipMaskTexture"; +constexpr float NOT_FLIP_MASK_TEXTURE = 0.0f; -// 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, -}; +constexpr auto SHADER_TYPE_COUNT = 6u; -static constexpr auto SHADER_TYPE_COUNT = 12u; -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}; +constexpr std::string_view VertexPredefines[SHADER_TYPE_COUNT]{ + "", // VisualFactoryCache::IMAGE_SHADER, + "#define IS_REQUIRED_ROUNDED_CORNER\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER, + "", // VisualFactoryCache::IMAGE_SHADER_YUV_TO_RGB, + "#define IS_REQUIRED_ROUNDED_CORNER\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_TO_RGB, + "", // VisualFactoryCache::IMAGE_SHADER_YUV_AND_RGB, + "#define IS_REQUIRED_ROUNDED_CORNER\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_AND_RGB, +}; +constexpr std::string_view FragmentPredefines[SHADER_TYPE_COUNT]{ + "", // VisualFactoryCache::IMAGE_SHADER, + "#define IS_REQUIRED_ROUNDED_CORNER\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER, + "#define IS_REQUIRED_YUV_TO_RGB\n", // VisualFactoryCache::IMAGE_SHADER_YUV_TO_RGB, + "#define IS_REQUIRED_ROUNDED_CORNER\n#define IS_REQUIRED_YUV_TO_RGB\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_TO_RGB, + "#define IS_REQUIRED_UNIFIED_YUV_AND_RGB\n", // VisualFactoryCache::IMAGE_SHADER_YUV_AND_RGB, + "#define IS_REQUIRED_ROUNDED_CORNER\n#define IS_REQUIRED_UNIFIED_YUV_AND_RGB\n", // VisualFactoryCache::IMAGE_SHADER_ROUNDED_CORNER_YUV_AND_RGB, +}; +constexpr VisualFactoryCache::ShaderType ShaderTypePredefines[SHADER_TYPE_COUNT]{ + VisualFactoryCache::ShaderType::IMAGE_SHADER, + VisualFactoryCache::ShaderType::IMAGE_SHADER_ROUNDED_CORNER, + VisualFactoryCache::ShaderType::IMAGE_SHADER_YUV_TO_RGB, + VisualFactoryCache::ShaderType::IMAGE_SHADER_ROUNDED_CORNER_YUV_TO_RGB, + VisualFactoryCache::ShaderType::IMAGE_SHADER_YUV_AND_RGB, + VisualFactoryCache::ShaderType::IMAGE_SHADER_ROUNDED_CORNER_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) -{ - mColorConversion = (enableYuvToRgb ? ColorConversion::YUV_TO_RGB : ColorConversion::DONT_NEED); - return *this; -} -} // namespace ImageVisualShaderFeature - ImageVisualShaderFactory::ImageVisualShaderFactory() : mFragmentShaderNeedChange(ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED) { @@ -118,154 +77,75 @@ 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; + VisualFactoryCache::ShaderType shaderType = featureBuilder.GetShaderType(); - 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(featureBuilder.NeedToChangeFragmentShader() == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE && + (mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED || + mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE)) + { + DALI_ASSERT_DEBUG((static_cast(shaderType) >= static_cast(VisualFactoryCache::IMAGE_SHADER)) && + (static_cast(shaderType) <= static_cast(VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP)) && + "Do not support native image shader for given feature!!"); + shaderType = static_cast(static_cast(shaderType) + NATIVE_SHADER_TYPE_OFFSET); + } - if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED) + shader = factoryCache.GetShader(shaderType); + if(shader) { - if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY) - { - shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP; - } - else - { - shaderType = VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP; - } + return shader; } - else + + std::string vertexShaderPrefixList; + std::string fragmentShaderPrefixList; + featureBuilder.GetVertexShaderPrefixList(vertexShaderPrefixList); + featureBuilder.GetFragmentShaderPrefixList(fragmentShaderPrefixList); + + if(Dali::Toolkit::Internal::ImageVisualShaderDebug::DebugImageVisualShaderEnabled()) { - uint32_t shaderTypeFlag = static_cast(ImageVisualRequireFlag::DEFAULT); - if(roundedCorner == ImageVisualShaderFeature::RoundedCorner::ENABLED) - { - shaderTypeFlag |= static_cast(ImageVisualRequireFlag::ROUNDED_CORNER); - } - if(borderline == ImageVisualShaderFeature::Borderline::ENABLED) - { - shaderTypeFlag |= static_cast(ImageVisualRequireFlag::BORDERLINE); - } - if(alphaMaskingOnRendering == ImageVisualShaderFeature::AlphaMaskingOnRendering::ENABLED) - { - shaderTypeFlag |= static_cast(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(ImageVisualRequireFlag::COLOR_CONVERSION); - } - shaderType = SHADER_TYPE_TABLE[shaderTypeFlag]; + vertexShaderPrefixList += "#define IS_REQUIRED_DEBUG_VISUAL_SHADER\n"; + fragmentShaderPrefixList += "#define IS_REQUIRED_DEBUG_VISUAL_SHADER\n"; } - if(changeFragmentShader == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE && - (mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED || - mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_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()); + + if(Dali::Toolkit::Internal::ImageVisualShaderDebug::DebugImageVisualShaderEnabled()) { - shaderType = static_cast(static_cast(shaderType) + NATIVE_SHADER_TYPE_OFFSET); + Dali::Toolkit::Internal::ImageVisualShaderDebug::ApplyImageVisualShaderDebugScriptCode(vertexShader, fragmentShader); } - shader = factoryCache.GetShader(shaderType); - if(!shader) + if(featureBuilder.NeedToChangeFragmentShader() == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE) { - std::string vertexShaderPrefixList; - std::string fragmentShaderPrefixList; - if(atlasing == ImageVisualShaderFeature::TextureAtlas::ENABLED) + bool modified = DevelTexture::ApplyNativeFragmentShader(featureBuilder.GetTexture(), fragmentShader); + if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE) { - if(defaultTextureWrapping == ImageVisualShaderFeature::DefaultTextureWrapMode::APPLY) - { - fragmentShaderPrefixList += "#define ATLAS_DEFAULT_WARP\n"; - } - else - { - fragmentShaderPrefixList += "#define ATLAS_CUSTOM_WARP\n"; - } + DALI_ASSERT_ALWAYS(modified && "NativeImageTexture need to change fragment shader. But DALI default image shader doesn't changed!"); } - else + else if(DALI_UNLIKELY(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::UNDECIDED)) { - 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) + mFragmentShaderNeedChange = (modified) ? ImageVisualShaderFeature::ChangeFragmentShader::NEED_CHANGE : ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE; + + if(mFragmentShaderNeedChange == ImageVisualShaderFeature::ChangeFragmentShader::DONT_CHANGE) { - fragmentShaderPrefixList += "#define IS_REQUIRED_YUV_TO_RGB\n"; + shaderType = static_cast(static_cast(shaderType) - NATIVE_SHADER_TYPE_OFFSET); + shader = factoryCache.GetShader(shaderType); } } + } - 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()); - - 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. - - // 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; - - // Now we need normal shader type - // So decrease NATIVE_SHADER_TYPE_OFFSET. - shaderType = static_cast(static_cast(shaderType) - NATIVE_SHADER_TYPE_OFFSET); + if(shader) + { + return shader; + } - // 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) - { - // 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!"); - } - } - shader = Shader::New(vertexShader, fragmentShader); - shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); - factoryCache.SaveShader(shaderType, shader); + shader = factoryCache.GenerateAndSaveShader(shaderType, vertexShader, fragmentShader); + shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); + if(featureBuilder.IsEnabledAlphaMaskingOnRendering()) + { + shader.RegisterProperty(Y_FLIP_MASK_TEXTURE, NOT_FLIP_MASK_TEXTURE); } return shader; @@ -294,6 +174,29 @@ std::string_view ImageVisualShaderFactory::GetFragmentShaderSource() return gFragmentShaderNoAtlas; } +void ImageVisualShaderFactory::GetPreCompiledShader(RawShaderData& shaders) +{ + std::vector vertexPrefix; + std::vector fragmentPrefix; + std::vector shaderName; + shaders.shaderCount = 0; + int shaderCount = 0; + for(uint32_t i = 0; i < SHADER_TYPE_COUNT; ++i) + { + vertexPrefix.push_back(VertexPredefines[i]); + fragmentPrefix.push_back(FragmentPredefines[i]); + shaderName.push_back(Scripting::GetLinearEnumerationName(ShaderTypePredefines[i], VISUAL_SHADER_TYPE_TABLE, VISUAL_SHADER_TYPE_TABLE_COUNT)); + shaderCount++; + } + + shaders.vertexPrefix = vertexPrefix; + shaders.fragmentPrefix = fragmentPrefix; + shaders.shaderName = shaderName; + shaders.vertexShader = SHADER_IMAGE_VISUAL_SHADER_VERT; + shaders.fragmentShader = SHADER_IMAGE_VISUAL_SHADER_FRAG; + shaders.shaderCount = shaderCount; +} + } // namespace Internal } // namespace Toolkit