From 70cda53a32b66bcc77619835cc06049635043d91 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Fri, 17 Aug 2018 15:02:58 +0900 Subject: [PATCH] Add ImageVisualShaderFactory - Add ImageVisualShaderFactory to share shader sources - Support custom shader in SVG visual Change-Id: I58ebab4dbbbb3a3976e1ec7ce84ac284f5bc890b --- .../src/dali-toolkit/utc-Dali-ImageVisual.cpp | 74 ++++++++ .../src/dali-toolkit/utc-Dali-Visual.cpp | 48 +++++ dali-toolkit/internal/file.list | 1 + .../animated-image/animated-image-visual.cpp | 20 ++- .../visuals/animated-image/animated-image-visual.h | 14 +- .../visuals/image-visual-shader-factory.cpp | 194 +++++++++++++++++++++ .../internal/visuals/image-visual-shader-factory.h | 94 ++++++++++ .../internal/visuals/image/image-visual.cpp | 165 +++--------------- dali-toolkit/internal/visuals/image/image-visual.h | 23 +-- dali-toolkit/internal/visuals/svg/svg-visual.cpp | 31 +++- dali-toolkit/internal/visuals/svg/svg-visual.h | 23 ++- .../internal/visuals/visual-factory-cache.h | 1 - .../internal/visuals/visual-factory-impl.cpp | 33 ++-- .../internal/visuals/visual-factory-impl.h | 15 +- 14 files changed, 535 insertions(+), 201 deletions(-) create mode 100644 dali-toolkit/internal/visuals/image-visual-shader-factory.cpp create mode 100644 dali-toolkit/internal/visuals/image-visual-shader-factory.h diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index 5cbfc89..90dd9e7 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -2104,3 +2104,77 @@ int UtcDaliImageVisualOrientationCorrection(void) END_TEST; } + +int UtcDaliImageVisualCustomShader(void) +{ + ToolkitTestApplication application; + tet_infoline( "UtcDaliImageVisualCustomShader Test custom shader" ); + + VisualFactory factory = VisualFactory::Get(); + Property::Map properties; + Property::Map shader; + const std::string vertexShader = "Foobar"; + const std::string fragmentShader = "Foobar"; + shader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader; + shader[Visual::Shader::Property::VERTEX_SHADER] = vertexShader; + + properties[Visual::Property::TYPE] = Visual::IMAGE; + properties[Visual::Property::SHADER] = shader; + properties[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + + Visual::Base visual = factory.CreateVisual( properties ); + + // trigger creation through setting on stage + DummyControl dummy = DummyControl::New( true ); + Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummy.GetImplementation() ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + + dummy.SetSize( 200.f, 200.f ); + dummy.SetParentOrigin( ParentOrigin::CENTER ); + Stage::GetCurrent().Add( dummy ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = dummy.GetRendererAt( 0 ); + Shader shader2 = renderer.GetShader(); + Property::Value value = shader2.GetProperty( Shader::Property::PROGRAM ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + + Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_EQUALS( fragmentShader, fragment->Get< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + + shader.Clear(); + + shader[Visual::Shader::Property::HINTS] = Shader::Hint::OUTPUT_IS_TRANSPARENT; + properties[Visual::Property::SHADER] = shader; + + Visual::Base visual1 = factory.CreateVisual( properties ); + + // trigger creation through setting on stage + DummyControl dummy1 = DummyControl::New( true ); + Impl::DummyControl& dummyImpl1 = static_cast< Impl::DummyControl& >( dummy1.GetImplementation() ); + dummyImpl1.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual1 ); + dummy1.SetSize( 200, 200 ); + dummy1.SetParentOrigin( ParentOrigin::CENTER ); + Stage::GetCurrent().Add( dummy1 ); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + glAbstraction.EnableEnableDisableCallTrace( true ); + + application.SendNotification(); + application.Render(); + + TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); + std::ostringstream blendStr; + blendStr << GL_BLEND; + DALI_TEST_CHECK( glEnableStack.FindMethodAndParams( "Enable", blendStr.str().c_str() ) ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index 07c8564..a88c763 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -3514,3 +3514,51 @@ int UtcDaliColorVisualRenderIfTransparentProperty(void) END_TEST; } + +int UtcDaliSvgVisualCustomShader(void) +{ + ToolkitTestApplication application; + tet_infoline( "SvgVisual with custom shader" ); + + VisualFactory factory = VisualFactory::Get(); + Property::Map properties; + Property::Map shader; + const std::string vertexShader = "Foobar"; + const std::string fragmentShader = "Foobar"; + shader[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader; + shader[Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER] = vertexShader; + + properties[Visual::Property::TYPE] = Visual::IMAGE; + properties[Visual::Property::SHADER] = shader; + properties[ImageVisual::Property::URL] = TEST_SVG_FILE_NAME; + + Visual::Base visual = factory.CreateVisual( properties ); + + // trigger creation through setting on stage + DummyControl dummy = DummyControl::New( true ); + Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummy.GetImplementation() ); + dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual ); + + dummy.SetSize( 200.f, 200.f ); + dummy.SetParentOrigin( ParentOrigin::CENTER ); + Stage::GetCurrent().Add( dummy ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = dummy.GetRendererAt( 0 ); + Shader shader2 = renderer.GetShader(); + Property::Value value = shader2.GetProperty( Shader::Property::PROGRAM ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + + Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp + DALI_TEST_EQUALS( fragmentShader, fragment->Get< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + + END_TEST; +} diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 6475502..3f0bd91 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -44,6 +44,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/visuals/transition-data-impl.cpp \ $(toolkit_src_dir)/visuals/texture-manager-impl.cpp \ $(toolkit_src_dir)/visuals/texture-upload-observer.cpp \ + $(toolkit_src_dir)/visuals/image-visual-shader-factory.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 \ diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp index fcb3811..ec58860 100755 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp @@ -30,12 +30,13 @@ #include #include #include +#include #include #include #include -#include #include #include +#include namespace Dali { @@ -100,9 +101,9 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, " * Time */ -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->InitializeGif( imageUrl ); visual->SetProperties( properties ); @@ -114,9 +115,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const Property::Array& imageUrls, const Property::Map& properties ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Property::Array& imageUrls, const Property::Map& properties ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->mImageUrls = new ImageCache::UrlList(); visual->mImageUrls->reserve( imageUrls.Count() ); @@ -138,9 +139,9 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach return visual; } -AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl ) +AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ) { - AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache ) ); + AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) ); visual->InitializeGif( imageUrl ); if( visual->mFrameCount > 0 ) @@ -159,10 +160,11 @@ void AnimatedImageVisual::InitializeGif( const VisualUrl& imageUrl ) mGifLoading->LoadFrameDelays( mFrameDelayContainer ); } -AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache ) +AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ) : Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ), mFrameDelayTimer(), mPlacementActor(), + mImageVisualShaderFactory( shaderFactory ), mPixelArea( FULL_TEXTURE_RECT ), mImageUrl(), mGifLoading( nullptr ), @@ -442,7 +444,7 @@ void AnimatedImageVisual::CreateRenderer() { bool defaultWrapMode = mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE; bool atlasing = false; - Shader shader = ImageVisual::GetImageShader( mFactoryCache, atlasing, defaultWrapMode ); + Shader shader = mImageVisualShaderFactory.GetShader( mFactoryCache, atlasing, defaultWrapMode ); Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); diff --git a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h index 0db9154..b5fbb2e 100644 --- a/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-image/animated-image-visual.h @@ -41,6 +41,7 @@ namespace Toolkit namespace Internal { +class ImageVisualShaderFactory; class AnimatedImageVisual; typedef IntrusivePtr< AnimatedImageVisual > AnimatedImageVisualPtr; @@ -90,29 +91,32 @@ public: * @brief Create the animated image Visual using the image URL. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL to gif resource to use * @param[in] properties A Property::Map containing settings for this visual * @return A smart-pointer to the newly allocated visual. */ - static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties ); + static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ); /** * @brief Create the animated image Visual using image URLs. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrls A Property::Array containing the URLs to the image resources * @param[in] properties A Property::Map containing settings for this visual * @return A smart-pointer to the newly allocated visual. */ - static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const Property::Array& imageUrls, const Property::Map& properties ); + static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Property::Array& imageUrls, const Property::Map& properties ); /** * @brief Create the animated image visual using the image URL. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL to animated image resource to use */ - static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl ); + static AnimatedImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ); public: // from Visual @@ -142,8 +146,9 @@ protected: * @brief Constructor. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object */ - AnimatedImageVisual( VisualFactoryCache& factoryCache ); + AnimatedImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -234,6 +239,7 @@ private: Timer mFrameDelayTimer; WeakHandle mPlacementActor; + ImageVisualShaderFactory& mImageVisualShaderFactory; // Variables for GIF player Dali::Vector mFrameDelayContainer; diff --git a/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp new file mode 100644 index 0000000..3c3fc30 --- /dev/null +++ b/dali-toolkit/internal/visuals/image-visual-shader-factory.cpp @@ -0,0 +1,194 @@ + /* + * Copyright (c) 2018 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 + +// EXTERNAL INCLUDES + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ + +const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); + +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + uniform mediump mat4 uModelMatrix;\n + uniform mediump mat4 uViewMatrix;\n + uniform mediump mat4 uProjection;\n + uniform mediump vec3 uSize;\n + uniform mediump vec4 pixelArea; + varying mediump vec2 vTexCoord;\n + uniform lowp float uPixelAligned;\n + \n + //Visual size and offset + uniform mediump vec2 offset;\n + uniform mediump vec2 size;\n + uniform mediump vec4 offsetSizeMode;\n + uniform mediump vec2 origin;\n + uniform mediump vec2 anchorPoint;\n +\n + vec4 ComputeVertexPosition()\n + {\n + vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n + vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n + return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n + }\n +\n + void main()\n + {\n + mediump vec4 vertexPosition = uViewMatrix * uModelMatrix * ComputeVertexPosition();\n + vec4 alignedVertexPosition = vertexPosition;\n + alignedVertexPosition.xy = floor ( vertexPosition.xy );\n // Pixel alignment + vertexPosition = uProjection * mix( vertexPosition, alignedVertexPosition, uPixelAligned );\n + vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n + gl_Position = vertexPosition;\n + }\n +); + +const char* FRAGMENT_SHADER_NO_ATLAS = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform lowp vec3 mixColor;\n + uniform lowp float preMultipliedAlpha;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n + }\n +); + +const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + uniform lowp vec4 uColor;\n + uniform lowp vec3 mixColor;\n + uniform lowp float preMultipliedAlpha;\n + \n + void main()\n + {\n + mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n + }\n +); + +const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uAtlasRect;\n + // WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT; + uniform lowp vec2 wrapMode;\n + uniform lowp vec4 uColor;\n + uniform lowp vec3 mixColor;\n + uniform lowp float preMultipliedAlpha;\n + \n + mediump float wrapCoordinate( mediump vec2 range, mediump float coordinate, lowp float wrap )\n + {\n + mediump float coord;\n + if( wrap > 1.5 )\n // REFLECT + coord = 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n + else \n// warp == 0 or 1 + coord = mix(coordinate, fract( coordinate ), wrap);\n + return clamp( mix(range.x, range.y, coord), range.x, range.y ); + }\n + \n + void main()\n + {\n + mediump vec2 texCoord = vec2( wrapCoordinate( uAtlasRect.xz, vTexCoord.x, wrapMode.x ), + wrapCoordinate( uAtlasRect.yw, vTexCoord.y, wrapMode.y ) );\n + gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n + }\n +); + +} // unnamed namespace + +ImageVisualShaderFactory::ImageVisualShaderFactory() +{ +} + +ImageVisualShaderFactory::~ImageVisualShaderFactory() +{ +} + +Shader ImageVisualShaderFactory::GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ) +{ + Shader shader; + if( atlasing ) + { + if( defaultTextureWrapping ) + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader ); + } + } + else + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader ); + } + } + } + else + { + shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); + if( !shader ) + { + shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); + } + } + + return shader; +} + +const char* ImageVisualShaderFactory::GetVertexShaderSource() +{ + return VERTEX_SHADER; +} + +const char* ImageVisualShaderFactory::GetFragmentShaderSource() +{ + return FRAGMENT_SHADER_NO_ATLAS; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/visuals/image-visual-shader-factory.h b/dali-toolkit/internal/visuals/image-visual-shader-factory.h new file mode 100644 index 0000000..58b4dd0 --- /dev/null +++ b/dali-toolkit/internal/visuals/image-visual-shader-factory.h @@ -0,0 +1,94 @@ +#ifndef DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FACTORY_H +#define DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FACTORY_H + +/* + * Copyright (c) 2018 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 + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * ImageVisualShaderFactory is an object that provides and shares shaders between image visuals + */ +class ImageVisualShaderFactory +{ +public: + +public: + + /** + * @brief Constructor + */ + ImageVisualShaderFactory(); + + /** + * @brief Destructor + */ + ~ImageVisualShaderFactory(); + + /** + * Get the standard image rendering shader. + * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] atlasing Whether texture atlasing is applied. + * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied. + */ + Shader GetShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ); + + /** + * Request the default vertex shader source. + * @return The default vertex shader source. + */ + const char* GetVertexShaderSource(); + + /** + * Request the default fragment shader source. + * @return The default fragment shader source. + */ + const char* GetFragmentShaderSource(); + +protected: + + /** + * Undefined copy constructor. + */ + ImageVisualShaderFactory(const ImageVisualShaderFactory&); + + /** + * Undefined assignment operator. + */ + ImageVisualShaderFactory& operator=(const ImageVisualShaderFactory& rhs); + +private: +}; + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali + +#endif // DALI_TOOLKIT_IMAGE_VISUAL_SHADER_FACTORY_H diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 2fb7e5d..3f4e763 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -42,6 +42,7 @@ #include #include #include +#include namespace Dali { @@ -112,97 +113,6 @@ const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D"; const float PIXEL_ALIGN_ON = 1.0f; const float PIXEL_ALIGN_OFF = 0.0f; -const char* VERTEX_SHADER = DALI_COMPOSE_SHADER( - attribute mediump vec2 aPosition;\n - uniform mediump mat4 uModelMatrix;\n - uniform mediump mat4 uViewMatrix;\n - uniform mediump mat4 uProjection;\n - uniform mediump vec3 uSize;\n - uniform mediump vec4 pixelArea; - varying mediump vec2 vTexCoord;\n - uniform lowp float uPixelAligned;\n - \n - //Visual size and offset - uniform mediump vec2 offset;\n - uniform mediump vec2 size;\n - uniform mediump vec4 offsetSizeMode;\n - uniform mediump vec2 origin;\n - uniform mediump vec2 anchorPoint;\n -\n - vec4 ComputeVertexPosition()\n - {\n - vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n - vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n - return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n - }\n -\n - void main()\n - {\n - mediump vec4 vertexPosition = uViewMatrix * uModelMatrix * ComputeVertexPosition();\n - vec4 alignedVertexPosition = vertexPosition;\n - alignedVertexPosition.xy = floor ( vertexPosition.xy );\n // Pixel alignment - vertexPosition = uProjection * mix( vertexPosition, alignedVertexPosition, uPixelAligned );\n - vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n - gl_Position = vertexPosition;\n - }\n -); - -const char* FRAGMENT_SHADER_NO_ATLAS = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float preMultipliedAlpha;\n - \n - void main()\n - {\n - gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4( mixColor, 1.0 );\n - }\n -); - -const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform mediump vec4 uAtlasRect;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float preMultipliedAlpha;\n - \n - void main()\n - {\n - mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n - gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n - }\n -); - -const char* FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP = DALI_COMPOSE_SHADER( - varying mediump vec2 vTexCoord;\n - uniform sampler2D sTexture;\n - uniform mediump vec4 uAtlasRect;\n - // WrapMode -- 0: CLAMP; 1: REPEAT; 2: REFLECT; - uniform lowp vec2 wrapMode;\n - uniform lowp vec4 uColor;\n - uniform lowp vec3 mixColor;\n - uniform lowp float preMultipliedAlpha;\n - \n - mediump float wrapCoordinate( mediump vec2 range, mediump float coordinate, lowp float wrap )\n - {\n - mediump float coord;\n - if( wrap > 1.5 )\n // REFLECT - coord = 1.0-abs(fract(coordinate*0.5)*2.0 - 1.0);\n - else \n// warp == 0 or 1 - coord = mix(coordinate, fract( coordinate ), wrap);\n - return clamp( mix(range.x, range.y, coord), range.x, range.y ); - }\n - \n - void main()\n - {\n - mediump vec2 texCoord = vec2( wrapCoordinate( uAtlasRect.xz, vTexCoord.x, wrapMode.x ), - wrapCoordinate( uAtlasRect.yw, vTexCoord.y, wrapMode.y ) );\n - gl_FragColor = texture2D( sTexture, texCoord ) * uColor * vec4( mixColor, 1.0 );\n - }\n -); - Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize ) { Geometry geometry; @@ -222,32 +132,35 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS } // unnamed namespace ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties, ImageDimensions size, FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode ) { - ImageVisualPtr imageVisualPtr( new ImageVisual( factoryCache, imageUrl, size, fittingMode, samplingMode ) ); + ImageVisualPtr imageVisualPtr( new ImageVisual( factoryCache, shaderFactory, imageUrl, size, fittingMode, samplingMode ) ); imageVisualPtr->SetProperties( properties ); return imageVisualPtr; } ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size, FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode ) { - return new ImageVisual( factoryCache, imageUrl, size, fittingMode, samplingMode ); + return new ImageVisual( factoryCache, shaderFactory, imageUrl, size, fittingMode, samplingMode ); } -ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, const Image& image ) +ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ) { - return new ImageVisual( factoryCache, image ); + return new ImageVisual( factoryCache, shaderFactory, image ); } ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size, FittingMode::Type fittingMode, @@ -261,6 +174,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, mDesiredSize( size ), mTextureId( TextureManager::INVALID_TEXTURE_ID ), mTextures(), + mImageVisualShaderFactory( shaderFactory ), mFittingMode( fittingMode ), mSamplingMode( samplingMode ), mWrapModeU( WrapMode::DEFAULT ), @@ -275,7 +189,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, { } -ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image ) +ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ) : Visual::Base( factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ), mImage( image ), mPixelArea( FULL_TEXTURE_RECT ), @@ -285,6 +199,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image ) mDesiredSize(), mTextureId( TextureManager::INVALID_TEXTURE_ID ), mTextures(), + mImageVisualShaderFactory( shaderFactory ), mFittingMode( FittingMode::DEFAULT ), mSamplingMode( SamplingMode::DEFAULT ), mWrapModeU( WrapMode::DEFAULT ), @@ -651,7 +566,7 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet ) { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - shader = GetImageShader( mFactoryCache, + shader = mImageVisualShaderFactory.GetShader( mFactoryCache, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, mWrapModeU <= WrapMode::CLAMP_TO_EDGE && mWrapModeV <= WrapMode::CLAMP_TO_EDGE ); } @@ -660,13 +575,15 @@ void ImageVisual::CreateRenderer( TextureSet& textureSet ) geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) { - shader = GetImageShader( mFactoryCache, false, true ); + // Use custom hints + shader = Shader::New( mImageVisualShaderFactory.GetVertexShaderSource(), mImageVisualShaderFactory.GetFragmentShaderSource(), mImpl->mCustomShader->mHints ); + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } else { - shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, - mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER_NO_ATLAS : mImpl->mCustomShader->mFragmentShader, - mImpl->mCustomShader->mHints ); + shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader, + mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mHints ); if( mImpl->mCustomShader->mVertexShader.empty() ) { shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); @@ -713,7 +630,7 @@ void ImageVisual::CreateNativeImageRenderer( NativeImage& nativeImage ) } else { - fragmentShader += FRAGMENT_SHADER_NO_ATLAS; + fragmentShader += mImageVisualShaderFactory.GetFragmentShaderSource(); } if( customSamplerTypename ) @@ -725,13 +642,13 @@ void ImageVisual::CreateNativeImageRenderer( NativeImage& nativeImage ) { geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) ); - shader = Shader::New( VERTEX_SHADER, fragmentShader ); + shader = Shader::New( mImageVisualShaderFactory.GetVertexShaderSource(), fragmentShader ); shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); } else { geometry = CreateGeometry( mFactoryCache, mImpl->mCustomShader->mGridSize ); - shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, + shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader, fragmentShader, mImpl->mCustomShader->mHints ); if( mImpl->mCustomShader->mVertexShader.empty() ) @@ -998,46 +915,6 @@ bool ImageVisual::IsResourceReady() const mImpl->mResourceStatus == Toolkit::Visual::ResourceStatus::FAILED ); } -Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ) -{ - Shader shader; - if( atlasing ) - { - if( defaultTextureWrapping ) - { - shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader ); - } - } - else - { - shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_VARIOUS_WRAP ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_CUSTOM_WRAP, shader ); - } - } - } - else - { - shader = factoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER ); - if( !shader ) - { - shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_NO_ATLAS ); - shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); - factoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER, shader ); - } - } - - return shader; -} - void ImageVisual::ApplyImageToSampler( const Image& image ) { if( image ) diff --git a/dali-toolkit/internal/visuals/image/image-visual.h b/dali-toolkit/internal/visuals/image/image-visual.h index dd63c16..c693f0b 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.h +++ b/dali-toolkit/internal/visuals/image/image-visual.h @@ -46,6 +46,7 @@ namespace Toolkit namespace Internal { +class ImageVisualShaderFactory; class ImageVisual; typedef IntrusivePtr< ImageVisual > ImageVisualPtr; @@ -121,6 +122,7 @@ public: * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL of the image resource to use * @param[in] properties A Property::Map containing settings for this visual * @param[in] size The width and height to fit the loaded image to. @@ -129,6 +131,7 @@ public: * @return A smart-pointer to the newly allocated visual. */ static ImageVisualPtr New( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties, ImageDimensions size = ImageDimensions(), @@ -141,6 +144,7 @@ public: * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL of the image resource to use * @param[in] size The width and height to fit the loaded image to. * @param[in] fittingMode The FittingMode of the resource to load @@ -148,6 +152,7 @@ public: * @return A smart-pointer to the newly allocated visual. */ static ImageVisualPtr New( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions(), FittingMode::Type fittingMode = FittingMode::DEFAULT, @@ -157,9 +162,10 @@ public: * @brief Create a new image visual with an Image type. * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] image The image to use */ - static ImageVisualPtr New( VisualFactoryCache& factoryCache, const Image& image ); + static ImageVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ); public: // from Visual @@ -191,12 +197,14 @@ protected: * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL of the image resource to use * @param[in] size The width and height to fit the loaded image to. * @param[in] fittingMode The FittingMode of the resource to load * @param[in] samplingMode The SamplingMode of the resource to load */ ImageVisual( VisualFactoryCache& factoryCache, + ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size, FittingMode::Type fittingMode, @@ -206,9 +214,10 @@ protected: * @brief Constructor with an Image type. * * @param[in] factoryCache The VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] image The image to use */ - ImageVisual( VisualFactoryCache& factoryCache, const Image& image ); + ImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const Image& image ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -243,14 +252,6 @@ protected: public: /** - * Get the standard image rendering shader. - * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object - * @param[in] atlasing Whether texture atlasing is applied. - * @param[in] defaultTextureWrapping Whether the default texture wrap mode is applied. - */ - static Shader GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping ); - - /** * @copydoc AtlasUploadObserver::UploadCompleted * * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready. @@ -367,6 +368,8 @@ private: TextureManager::TextureId mTextureId; TextureSet mTextures; + ImageVisualShaderFactory& mImageVisualShaderFactory; + Dali::FittingMode::Type mFittingMode:3; Dali::SamplingMode::Type mSamplingMode:4; Dali::WrapMode::Type mWrapModeU:3; diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index bf7641d..f59901c 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -30,12 +30,11 @@ #include #include #include -#include #include #include #include #include - +#include namespace { @@ -56,25 +55,26 @@ namespace Toolkit namespace Internal { -SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties ) +SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ) { - SvgVisualPtr svgVisual( new SvgVisual( factoryCache ) ); + SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory ) ); svgVisual->ParseFromUrl( imageUrl ); svgVisual->SetProperties( properties ); return svgVisual; } -SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl ) +SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ) { - SvgVisualPtr svgVisual( new SvgVisual( factoryCache ) ); + SvgVisualPtr svgVisual( new SvgVisual( factoryCache, shaderFactory ) ); svgVisual->ParseFromUrl( imageUrl ); return svgVisual; } -SvgVisual::SvgVisual( VisualFactoryCache& factoryCache ) +SvgVisual::SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ) : Visual::Base( factoryCache, Visual::FittingMode::FILL ), + mImageVisualShaderFactory( shaderFactory ), mAtlasRect( FULL_TEXTURE_RECT ), mImageUrl( ), mParsedImage( NULL ), @@ -125,7 +125,20 @@ void SvgVisual::DoSetProperty( Property::Index index, const Property::Value& val void SvgVisual::DoSetOnStage( Actor& actor ) { - Shader shader = ImageVisual::GetImageShader( mFactoryCache, mAttemptAtlasing, true ); + Shader shader; + if( !mImpl->mCustomShader ) + { + shader = mImageVisualShaderFactory.GetShader( mFactoryCache, mAttemptAtlasing, true ); + } + else + { + shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? mImageVisualShaderFactory.GetVertexShaderSource() : mImpl->mCustomShader->mVertexShader, + mImpl->mCustomShader->mFragmentShader.empty() ? mImageVisualShaderFactory.GetFragmentShaderSource() : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mHints ); + + shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT ); + } + Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY ); TextureSet textureSet = TextureSet::New(); mImpl->mRenderer = Renderer::New( geometry, shader ); @@ -219,7 +232,7 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData ) TextureSet textureSet; - if( mAttemptAtlasing ) + if( mAttemptAtlasing && !mImpl->mCustomShader ) { Vector4 atlasRect; textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData ); diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.h b/dali-toolkit/internal/visuals/svg/svg-visual.h index 7852bfc..e516186 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.h +++ b/dali-toolkit/internal/visuals/svg/svg-visual.h @@ -37,6 +37,7 @@ namespace Toolkit namespace Internal { +class ImageVisualShaderFactory; class SvgVisual; typedef IntrusivePtr< SvgVisual > SvgVisualPtr; @@ -61,11 +62,12 @@ public: * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL to svg resource to use * @param[in] properties A Property::Map containing settings for this visual * @return A smart-pointer to the newly allocated visual. */ - static SvgVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl, const Property::Map& properties ); + static SvgVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties ); /** * @brief Create the SVG Visual using the image URL. @@ -74,10 +76,11 @@ public: * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object * @param[in] imageUrl The URL to svg resource to use * @return A smart-pointer to the newly allocated visual. */ - static SvgVisualPtr New( VisualFactoryCache& factoryCache, const VisualUrl& imageUrl ); + static SvgVisualPtr New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl ); public: // from Visual @@ -102,8 +105,9 @@ protected: * @brief Constructor. * * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object + * @param[in] shaderFactory The ImageVisualShaderFactory object */ - SvgVisual( VisualFactoryCache& factoryCache ); + SvgVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory ); /** * @brief A reference counted object may only be deleted by calling Unreference(). @@ -170,12 +174,13 @@ private: SvgVisual& operator=( const SvgVisual& svgRenderer ); private: - Vector4 mAtlasRect; - VisualUrl mImageUrl; - NSVGimage* mParsedImage; - WeakHandle mPlacementActor; - Vector2 mVisualSize; - bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture + ImageVisualShaderFactory& mImageVisualShaderFactory; + Vector4 mAtlasRect; + VisualUrl mImageUrl; + NSVGimage* mParsedImage; + WeakHandle mPlacementActor; + Vector2 mVisualSize; + bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-factory-cache.h b/dali-toolkit/internal/visuals/visual-factory-cache.h index a62dfb4..f2c8120 100644 --- a/dali-toolkit/internal/visuals/visual-factory-cache.h +++ b/dali-toolkit/internal/visuals/visual-factory-cache.h @@ -68,7 +68,6 @@ public: IMAGE_SHADER_ATLAS_CUSTOM_WRAP, NINE_PATCH_SHADER, NINE_PATCH_MASK_SHADER, - SVG_SHADER, TEXT_SHADER_MULTI_COLOR_TEXT, TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE, TEXT_SHADER_SINGLE_COLOR_TEXT, diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.cpp b/dali-toolkit/internal/visuals/visual-factory-impl.cpp index e762b3e..4afade9 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-factory-impl.cpp @@ -45,6 +45,7 @@ #include #include #include +#include namespace Dali { @@ -73,6 +74,7 @@ const char * const BROKEN_IMAGE_URL( DALI_IMAGE_DIR "broken.png" ); ///< URL Fo VisualFactory::VisualFactory( bool debugEnabled ) : mFactoryCache(), + mImageVisualShaderFactory(), mSlotDelegate(this), mDebugEnabled( debugEnabled ), mPreMultiplyOnLoad( true ) @@ -151,17 +153,17 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property } case VisualUrl::SVG: { - visualPtr = SvgVisual::New( GetFactoryCache(), visualUrl, propertyMap ); + visualPtr = SvgVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap ); break; } case VisualUrl::GIF: { - visualPtr = AnimatedImageVisual::New( GetFactoryCache(), visualUrl, propertyMap ); + visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap ); break; } case VisualUrl::REGULAR_IMAGE: { - visualPtr = ImageVisual::New( GetFactoryCache(), visualUrl, propertyMap ); + visualPtr = ImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap ); break; } } @@ -172,7 +174,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property Property::Array* array = imageURLValue->GetArray(); if( array ) { - visualPtr = AnimatedImageVisual::New( GetFactoryCache(), *array, propertyMap ); + visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap ); } } } @@ -220,7 +222,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property std::string imageUrl; if( imageURLValue && imageURLValue->Get( imageUrl ) ) { - visualPtr = SvgVisual::New( GetFactoryCache(), imageUrl, propertyMap ); + visualPtr = SvgVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap ); } break; } @@ -233,14 +235,14 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property { if( imageURLValue->Get( imageUrl ) ) { - visualPtr = AnimatedImageVisual::New( GetFactoryCache(), imageUrl, propertyMap ); + visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap ); } else { Property::Array* array = imageURLValue->GetArray(); if( array ) { - visualPtr = AnimatedImageVisual::New( GetFactoryCache(), *array, propertyMap ); + visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap ); } } } @@ -281,7 +283,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Image& image ) } else { - visualPtr = ImageVisual::New(GetFactoryCache(), image ); + visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), image ); } } @@ -311,17 +313,17 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image } case VisualUrl::SVG: { - visualPtr = SvgVisual::New( GetFactoryCache(), visualUrl ); + visualPtr = SvgVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl ); break; } case VisualUrl::GIF: { - visualPtr = AnimatedImageVisual::New( GetFactoryCache(), visualUrl ); + visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl ); break; } case VisualUrl::REGULAR_IMAGE: { - visualPtr = ImageVisual::New(GetFactoryCache(), visualUrl, size ); + visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size ); break; } } @@ -375,6 +377,15 @@ Internal::VisualFactoryCache& VisualFactory::GetFactoryCache() return *mFactoryCache; } +ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory() +{ + if( !mImageVisualShaderFactory ) + { + mImageVisualShaderFactory = std::unique_ptr< ImageVisualShaderFactory >( new ImageVisualShaderFactory() ); + } + return *mImageVisualShaderFactory; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/visuals/visual-factory-impl.h b/dali-toolkit/internal/visuals/visual-factory-impl.h index a9a6563..0e4dcb4 100644 --- a/dali-toolkit/internal/visuals/visual-factory-impl.h +++ b/dali-toolkit/internal/visuals/visual-factory-impl.h @@ -37,6 +37,7 @@ namespace Internal { class VisualFactoryCache; +class ImageVisualShaderFactory; /** * @copydoc Toolkit::VisualFactory @@ -103,15 +104,21 @@ private: */ Internal::VisualFactoryCache& GetFactoryCache(); + /** + * Get the image visual shader factory, creating it if necessary. + */ + ImageVisualShaderFactory& GetImageVisualShaderFactory(); + VisualFactory(const VisualFactory&) = delete; VisualFactory& operator=(const VisualFactory& rhs) = delete; private: - std::unique_ptr mFactoryCache; - SlotDelegate< VisualFactory > mSlotDelegate; - bool mDebugEnabled:1; - bool mPreMultiplyOnLoad:1; ///< Local store for this flag + std::unique_ptr< VisualFactoryCache > mFactoryCache; + std::unique_ptr< ImageVisualShaderFactory > mImageVisualShaderFactory; + SlotDelegate< VisualFactory > mSlotDelegate; + bool mDebugEnabled:1; + bool mPreMultiplyOnLoad:1; ///< Local store for this flag }; /** -- 2.7.4