Add GetVisualProperty to Control
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / color / color-visual.cpp
index dce5255..68dc04a 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 
 //INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
@@ -43,140 +44,139 @@ namespace Internal
 namespace
 {
 
-const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\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
-  uniform mediump vec2 extraSize;\n
-
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\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
-
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  \n
-  void main()\n
-  {\n
-    gl_FragColor = vec4(mixColor, 1.0)*uColor;\n
-  }\n
-);
-
-const char* VERTEX_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\n
-  \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
-  uniform mediump vec2 extraSize;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump float cornerRadius;\n
-  uniform mediump float cornerRadiusPolicy;\n
-  \n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    mediump float minSize = min( visualSize.x, visualSize.y );\n
-    vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n
-    vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n
-    vRectSize = visualSize / 2.0 - vCornerRadius;\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-  \n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
+const char* VERTEX_SHADER =
+  "INPUT mediump vec2 aPosition;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump vec2 extraSize;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\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"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
+
+
+const char* FRAGMENT_SHADER =
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+
+  "void main()\n"
+  "{\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "}\n";
+
+const char* VERTEX_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+  "OUTPUT mediump vec2 vRectSize;\n"
+  "OUTPUT mediump float vCornerRadius;\n"
+
+  "uniform highp mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec2 extraSize;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump float cornerRadius;\n"
+  "uniform mediump float cornerRadiusPolicy;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  mediump float minSize = min( visualSize.x, visualSize.y );\n"
+  "  vCornerRadius = mix( cornerRadius * minSize, cornerRadius, cornerRadiusPolicy);\n"
+  "  vCornerRadius = min( vCornerRadius, minSize * 0.5 );\n"
+  "  vRectSize = visualSize / 2.0 - vCornerRadius;\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
 
 //float distance = length( max( abs( position - center ), size ) - size ) - radius;
-const char* FRAGMENT_SHADER_ROUNDED_CORNER = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  varying mediump float vCornerRadius;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  \n
-  void main()\n
-  {\n
-      mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n
-      gl_FragColor = uColor * vec4( mixColor, 1.0 );\n
-      gl_FragColor.a *= 1.0 - smoothstep( -1.0, 1.0, dist );\n
-  }\n
-);
-
-const char* VERTEX_SHADER_BLUR_EDGE = DALI_COMPOSE_SHADER(
-  attribute mediump vec2 aPosition;\n
-  uniform highp   mat4 uMvpMatrix;\n
-  uniform mediump vec3 uSize;\n
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  \n
-  //Visual size and offset
-  uniform mediump vec2 offset;\n
-  uniform mediump vec2 size;\n
-  uniform mediump vec2 extraSize;\n
-  uniform mediump vec4 offsetSizeMode;\n
-  uniform mediump vec2 origin;\n
-  uniform mediump vec2 anchorPoint;\n
-  uniform mediump float blurRadius;\n
-  \n
-  vec4 ComputeVertexPosition()\n
-  {\n
-    vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize + blurRadius * 2.0;\n
-    vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
-    vRectSize = visualSize / 2.0;\n
-    vPosition = aPosition* visualSize;\n
-    return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
-  }\n
-  \n
-  void main()\n
-  {\n
-    gl_Position = uMvpMatrix * ComputeVertexPosition();\n
-  }\n
-);
-
-const char* FRAGMENT_SHADER_BLUR_EDGE = DALI_COMPOSE_SHADER(
-  varying mediump vec2 vPosition;\n
-  varying mediump vec2 vRectSize;\n
-  uniform lowp vec4 uColor;\n
-  uniform lowp vec3 mixColor;\n
-  uniform mediump float blurRadius;\n
-  \n
-  void main()\n
-  {\n
-      mediump vec2 blur = 1.0 - smoothstep( vRectSize - blurRadius * 2.0, vRectSize, abs( vPosition ) );\n
-      gl_FragColor = uColor * vec4( mixColor, 1.0 );\n
-      gl_FragColor.a *= blur.x * blur.y;\n
-  }\n
-);
+const char* FRAGMENT_SHADER_ROUNDED_CORNER =
+  "INPUT mediump vec2 vPosition;\n"
+  "INPUT mediump vec2 vRectSize;\n"
+  "INPUT mediump float vCornerRadius;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump float dist = length( max( abs( vPosition ), vRectSize ) - vRectSize ) - vCornerRadius;\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "  OUT_COLOR.a *= 1.0 - smoothstep( -1.0, 1.0, dist );\n"
+  "}\n";
+
+const char* VERTEX_SHADER_BLUR_EDGE =
+  "INPUT mediump vec2 aPosition;\n"
+  "OUTPUT mediump vec2 vPosition;\n"
+  "OUTPUT mediump vec2 vRectSize;\n"
+
+  "uniform highp   mat4 uMvpMatrix;\n"
+  "uniform highp vec3 uSize;\n"
+
+  "//Visual size and offset\n"
+  "uniform mediump vec2 offset;\n"
+  "uniform highp vec2 size;\n"
+  "uniform mediump vec2 extraSize;\n"
+  "uniform mediump vec4 offsetSizeMode;\n"
+  "uniform mediump vec2 origin;\n"
+  "uniform mediump vec2 anchorPoint;\n"
+  "uniform mediump float blurRadius;\n"
+
+  "vec4 ComputeVertexPosition()\n"
+  "{\n"
+  "  vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw ) + extraSize + blurRadius * 2.0;\n"
+  "  vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n"
+  "  vRectSize = visualSize / 2.0;\n"
+  "  vPosition = aPosition* visualSize;\n"
+  "  return vec4( vPosition + anchorPoint*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n"
+  "}\n"
+
+  "void main()\n"
+  "{\n"
+  "  gl_Position = uMvpMatrix * ComputeVertexPosition();\n"
+  "}\n";
+
+const char* FRAGMENT_SHADER_BLUR_EDGE =
+  "INPUT mediump vec2 vPosition;\n"
+  "INPUT mediump vec2 vRectSize;\n"
+
+  "uniform lowp vec4 uColor;\n"
+  "uniform lowp vec3 mixColor;\n"
+  "uniform mediump float blurRadius;\n"
+
+  "void main()\n"
+  "{\n"
+  "  mediump vec2 blur = 1.0 - smoothstep( vRectSize - blurRadius * 2.0, vRectSize, abs( vPosition ) );\n"
+  "  OUT_COLOR = vec4(mixColor, 1.0) * uColor;\n"
+  "  OUT_COLOR.a *= blur.x * blur.y;\n"
+  "}\n";
 
 }
 
@@ -187,10 +187,12 @@ ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache, const Propert
   return colorVisualPtr;
 }
 
-ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
-: Visual::Base( factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR ),
-  mBlurRadius( 0.0f ),
-  mRenderIfTransparent( false )
+ColorVisual::ColorVisual(VisualFactoryCache& factoryCache)
+: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR),
+  mBlurRadius(0.0f),
+  mBlurRadiusIndex(Property::INVALID_INDEX),
+  mRenderIfTransparent(false),
+  mNeedBlurRadius(false)
 {
 }
 
@@ -259,13 +261,36 @@ void ColorVisual::DoSetOnScene( Actor& actor )
   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
 }
 
+void ColorVisual::DoSetOffScene(Actor& actor)
+{
+  if(mImpl->mRenderer && mBlurRadiusIndex != Property::INVALID_INDEX)
+  {
+    // Update values from Renderer
+    mBlurRadius = mImpl->mRenderer.GetProperty<float>(mBlurRadiusIndex);
+  }
+
+  actor.RemoveRenderer(mImpl->mRenderer);
+  mImpl->mRenderer.Reset();
+  mBlurRadiusIndex = Property::INVALID_INDEX;
+}
+
 void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
 {
   map.Clear();
   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR );
   map.Insert( Toolkit::ColorVisual::Property::MIX_COLOR, mImpl->mMixColor );
   map.Insert( Toolkit::DevelColorVisual::Property::RENDER_IF_TRANSPARENT, mRenderIfTransparent );
-  map.Insert( Toolkit::DevelColorVisual::Property::BLUR_RADIUS, mBlurRadius );
+
+  if(mImpl->mRenderer && mBlurRadiusIndex != Property::INVALID_INDEX)
+  {
+    // Update values from Renderer
+    float blurRadius = mImpl->mRenderer.GetProperty<float>(mBlurRadiusIndex);
+    map.Insert(Toolkit::DevelColorVisual::Property::BLUR_RADIUS, blurRadius);
+  }
+  else
+  {
+    map.Insert(Toolkit::DevelColorVisual::Property::BLUR_RADIUS, mBlurRadius);
+  }
 }
 
 void ColorVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -273,7 +298,6 @@ void ColorVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
   // Do nothing
 }
 
-
 void ColorVisual::OnSetTransform()
 {
   if( mImpl->mRenderer )
@@ -289,7 +313,7 @@ void ColorVisual::OnDoAction( const Property::Index actionId, const Property::Va
   {
     case DevelColorVisual::Action::UPDATE_PROPERTY:
     {
-      Property::Map* map = attributes.GetMap();
+      const Property::Map* map = attributes.GetMap();
       if( map )
       {
         DoSetProperties( *map );
@@ -299,17 +323,47 @@ void ColorVisual::OnDoAction( const Property::Index actionId, const Property::Va
   }
 }
 
+void ColorVisual::UpdateShader()
+{
+  if(mImpl->mRenderer)
+  {
+    Shader shader = GetShader();
+    mImpl->mRenderer.SetShader(shader);
+  }
+}
+
 void ColorVisual::InitializeRenderer()
 {
   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
 
+  Shader shader = GetShader();
+
+  mImpl->mRenderer = Renderer::New(geometry, shader);
+
+  // ColorVisual has it's own index key for mix color - use this instead
+  // of using the new base index to avoid changing existing applications
+  // String keys will get to this property.
+  mImpl->mMixColorIndex = mImpl->mRenderer.RegisterProperty(Toolkit::ColorVisual::Property::MIX_COLOR, MIX_COLOR, Vector3(mImpl->mMixColor));
+
+  if(!EqualsZero(mBlurRadius))
+  {
+    mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius);
+    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+  }
+
+  // Register transform properties
+  mImpl->mTransform.RegisterUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+}
+
+Shader ColorVisual::GetShader()
+{
   Shader shader;
-  if( !EqualsZero( mBlurRadius ) )
+  if(!EqualsZero(mBlurRadius) || mNeedBlurRadius)
   {
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_BLUR_EDGE );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER_BLUR_EDGE, FRAGMENT_SHADER_BLUR_EDGE );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_BLUR_EDGE, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_BLUR_EDGE );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER_BLUR_EDGE, shader );
     }
   }
@@ -318,7 +372,7 @@ void ColorVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER, shader );
     }
   }
@@ -327,27 +381,38 @@ void ColorVisual::InitializeRenderer()
     shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER );
     if( !shader )
     {
-      shader = Shader::New( VERTEX_SHADER_ROUNDED_CORNER, FRAGMENT_SHADER_ROUNDED_CORNER );
+      shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + VERTEX_SHADER_ROUNDED_CORNER, Dali::Shader::GetFragmentShaderPrefix() + FRAGMENT_SHADER_ROUNDED_CORNER );
       mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER_ROUNDED_CORNER, shader );
     }
   }
 
-  mImpl->mRenderer = Renderer::New( geometry, shader );
-
-  // ColorVisual has it's own index key for mix color - use this instead
-  // of using the new base index to avoid changing existing applications
-  // String keys will get to this property.
-  mImpl->mMixColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::ColorVisual::Property::MIX_COLOR, MIX_COLOR, Vector3(mImpl->mMixColor) );
+  return shader;
+}
 
-  mImpl->mRenderer.RegisterProperty( BLUR_RADIUS_NAME, mBlurRadius );
+Dali::Property ColorVisual::OnGetPropertyObject(Dali::Property::Key key)
+{
+  if(!mImpl->mRenderer)
+  {
+    Handle handle;
+    return Dali::Property(handle, Property::INVALID_INDEX);
+  }
 
-  if( mImpl->mMixColor.a < 1.f || !EqualsZero( mBlurRadius ) )
+  if((key.type == Property::Key::INDEX && key.indexKey == DevelColorVisual::Property::BLUR_RADIUS) || (key.type == Property::Key::STRING && key.stringKey == BLUR_RADIUS_NAME))
   {
-    mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+    mBlurRadiusIndex = mImpl->mRenderer.RegisterProperty(DevelColorVisual::Property::BLUR_RADIUS, BLUR_RADIUS_NAME, mBlurRadius);
+
+    mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON);
+
+    mNeedBlurRadius = true;
+
+    // Change shader
+    UpdateShader();
+
+    return Dali::Property(mImpl->mRenderer, mBlurRadiusIndex);
   }
 
-  // Register transform properties
-  mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
+  Handle handle;
+  return Dali::Property(handle, Property::INVALID_INDEX);
 }
 
 } // namespace Internal