[4.0] Support custom shader in svg visual 78/165078/1
authorHeeyong Song <heeyong.song@samsung.com>
Thu, 14 Dec 2017 00:29:38 +0000 (09:29 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 26 Dec 2017 03:00:49 +0000 (12:00 +0900)
Change-Id: I928296c64c614c8e4cf9b8bfb1258f90d651a1e9

automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp

index bf54997..ee8010b 100644 (file)
@@ -19,6 +19,7 @@
 #include <unistd.h>
 
 #include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
 #include <dali/devel-api/object/handle-devel.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
@@ -2998,6 +2999,133 @@ int UtcDaliNPatchVisualCustomShader(void)
   END_TEST;
 }
 
+int UtcDaliSvgVisualCustomShader(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "SvgVisual with custom shader" );
+
+  // Vertex & fragment shader
+  const std::string vertexShader = "Foobar";
+  const std::string fragmentShader = "Foobar";
+  Property::Map properties;
+  Property::Map shaderProperty1;
+  shaderProperty1[Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER] = vertexShader;
+  shaderProperty1[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader;
+
+  properties[Visual::Property::TYPE] = Visual::SVG;
+  properties[Visual::Property::SHADER] = shaderProperty1;
+  properties[ImageVisual::Property::URL] = TEST_SVG_FILE_NAME;
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( properties );
+
+  // trigger creation through setting on stage
+  DummyControl dummy = DummyControl::New( true );
+  Impl::DummyControl& dummyImpl1 = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+
+  dummyImpl1.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+  dummy.SetSize( 200, 200 );
+  Stage::GetCurrent().Add( dummy );
+
+  visual.SetTransformAndSize( DefaultTransform(), Vector2( 100, 100 ) );
+
+  application.SendNotification();
+
+  // Wait for image to load
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  Renderer renderer = dummy.GetRendererAt( 0 );
+  Shader shader = renderer.GetShader();
+  Property::Value value = shader.GetProperty( Shader::Property::PROGRAM );
+  Property::Map* map = value.GetMap();
+  DALI_TEST_CHECK( map );
+
+  Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+  DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION );
+
+  Property::Value* fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+  DALI_TEST_EQUALS( fragmentShader, fragment->Get< std::string >(), TEST_LOCATION );
+
+  // Vertex shader only
+  Property::Map shaderProperty2;
+  shaderProperty2[Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER] = vertexShader;
+
+  properties[Visual::Property::TYPE] = Visual::SVG;
+  properties[Visual::Property::SHADER] = shaderProperty2;
+  properties[ImageVisual::Property::URL] = TEST_SVG_FILE_NAME;
+
+  visual = factory.CreateVisual( properties );
+
+  // trigger creation through setting on stage
+  dummy = DummyControl::New( true );
+  Impl::DummyControl& dummyImpl2 = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+
+  dummyImpl2.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+  dummy.SetSize( 200, 200 );
+  Stage::GetCurrent().Add( dummy );
+
+  visual.SetTransformAndSize( DefaultTransform(), Vector2( 100, 100 ) );
+
+  application.SendNotification();
+
+  // Wait for image to load
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  renderer = dummy.GetRendererAt( 0 );
+  shader = renderer.GetShader();
+  value = shader.GetProperty( Shader::Property::PROGRAM );
+  map = value.GetMap();
+  DALI_TEST_CHECK( map );
+
+  vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp
+  DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION );
+
+  // Fragment shader only
+  Property::Map shaderProperty3;
+  shaderProperty3[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader;
+
+  properties[Visual::Property::TYPE] = Visual::SVG;
+  properties[Visual::Property::SHADER] = shaderProperty3;
+  properties[ImageVisual::Property::URL] = TEST_SVG_FILE_NAME;
+
+  visual = factory.CreateVisual( properties );
+
+  // trigger creation through setting on stage
+  dummy = DummyControl::New( true );
+  Impl::DummyControl& dummyImpl3 = static_cast< Impl::DummyControl& >( dummy.GetImplementation() );
+
+  dummyImpl3.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+  dummy.SetSize( 200, 200 );
+  Stage::GetCurrent().Add( dummy );
+
+  visual.SetTransformAndSize( DefaultTransform(), Vector2( 100, 100 ) );
+
+  application.SendNotification();
+
+  // Wait for image to load
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  renderer = dummy.GetRendererAt( 0 );
+  shader = renderer.GetShader();
+  value = shader.GetProperty( Shader::Property::PROGRAM );
+  map = value.GetMap();
+  DALI_TEST_CHECK( map );
+
+  fragment = map->Find( "fragment" ); // fragment key name from shader-impl.cpp
+  DALI_TEST_EQUALS( fragmentShader, fragment->Get< std::string >(), TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliGradientVisualBlendMode(void)
 {
   ToolkitTestApplication application;
index 51924f0..62e4f99 100644 (file)
@@ -1039,6 +1039,16 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
   return shader;
 }
 
+const char* ImageVisual::GetStandardVertexShader()
+{
+  return VERTEX_SHADER;
+}
+
+const char* ImageVisual::GetStandardFrgamentShader()
+{
+  return FRAGMENT_SHADER_NO_ATLAS;
+}
+
 void ImageVisual::ApplyImageToSampler( const Image& image )
 {
   if( image )
index d78ceca..e3b8e61 100644 (file)
@@ -251,6 +251,16 @@ public:
   static Shader GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping );
 
   /**
+   * Get the standard vertex shader code.
+   */
+  static const char* GetStandardVertexShader();
+
+  /**
+   * Get the standard fragment shader code.
+   */
+  static const char* GetStandardFrgamentShader();
+
+  /**
    * @copydoc AtlasUploadObserver::UploadCompleted
    *
    * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
index eef883c..b37bddb 100644 (file)
@@ -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 = ImageVisual::GetImageShader( mFactoryCache, mAttemptAtlasing, true );
+  }
+  else
+  {
+    shader  = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? ImageVisual::GetStandardVertexShader() : mImpl->mCustomShader->mVertexShader,
+                           mImpl->mCustomShader->mFragmentShader.empty() ? ImageVisual::GetStandardFrgamentShader() : 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 );
@@ -216,7 +229,7 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
 
     TextureSet textureSet;
 
-    if( mAttemptAtlasing )
+    if( mAttemptAtlasing && !mImpl->mCustomShader )
     {
       Vector4 atlasRect;
       textureSet = mFactoryCache.GetAtlasManager()->Add(atlasRect, rasterizedPixelData );