From cde5ef8b9c6de8008865e29f3b1acab8f7cd2bbc Mon Sep 17 00:00:00 2001 From: Chu Hoang Date: Mon, 28 Sep 2015 16:55:44 +0100 Subject: [PATCH] Implemented custom shader in ImageRenderer and changed Dissolve-effect to utilise this. Change-Id: I3275449610040b533cca265445c4c1a65a35b404 --- .../src/dali-toolkit/utc-Dali-ShaderEffects.cpp | 63 +++++- .../controls/renderer-factory/renderer-factory.cpp | 5 + .../controls/renderer-factory/renderer-factory.h | 13 ++ .../devel-api/shader-effects/dissolve-effect.h | 203 +++++++++++------ .../controls/image-view/image-view-impl.cpp | 17 +- .../controls/renderers/border/border-renderer.cpp | 4 +- .../controls/renderers/border/border-renderer.h | 6 +- .../controls/renderers/color/color-renderer.cpp | 4 +- .../controls/renderers/color/color-renderer.h | 6 +- .../renderers/control-renderer-data-impl.cpp | 247 +++++++++++++++++++++ .../renderers/control-renderer-data-impl.h | 21 +- .../controls/renderers/control-renderer-impl.cpp | 43 +++- .../controls/renderers/control-renderer-impl.h | 43 +++- .../renderers/gradient/gradient-renderer.cpp | 4 +- .../renderers/gradient/gradient-renderer.h | 6 +- .../controls/renderers/image/image-renderer.cpp | 164 ++++++++++++-- .../controls/renderers/image/image-renderer.h | 6 +- .../controls/renderers/npatch/npatch-renderer.cpp | 4 +- .../controls/renderers/npatch/npatch-renderer.h | 6 +- .../controls/renderers/renderer-factory-impl.cpp | 42 ++++ .../controls/renderers/renderer-factory-impl.h | 7 +- dali-toolkit/internal/file.list | 1 + 22 files changed, 782 insertions(+), 133 deletions(-) create mode 100644 dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp index cc5195d..33dfee4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ShaderEffects.cpp @@ -123,24 +123,69 @@ int UtcDaliCreateDisplacementEffectFixed(void) END_TEST; } -int UtcDaliCreateDissolveEffect(void) +int UtcDaliCreateDissolveEffect( bool highPrecision ) { ToolkitTestApplication application; - ShaderEffect effect = Toolkit::CreateDissolveEffect(); - DALI_TEST_CHECK( effect ); + Property::Map effect = Toolkit::CreateDissolveEffect( highPrecision ); + DALI_TEST_CHECK( !effect.Empty() ); + + Property::Value* customShaderValue = effect.Find( "shader" ); + DALI_TEST_CHECK( customShaderValue ); + + Property::Map customShader; + DALI_TEST_CHECK( customShaderValue->Get( customShader ) ); + + Property::Value* vertexShaderValue = customShader.Find( "vertex-shader" ); + DALI_TEST_CHECK( vertexShaderValue ); + + std::string vertexShader; + DALI_TEST_CHECK( vertexShaderValue->Get( vertexShader ) ); + DALI_TEST_CHECK( !vertexShader.empty() ); + + Property::Value* fragmentShaderValue = customShader.Find( "fragment-shader" ); + DALI_TEST_CHECK( fragmentShaderValue ); + + std::string fragmentShader; + DALI_TEST_CHECK( fragmentShaderValue->Get( fragmentShader ) ); + DALI_TEST_CHECK( !fragmentShader.empty() ); + + Property::Value* gridXValue = customShader.Find( "subdivide-grid-x" ); + DALI_TEST_CHECK( gridXValue ); + + int gridX = 0; + DALI_TEST_CHECK( gridXValue->Get( gridX ) ); + DALI_TEST_CHECK( gridX > 1 ); + + Property::Value* gridYValue = customShader.Find( "subdivide-grid-y" ); + DALI_TEST_CHECK( gridYValue ); + + int gridY = 0; + DALI_TEST_CHECK( gridYValue->Get( gridY ) ); + DALI_TEST_CHECK( gridY > 1 ); + + Property::Value* hintsValue = customShader.Find( "hints" ); + DALI_TEST_CHECK( hintsValue ); + + std::string hints; + DALI_TEST_CHECK( hintsValue->Get( hints ) ); + DALI_TEST_CHECK( hints == "output-is-transparent" ); + + Actor actor = Actor::New(); + Toolkit::DissolveEffectSetCentralLine( actor, Vector2::ONE, Vector2::ONE, 0.0f ); + DALI_TEST_CHECK( actor.GetPropertyIndex( "uPercentage" ) != Property::INVALID_INDEX ); END_TEST; } -int UtcDaliCreateDissolveEffectMediumPrecision(void) +int UtcDaliCreateDissolveEffectHighPrecision(void) { - ToolkitTestApplication application; - - ShaderEffect effect = Toolkit::CreateDissolveEffect(false); - DALI_TEST_CHECK( effect ); + return UtcDaliCreateDissolveEffect(true); +} - END_TEST; +int UtcDaliCreateDissolveEffectMediumPrecision(void) +{ + return UtcDaliCreateDissolveEffect(false); } int UtcDaliCreateDissolveLocalEffect(void) diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp index ce70893..3f7ef6c 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.cpp @@ -122,6 +122,11 @@ bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const std::strin return GetImplementation( *this ).ResetRenderer( renderer, url ); } +bool RendererFactory::ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap ) +{ + return GetImplementation( *this ).ResetRenderer( renderer, propertyMap ); +} + } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h index c4ac6a4..13242f4 100644 --- a/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h +++ b/dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h @@ -163,6 +163,19 @@ public: */ bool ResetRenderer( ControlRenderer& renderer, const std::string& url ); + + /** + * @brief Request the current control renderer from the property map, merging the property map with the renderer + * + * if the current renderer is capable of merging with the property map the reset the renderer with the merged properties + * else the renderer would be a handle to a newly created internal renderer. + * + * @param[in] propertyMap The map contains the properties required by the control renderer + * Depends on the content of the map, different kind of renderer would be returned. + * @return Whether a new internal control renderer is created. + */ + bool ResetRenderer( ControlRenderer& renderer, const Property::Map& propertyMap ); + private: explicit DALI_INTERNAL RendererFactory(Internal::RendererFactory *impl); diff --git a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h index 4aee8cc..95cccc8 100644 --- a/dali-toolkit/devel-api/shader-effects/dissolve-effect.h +++ b/dali-toolkit/devel-api/shader-effects/dissolve-effect.h @@ -19,7 +19,40 @@ */ // EXTERNAL INCLUDES -#include +#include +#include + +namespace +{ + template < typename T> + void SafeSetCustomProperty( Dali::Actor& actor, const std::string& name, const T& value ) + { + Dali::Property::Index index = actor.GetPropertyIndex( name ); + if ( Dali::Property::INVALID_INDEX == index ) + { + index = actor.RegisterProperty( name, value ); + } + else + { + actor.SetProperty( index, value ); + } + } + + template < typename T> + void SafeSetCustomProperty( Dali::Actor& actor, const std::string& name, const T& value, Dali::Property::AccessMode accessMode ) + { + Dali::Property::Index index = actor.GetPropertyIndex( name ); + if ( Dali::Property::INVALID_INDEX == index ) + { + index = actor.RegisterProperty( name, value, accessMode ); + } + else + { + actor.SetProperty( index, value ); + } + } + +}; namespace Dali { @@ -34,11 +67,11 @@ namespace Toolkit * As we use the texture coordinate as pixel position to calculate random offset, * the line should passing through rectangle {(0,0),(0,1),(1,0),(1,1)}, * so make the position parameter with two component values between 0.0 to 1.0 - * @param[in] dissolveEffect The shader effect * @param[in] position The point ( locates within rectangle {(0,0),(0,1),(1,0),(1,1)} ) passed through by the central line * @param[in] displacement The direction of the central line + * @param[in] initialProgress, the normalised initial progress of the shader */ -inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Vector2& position, const Vector2& displacement ) +inline void DissolveEffectSetCentralLine( Actor& actor, const Vector2& position, const Vector2& displacement, float initialProgress ) { // the line passes through 'position' and has the direction of 'displacement' float coefA, coefB, coefC; //line equation: Ax+By+C=0; @@ -102,10 +135,11 @@ inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Ve rotation = Vector2(-displacement.x, displacement.y); rotation.Normalize(); - dissolveEffect.SetUniform( "uSaddleParam", saddleParam ); - dissolveEffect.SetUniform( "uTranslation", translation ); - dissolveEffect.SetUniform( "uRotation", rotation ); - dissolveEffect.SetUniform( "uToNext", toNext ); + SafeSetCustomProperty( actor, "uSaddleParam", saddleParam ); + SafeSetCustomProperty( actor, "uTranslation", translation ); + SafeSetCustomProperty( actor, "uRotation", rotation ); + SafeSetCustomProperty( actor, "uToNext", toNext ); + SafeSetCustomProperty( actor, "uPercentage", initialProgress, Dali::Property::ANIMATABLE ); } /** * @brief Create a new Dissolve effect @@ -119,69 +153,108 @@ inline void DissolveEffectSetCentralLine( ShaderEffect& dissolveEffect, const Ve * @return A handle to a newly allocated ShaderEffect */ -inline ShaderEffect CreateDissolveEffect(bool useHighPrecision = true) +inline Property::Map CreateDissolveEffect( bool useHighPrecision = true ) { - std::string prefixHighPrecision( "precision highp float;\n"); - std::string prefixMediumPrecision( "precision mediump float;\n" ); - std::string vertexShader( - "uniform float uPercentage;\n" - "uniform vec3 uSaddleParam;\n" - "uniform vec2 uTranslation;\n" - "uniform vec2 uRotation; \n" - "uniform float uToNext;\n" - "varying float vPercentage;\n" - "void main()\n" - "{\n" - "gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n" - "vTexCoord = aTexCoord;\n" - //Calculate the distortion value given the dissolve central line - "vec2 texCoor = vec2( (aTexCoord.s - sTextureRect.s ) / (sTextureRect.p - sTextureRect.s), (aTexCoord.t- sTextureRect.t)/(sTextureRect.q - sTextureRect.t) ); \n" - "vec2 value = texCoor + uTranslation; \n" - "mat2 rotateMatrix = mat2( uRotation.s, uRotation.t, -uRotation.t, uRotation.s ); \n" - "value = rotateMatrix * value; \n" - "if(uToNext == 1.0) \n" - " value.s = uSaddleParam[2] + value.s; \n" - "float delay = value.t*value.t / uSaddleParam[0] - value.s*value.s/uSaddleParam[1];\n" - "vPercentage = clamp( uPercentage*2.0 - 0.5*sin(delay*1.571) - 0.5, 0.0, 1.0 ); \n" - "}\n"); - std::string fragmentShader( - "varying float vPercentage;\n" - "float rand(vec2 co) \n" - "{\n" - " return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n" - "}\n" - "void main()\n" - "{\n" - //Calculate the randomness - "float offsetS = rand( vTexCoord * vPercentage ) * (sTextureRect.p - sTextureRect.s) - vTexCoord.s + sTextureRect.s; \n" - "float offsetT = rand( vec2(vTexCoord.t*vPercentage, vTexCoord.s * vPercentage) ) * (sTextureRect.q - sTextureRect.t) - vTexCoord.t + sTextureRect.t; \n" - "vec2 lookupCoord = vTexCoord + vec2(offsetS, offsetT) * vPercentage; \n" - "gl_FragColor = texture2D( sTexture, lookupCoord ) * uColor; \n" - "gl_FragColor.a *= 1.0 - vPercentage; \n" - "}" ); - - // Create the implementation, temporarily owned on stack, - Dali::ShaderEffect shaderEffect; - if( useHighPrecision ) - { - shaderEffect = Dali::ShaderEffect::New( - prefixHighPrecision+vertexShader, prefixHighPrecision + fragmentShader, - ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_BLENDING ) ); - } - else - { - shaderEffect = Dali::ShaderEffect::New( - prefixMediumPrecision+vertexShader, prefixMediumPrecision + fragmentShader, - ShaderEffect::GeometryHints( ShaderEffect::HINT_GRID | ShaderEffect::HINT_BLENDING ) ); - } + const char* prefixHighPrecision( "precision highp float;\n"); + const char* prefixMediumPrecision( "precision mediump float;\n" ); + + const char* vertexShader( DALI_COMPOSE_SHADER( + attribute mediump vec2 aPosition;\n + \n + uniform mediump mat4 uMvpMatrix;\n + uniform vec3 uSize;\n + uniform vec4 uTextureRect; + \n + uniform float uPercentage;\n + uniform vec3 uSaddleParam;\n + uniform vec2 uTranslation;\n + uniform vec2 uRotation; \n + uniform float uToNext;\n + \n + varying float vPercentage;\n + varying vec2 vTexCoord;\n + + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n + vertexPosition.xyz *= uSize;\n + vertexPosition = uMvpMatrix * vertexPosition;\n + gl_Position = vertexPosition;\n + + vec2 texCoord = aPosition + vec2(0.5); + vTexCoord = texCoord;\n + //Calculate the distortion value given the dissolve central line + vec2 value = texCoord + uTranslation; \n + mat2 rotateMatrix = mat2( uRotation.s, uRotation.t, -uRotation.t, uRotation.s ); \n + value = rotateMatrix * value; \n + if(uToNext == 1.0) \n + value.s = uSaddleParam[2] + value.s; \n + float delay = value.t*value.t / uSaddleParam[0] - value.s*value.s/uSaddleParam[1];\n + vPercentage = clamp( uPercentage*2.0 - 0.5*sin(delay*1.571) - 0.5, 0.0, 1.0 ); \n + }) + ); + + const char* fragmentShader( DALI_COMPOSE_SHADER( + varying float vPercentage;\n + varying mediump vec2 vTexCoord;\n + \n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform vec4 uTextureRect; + \n + float rand(vec2 co) \n + {\n + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); \n + }\n + \n + void main()\n + {\n + + //Calculate the randomness + float offsetS = rand( vTexCoord * vPercentage ) - vTexCoord.s; \n + float offsetT = rand( vec2(vTexCoord.t*vPercentage, vTexCoord.s * vPercentage) ) - vTexCoord.t; \n + vec2 lookupCoord = vTexCoord + vec2(offsetS, offsetT) * vPercentage; \n + gl_FragColor = texture2D( sTexture, lookupCoord ) * uColor; \n + gl_FragColor.a *= 1.0 - vPercentage; \n + } ) + ); + + Property::Map map; + + Property::Map customShader; + + std::string vertexShaderString; + std::string fragmentShaderString; + if( useHighPrecision ) + { + vertexShaderString.reserve(strlen( prefixHighPrecision ) + strlen( vertexShader )); + vertexShaderString.append( prefixHighPrecision ); + + fragmentShaderString.reserve(strlen( prefixHighPrecision ) + strlen( fragmentShader )); + fragmentShaderString.append( prefixHighPrecision ); + } + else + { + vertexShaderString.reserve(strlen( prefixMediumPrecision ) + strlen( vertexShader )); + vertexShaderString.append( prefixMediumPrecision ); + + fragmentShaderString.reserve(strlen( prefixMediumPrecision ) + strlen( fragmentShader )); + fragmentShaderString.append( prefixMediumPrecision ); + } + + vertexShaderString.append( vertexShader ); + fragmentShaderString.append( fragmentShader ); - shaderEffect.SetUniform( "uPercentage", 0.0f ); - shaderEffect.SetProperty( ShaderEffect::Property::GRID_DENSITY, Dali::Property::Value(50.0f) ); + customShader[ "vertex-shader" ] = vertexShaderString; + customShader[ "fragment-shader" ] = fragmentShaderString; - DissolveEffectSetCentralLine( shaderEffect, Vector2(1.0f,0.5f), Vector2(-1.0f, 0.0f) ); + customShader[ "subdivide-grid-x" ] = 20; + customShader[ "subdivide-grid-y" ] = 20; - return shaderEffect; + customShader[ "hints" ] = "output-is-transparent"; + map[ "shader" ] = customShader; + return map; } } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp index 76493a6..554469b 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -97,16 +97,23 @@ void ImageView::SetImage( Image image ) void ImageView::SetImage( Property::Map map ) { - mImage.Reset(); - mUrl.clear(); mPropertyMap = map; - mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mPropertyMap ); + bool newRendererCreated = false; + if( mRenderer ) + { + newRendererCreated = Toolkit::RendererFactory::Get().ResetRenderer( mRenderer, mPropertyMap ); + } + else + { + mRenderer = Toolkit::RendererFactory::Get().GetControlRenderer( mPropertyMap ); + newRendererCreated = true; + } //we need to inform any newly created renderers if it is on stage - if( Self().OnStage() ) + CustomActor self = Self(); + if( newRendererCreated && self.OnStage() ) { - CustomActor self = Self(); mRenderer.SetOnStage( self ); } diff --git a/dali-toolkit/internal/controls/renderers/border/border-renderer.cpp b/dali-toolkit/internal/controls/renderers/border/border-renderer.cpp index 423afc2..6542a2c 100644 --- a/dali-toolkit/internal/controls/renderers/border/border-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/border/border-renderer.cpp @@ -88,7 +88,7 @@ BorderRenderer::~BorderRenderer() { } -void BorderRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void BorderRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { Initialize( factoryCache ); @@ -122,7 +122,7 @@ void BorderRenderer::DoSetOnStage( Actor& actor ) mBorderSizeIndex = (mImpl->mRenderer).RegisterProperty( SIZE_UNIFORM_NAME, mBorderSize ); } -void BorderRenderer::CreatePropertyMap( Property::Map& map ) const +void BorderRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); diff --git a/dali-toolkit/internal/controls/renderers/border/border-renderer.h b/dali-toolkit/internal/controls/renderers/border/border-renderer.h index c05ea1c..9c53935 100644 --- a/dali-toolkit/internal/controls/renderers/border/border-renderer.h +++ b/dali-toolkit/internal/controls/renderers/border/border-renderer.h @@ -60,9 +60,9 @@ public: public: // from ControlRenderer /** - * @copydoc ControlRenderer::Initialize + * @copydoc ControlRenderer::DoInitialize */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc ControlRenderer::SetClipRect @@ -78,7 +78,7 @@ protected: /** * @copydoc ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const; + virtual void DoCreatePropertyMap( Property::Map& map ) const; public: diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp index 0da8112..68164ea 100644 --- a/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.cpp @@ -77,7 +77,7 @@ ColorRenderer::~ColorRenderer() { } -void ColorRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void ColorRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { Initialize( factoryCache ); @@ -107,7 +107,7 @@ void ColorRenderer::SetOffset( const Vector2& offset ) //ToDo: renderer applies the offset } -void ColorRenderer::CreatePropertyMap( Property::Map& map ) const +void ColorRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); diff --git a/dali-toolkit/internal/controls/renderers/color/color-renderer.h b/dali-toolkit/internal/controls/renderers/color/color-renderer.h index cec5b3a..ae5ccca 100644 --- a/dali-toolkit/internal/controls/renderers/color/color-renderer.h +++ b/dali-toolkit/internal/controls/renderers/color/color-renderer.h @@ -56,9 +56,9 @@ public: public: // from ControlRenderer /** - * @copydoc ControlRenderer::Initialize + * @copydoc ControlRenderer::DoInitialize */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc ControlRenderer::SetSize @@ -78,7 +78,7 @@ public: // from ControlRenderer /** * @copydoc ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const; + virtual void DoCreatePropertyMap( Property::Map& map ) const; protected: /** diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp new file mode 100644 index 0000000..6a58cfb --- /dev/null +++ b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.cpp @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2015 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 "control-renderer-data-impl.h" + +// EXTERNAL HEADER +#include +#include +#include + +// EXTERNAL HEADER + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ +//custom shader +const char * const CUSTOM_SHADER( "shader" ); +const char * const CUSTOM_VERTEX_SHADER( "vertex-shader" ); +const char * const CUSTOM_FRAGMENT_SHADER( "fragment-shader" ); +const char * const CUSTOM_SUBDIVIDE_GRID_X( "subdivide-grid-x" ); +const char * const CUSTOM_SUBDIVIDE_GRID_Y( "subdivide-grid-y" ); +const char * const CUSTOM_SHADER_HINTS( "hints" ); ///< type STRING for a hint from the below hint strings or an ARRAY of of hint strings + +/** + * where hints should be contain strings of the following shader hints: + * "none" | corresponds to HINT_NONE + * "requires-self-depth-test" | corresponds to HINT_REQUIRES_SELF_DEPTH_TEST + * "output-is-transparent" | corresponds to HINT_OUTPUT_IS_TRANSPARENT + * "output-is-opaque" | corresponds to HINT_OUTPUT_IS_OPAQUE + * "modifies-geometry" | corresponds to HINT_MODIFIES_GEOMETRY + */ + +Shader::ShaderHints HintFromString( std::string hintString ) +{ + if( hintString == "none" ) + { + return Shader::HINT_NONE; + } + else if( hintString == "requires-self-depth-test" ) + { + return Shader::HINT_REQUIRES_SELF_DEPTH_TEST; + } + else if( hintString == "output-is-transparent" ) + { + return Shader::HINT_OUTPUT_IS_TRANSPARENT; + } + else if( hintString == "output-is-opaque" ) + { + return Shader::HINT_OUTPUT_IS_OPAQUE; + } + else if( hintString == "modifies-geometry" ) + { + return Shader::HINT_MODIFIES_GEOMETRY; + } + else + { + DALI_LOG_ERROR( "'%s' hint string is not recognised", hintString.c_str() ); + } + + return Shader::HINT_NONE; +} + +}// unnamed namespace + +Internal::ControlRenderer::Impl::Impl() +: mCustomShader(NULL), + mDepthIndex( 0.0f ), + mIsOnStage( false ) +{ +} + +Internal::ControlRenderer::Impl::~Impl() +{ + delete mCustomShader; +} + +Internal::ControlRenderer::Impl::CustomShader::CustomShader( const Property::Map& map ) +: mGridSize( 1, 1 ), + mHints( Shader::HINT_NONE ) +{ + SetPropertyMap( map ); +} + +void Internal::ControlRenderer::Impl::CustomShader::SetPropertyMap( const Property::Map& propertyMap ) +{ + Property::Value* shaderValue = propertyMap.Find( CUSTOM_SHADER ); + if( shaderValue ) + { + mVertexShader.clear(); + mFragmentShader.clear(); + mGridSize = ImageDimensions( 1, 1 ); + mHints = Shader::HINT_NONE; + + Property::Map shaderMap; + if( shaderValue->Get( shaderMap ) ) + { + Property::Value* vertexShaderValue = shaderMap.Find( CUSTOM_VERTEX_SHADER ); + if( vertexShaderValue ) + { + if( !vertexShaderValue->Get( mVertexShader ) ) + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a string", CUSTOM_VERTEX_SHADER ); + } + } + + Property::Value* fragmentShaderValue = shaderMap.Find( CUSTOM_FRAGMENT_SHADER ); + if( fragmentShaderValue ) + { + if( !fragmentShaderValue->Get( mFragmentShader ) ) + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a string", CUSTOM_FRAGMENT_SHADER ); + } + } + + Property::Value* subdivideXValue = shaderMap.Find( CUSTOM_SUBDIVIDE_GRID_X ); + if( subdivideXValue ) + { + int subdivideX; + if( !subdivideXValue->Get( subdivideX ) || subdivideX < 1 ) + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a value greater than 1", CUSTOM_SUBDIVIDE_GRID_X ); + } + else + { + mGridSize = ImageDimensions( subdivideX, mGridSize.GetY() ); + } + } + + Property::Value* subdivideYValue = shaderMap.Find( CUSTOM_SUBDIVIDE_GRID_Y ); + if( subdivideYValue ) + { + int subdivideY; + if( !subdivideYValue->Get( subdivideY ) || subdivideY < 1 ) + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a value greater than 1", CUSTOM_SUBDIVIDE_GRID_Y ); + } + else + { + mGridSize = ImageDimensions( mGridSize.GetX(), subdivideY ); + } + } + + Property::Value* hintsValue = shaderMap.Find( CUSTOM_SHADER_HINTS ); + if( hintsValue ) + { + std::string hintString; + Property::Array hintsArray; + + if( hintsValue->Get( hintString ) ) + { + mHints = HintFromString( hintString ); + } + else if( hintsValue->Get( hintsArray ) ) + { + int hints = Shader::HINT_NONE; + for( Property::Array::SizeType i = 0; i < hintsArray.Count(); ++i) + { + Property::Value hintValue = hintsArray[ i ]; + if( hintValue.Get( hintString ) ) + { + hints |= static_cast< int >( HintFromString( hintString ) ); + } + else + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify an hint string at index %d", CUSTOM_SHADER_HINTS, i ); + } + + mHints = static_cast< Shader::ShaderHints >( hints ); + } + } + else + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a hint string or an array of hint strings", CUSTOM_SHADER_HINTS ); + } + } + } + else + { + //use value with no type to mean reseting the shader back to default + if( shaderValue->GetType() != Dali::Property::NONE ) + { + DALI_LOG_ERROR( "'%s' parameter does not correctly specify a property map", CUSTOM_SHADER ); + } + } + } +} + +void Internal::ControlRenderer::Impl::CustomShader::CreatePropertyMap( Property::Map& map ) const +{ + if( !mVertexShader.empty() || !mFragmentShader.empty() ) + { + Property::Map customShader; + if( !mVertexShader.empty() ) + { + customShader.Insert(CUSTOM_VERTEX_SHADER, mVertexShader ); + } + if( !mFragmentShader.empty() ) + { + customShader.Insert(CUSTOM_FRAGMENT_SHADER, mFragmentShader ); + } + + if( mGridSize.GetWidth() != 1 ) + { + customShader.Insert(CUSTOM_SUBDIVIDE_GRID_X, mGridSize.GetWidth() ); + } + if( mGridSize.GetHeight() != 1 ) + { + customShader.Insert(CUSTOM_SUBDIVIDE_GRID_Y, mGridSize.GetHeight() ); + } + + if( mHints != Dali::Shader::HINT_NONE ) + { + customShader.Insert(CUSTOM_SHADER_HINTS, static_cast< int >(mHints) ); + } + + map.Insert( CUSTOM_SHADER, customShader ); + } +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h index e865a0e..47095c9 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h +++ b/dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h @@ -18,10 +18,12 @@ * */ -// INTERNAL INCLUDES +// EXTERNAL INCLUDES #include #include +#include + namespace Dali { @@ -33,15 +35,32 @@ namespace Internal struct Internal::ControlRenderer::Impl { + struct CustomShader + { + std::string mVertexShader; + std::string mFragmentShader; + Dali::ImageDimensions mGridSize; + Dali::Shader::ShaderHints mHints; //(bitfield) values from enum Shader::Hints + + CustomShader( const Property::Map& map ); + void SetPropertyMap( const Property::Map& map ); + void CreatePropertyMap( Property::Map& map ) const; + }; + Geometry mGeometry; Shader mShader; Renderer mRenderer; + CustomShader* mCustomShader; + Vector2 mSize; Vector2 mOffset; Rect mClipRect; float mDepthIndex; bool mIsOnStage; + + Impl(); + ~Impl(); }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp index 1fa7bf3..91343a4 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.cpp @@ -20,10 +20,22 @@ // EXTERNAL HEADER #include +#include //INTERNAL HEARDER #include +namespace +{ +//custom shader +const char * const CUSTOM_SHADER( "shader" ); +const char * const CUSTOM_VERTEX_SHADER( "vertex-shader" ); +const char * const CUSTOM_FRAGMENT_SHADER( "fragment-shader" ); +const char * const CUSTOM_SUBDIVIDE_GRID_X( "subdivide-grid-x" ); +const char * const CUSTOM_SUBDIVIDE_GRID_Y( "subdivide-grid-y" ); +const char * const CUSTOM_SHADER_HINTS( "hints" ); ///< type INTEGER; (bitfield) values from enum Shader::Hints +} + namespace Dali { @@ -36,7 +48,6 @@ namespace Internal ControlRenderer::ControlRenderer() : mImpl( new Impl() ) { - mImpl->mIsOnStage = false; } ControlRenderer::~ControlRenderer() @@ -44,6 +55,27 @@ ControlRenderer::~ControlRenderer() delete mImpl; } +void ControlRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +{ + if( mImpl->mCustomShader ) + { + mImpl->mCustomShader->SetPropertyMap( propertyMap ); + } + else + { + Property::Value* customShaderValue = propertyMap.Find( CUSTOM_SHADER ); + if( customShaderValue ) + { + Property::Map customShader; + if( customShaderValue->Get( customShader ) ) + { + mImpl->mCustomShader = new Impl::CustomShader( propertyMap ); + } + } + } + DoInitialize( factoryCache, propertyMap ); +} + void ControlRenderer::SetSize( const Vector2& size ) { mImpl->mSize = size; @@ -115,6 +147,15 @@ void ControlRenderer::DoSetOffStage( Actor& actor ) { } +void ControlRenderer::CreatePropertyMap( Property::Map& map ) const +{ + if( mImpl->mCustomShader ) + { + mImpl->mCustomShader->CreatePropertyMap( map ); + } + DoCreatePropertyMap( map ); +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h index 773e7c0..4dea2d9 100644 --- a/dali-toolkit/internal/controls/renderers/control-renderer-impl.h +++ b/dali-toolkit/internal/controls/renderers/control-renderer-impl.h @@ -21,7 +21,10 @@ // EXTERNAL INCLUDES #include +#include +#include +// INTERNAL INCLUDES #include #include @@ -40,6 +43,21 @@ class RendererFactoryCache; * Base class for all Control rendering logic. A control may have multiple control renderers. * * Note: The control renderer responds to the the Actor::COLOR by blending it with the 'Multiply' operator. + * + * The following properties are optional + * + * | %Property Name | Type | + * |---------------------------|------------------| + * | custom-shader | MAP | + * + * where custom-shader is a map with the following properties: + * | %Property Name | Type | + * |---------------------------|------------------| + * | vertex-shader | STRING | + * | fragment-shader | STRING | + * | subdivide-grid-x | INT | + * | subdivide-grid-y | INT | + * | shader-hints | INT | */ class ControlRenderer : public BaseObject { @@ -53,7 +71,7 @@ public: * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object * @param[in] propertyMap The properties for the requested ControlRenderer object. */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) = 0; + void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc Toolkit::ControlRenderer::SetSize @@ -113,7 +131,7 @@ public: /** * @copydoc Toolkit::ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const = 0; + void CreatePropertyMap( Property::Map& map ) const; protected: @@ -128,16 +146,32 @@ protected: virtual ~ControlRenderer(); protected: + /** + * @brief Called by CreatePropertyMap() allowing sub classes to respond to the CreatePropertyMap event + * + * @param[out] map The renderer property map. + */ + virtual void DoCreatePropertyMap( Property::Map& map ) const = 0; /** - * Called by SetOnStage() allowing sub classes to respond to the SetOnStage event + * @brief Called by Initialize() allowing sub classes to respond to the Initialize event + * + * @param[in] factoryCache A pointer pointing to the RendererFactoryCache object + * @param[in] propertyMap The properties for the requested ControlRenderer object. + */ + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) = 0; + +protected: + + /** + * @brief Called by SetOnStage() allowing sub classes to respond to the SetOnStage event * * @param[in] actor The actor applying this renderer. */ virtual void DoSetOnStage( Actor& actor ); /** - * Called by SetOffStage() allowing sub classes to respond to the SetOffStage event + * @brief Called by SetOffStage() allowing sub classes to respond to the SetOffStage event * * @param[in] actor The actor applying this renderer. */ @@ -152,7 +186,6 @@ private: ControlRenderer& operator=( const ControlRenderer& renderer ); protected: - struct Impl; Impl* mImpl; }; diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp index 396ded3..0e502da 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.cpp @@ -143,7 +143,7 @@ GradientRenderer::~GradientRenderer() { } -void GradientRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void GradientRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); if( !(mImpl->mGeometry) ) @@ -214,7 +214,7 @@ void GradientRenderer::SetOffset( const Vector2& offset ) //ToDo: renderer applies the offset } -void GradientRenderer::CreatePropertyMap( Property::Map& map ) const +void GradientRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); diff --git a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h index e35b5db..1ee3f36 100644 --- a/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h +++ b/dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h @@ -84,9 +84,9 @@ public: public: // from ControlRenderer /** - * @copydoc ControlRenderer::Initialize + * @copydoc ControlRenderer::DoInitialize */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc ControlRenderer::SetSize @@ -106,7 +106,7 @@ public: // from ControlRenderer /** * @copydoc ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const; + virtual void DoCreatePropertyMap( Property::Map& map ) const; protected: /** diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index b84b5f5..4770960 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -18,11 +18,15 @@ // CLASS HEADER #include "image-renderer.h" +// EXTERNAL HEADER +#include +#include + +// INTERNAL HEADER #include #include #include #include -#include namespace Dali { @@ -39,11 +43,11 @@ const char * const RENDERER_TYPE("renderer-type"); const char * const RENDERER_TYPE_VALUE("image-renderer"); // property names -const char * const IMAGE_URL_NAME("image-url"); -const char * const IMAGE_FITTING_MODE("image-fitting-mode"); -const char * const IMAGE_SAMPLING_MODE("image-sampling-mode"); -const char * const IMAGE_DESIRED_WIDTH("image-desired-width"); -const char * const IMAGE_DESIRED_HEIGHT("image-desired-height"); +const char * const IMAGE_URL_NAME( "image-url" ); +const char * const IMAGE_FITTING_MODE( "image-fitting-mode" ); +const char * const IMAGE_SAMPLING_MODE( "image-sampling-mode" ); +const char * const IMAGE_DESIRED_WIDTH( "image-desired-width" ); +const char * const IMAGE_DESIRED_HEIGHT( "image-desired-height" ); // fitting modes const char * const SHRINK_TO_FIT("shrink-to-fit"); @@ -91,6 +95,93 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( }\n ); +void AddQuadIndices( Vector< unsigned int >& indices, unsigned int rowIdx, unsigned int nextRowIdx ) +{ + indices.PushBack( rowIdx ); + indices.PushBack( nextRowIdx + 1 ); + indices.PushBack( rowIdx + 1 ); + + indices.PushBack( rowIdx ); + indices.PushBack( nextRowIdx ); + indices.PushBack( nextRowIdx + 1 ); +} + +Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices ) +{ + Property::Map vertexFormat; + vertexFormat[ "aPosition" ] = Property::VECTOR2; + PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat, vertices.Size() ); + if( vertices.Size() > 0 ) + { + vertexPropertyBuffer.SetData( &vertices[ 0 ] ); + } + + Property::Map indexFormat; + indexFormat[ "indices" ] = Property::INTEGER; + PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat, indices.Size() ); + if( indices.Size() > 0 ) + { + indexPropertyBuffer.SetData( &indices[ 0 ] ); + } + + // Create the geometry object + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( vertexPropertyBuffer ); + geometry.SetIndexBuffer( indexPropertyBuffer ); + + return geometry; +} + +Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gridSize ) +{ + Geometry geometry; + + if( gridSize == ImageDimensions( 1, 1 ) ) + { + geometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); + if( !geometry ) + { + geometry = factoryCache.CreateQuadGeometry(); + factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry ); + } + } + else + { + uint16_t gridWidth = gridSize.GetWidth(); + uint16_t gridHeight = gridSize.GetHeight(); + + // Create vertices + Vector< Vector2 > vertices; + vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) ); + + for( int y = 0; y < gridHeight + 1; ++y ) + { + for( int x = 0; x < gridWidth + 1; ++x ) + { + vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight - 0.5f) ); + } + } + + // Create indices + Vector< unsigned int > indices; + indices.Reserve( gridWidth * gridHeight * 6 ); + + unsigned int rowIdx = 0; + unsigned int nextRowIdx = gridWidth + 1; + for( int y = 0; y < gridHeight; ++y, ++nextRowIdx, ++rowIdx ) + { + for( int x = 0; x < gridWidth; ++x, ++nextRowIdx, ++rowIdx ) + { + AddQuadIndices( indices, rowIdx, nextRowIdx ); + } + } + + return GenerateGeometry( vertices, indices ); + } + + return geometry; +} + } //unnamed namespace ImageRenderer::ImageRenderer() @@ -105,7 +196,7 @@ ImageRenderer::~ImageRenderer() { } -void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void ImageRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { Initialize(factoryCache); @@ -113,6 +204,10 @@ void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Proper if( imageURLValue ) { imageURLValue->Get( mImageUrl ); + if( !mImageUrl.empty() ) + { + mImage.Reset(); + } Property::Value* fittingValue = propertyMap.Find( IMAGE_FITTING_MODE ); if( fittingValue ) @@ -208,8 +303,6 @@ void ImageRenderer::Initialize( RendererFactoryCache& factoryCache, const Proper mDesiredSize = ImageDimensions( desiredWidth, desiredHeight ); } - - mImage.Reset(); } void ImageRenderer::SetSize( const Vector2& size ) @@ -270,7 +363,7 @@ void ImageRenderer::DoSetOffStage( Actor& actor ) } } -void ImageRenderer::CreatePropertyMap( Property::Map& map ) const +void ImageRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); @@ -368,24 +461,49 @@ void ImageRenderer::CreatePropertyMap( Property::Map& map ) const void ImageRenderer::Initialize( RendererFactoryCache& factoryCache ) { - mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); - if( !(mImpl->mGeometry) ) + if( !mImpl->mCustomShader ) { - mImpl->mGeometry = factoryCache.CreateQuadGeometry(); - factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry ); - } + mImpl->mGeometry = CreateGeometry( factoryCache, ImageDimensions( 1, 1 ) ); + + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER ); - mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER ); - if( !mImpl->mShader ) + if( !mImpl->mShader ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader ); + } + } + else { - mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); - factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader ); + mImpl->mGeometry = CreateGeometry( factoryCache, mImpl->mCustomShader->mGridSize ); + + if( mImpl->mCustomShader->mVertexShader.empty() && mImpl->mCustomShader->mFragmentShader.empty() ) + { + mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::IMAGE_SHADER ); + + if( !mImpl->mShader ) + { + mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); + factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, mImpl->mShader ); + } + } + else + { + mImpl->mShader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader, + mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader, + mImpl->mCustomShader->mHints ); + } } - mDesiredSize = ImageDimensions(); - mFittingMode = FittingMode::DEFAULT; - mSamplingMode = SamplingMode::DEFAULT; - mImageUrl.clear(); + if( mImpl->mRenderer ) + { + mImpl->mRenderer.SetGeometry( mImpl->mGeometry ); + Material material = mImpl->mRenderer.GetMaterial(); + if( material ) + { + material.SetShader( mImpl->mShader ); + } + } } void ImageRenderer::SetImage( const std::string& imageUrl ) diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.h b/dali-toolkit/internal/controls/renderers/image/image-renderer.h index fd88df0..367ae31 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.h +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.h @@ -85,9 +85,9 @@ public: public: // from ControlRenderer /** - * @copydoc ControlRenderer::Initialize + * @copydoc ControlRenderer::DoInitialize */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc ControlRenderer::SetSize @@ -112,7 +112,7 @@ public: // from ControlRenderer /** * @copydoc ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const; + virtual void DoCreatePropertyMap( Property::Map& map ) const; protected: /** diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp index aa52f3e..842a099 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.cpp @@ -160,7 +160,7 @@ NPatchRenderer::~NPatchRenderer() { } -void NPatchRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) +void NPatchRenderer::DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ) { Initialize(factoryCache); @@ -243,7 +243,7 @@ void NPatchRenderer::DoSetOffStage( Actor& actor ) mCroppedImage.Reset(); } -void NPatchRenderer::CreatePropertyMap( Property::Map& map ) const +void NPatchRenderer::DoCreatePropertyMap( Property::Map& map ) const { map.Clear(); map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE ); diff --git a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h index 0bcd28a..6e5bd5d 100644 --- a/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h +++ b/dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h @@ -66,9 +66,9 @@ public: public: // from ControlRenderer /** - * @copydoc ControlRenderer::Initialize + * @copydoc ControlRenderer::DoInitialize */ - virtual void Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); + virtual void DoInitialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap ); /** * @copydoc ControlRenderer::GetNaturalSize @@ -88,7 +88,7 @@ public: // from ControlRenderer /** * @copydoc ControlRenderer::CreatePropertyMap */ - virtual void CreatePropertyMap( Property::Map& map ) const; + virtual void DoCreatePropertyMap( Property::Map& map ) const; protected: /** diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp index 92fd3bf..afcc452 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.cpp @@ -274,6 +274,48 @@ bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const s } } +bool RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap ) +{ + Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME ); + std::string typeValue ; + if( type && type->Get( typeValue )) + { + //If there's been a renderer type change then we have to return a new shader + if( typeValue == COLOR_RENDERER && typeid( renderer ) != typeid( ColorRenderer ) ) + { + renderer = GetControlRenderer( propertyMap ); + return true; + } + else if( typeValue == GRADIENT_RENDERER && typeid( renderer ) != typeid( GradientRenderer ) ) + { + renderer = GetControlRenderer( propertyMap ); + return true; + } + else if( typeValue == IMAGE_RENDERER && typeid( renderer ) != typeid( ImageRenderer ) ) + { + renderer = GetControlRenderer( propertyMap ); + return true; + } + else if( typeValue == N_PATCH_RENDERER && typeid( renderer ) != typeid( NPatchRenderer ) ) + { + renderer = GetControlRenderer( propertyMap ); + return true; + } + else if( typeValue == BORDER_RENDERER && typeid( renderer ) != typeid( BorderRenderer ) ) + { + renderer = GetControlRenderer( propertyMap ); + return true; + } + } + + if( !mFactoryCache ) + { + mFactoryCache = new RendererFactoryCache(); + } + GetImplementation( renderer ).Initialize( *( mFactoryCache.Get() ), propertyMap ); + return false; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h index 4ed7e7f..99ef2b8 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-impl.h @@ -52,7 +52,12 @@ public: /** * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Property::Map& ) */ - Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + Toolkit::ControlRenderer GetControlRenderer( const Property::Map& propertyMap ); + + /** + * @copydoc Toolkit::RenderFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap ) + */ + bool ResetRenderer( Toolkit::ControlRenderer& renderer, const Property::Map& propertyMap ); /** * @copydoc Toolkit::RenderFactory::GetControlRenderer( const Vector4& ) diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 6c8c9b7..9ecd378 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -13,6 +13,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/builder/tree-node-manipulator.cpp \ $(toolkit_src_dir)/builder/replacement.cpp \ $(toolkit_src_dir)/controls/renderers/control-renderer-impl.cpp \ + $(toolkit_src_dir)/controls/renderers/control-renderer-data-impl.cpp \ $(toolkit_src_dir)/controls/renderers/renderer-factory-cache.cpp \ $(toolkit_src_dir)/controls/renderers/renderer-factory-impl.cpp \ $(toolkit_src_dir)/controls/renderers/border/border-renderer.cpp \ -- 2.7.4