Ensured ImageView requests inside ResourceReady signal handler are queued.
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-ImageView.cpp
index 77121d5..7d1ea16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -836,7 +836,8 @@ int UtcDaliImageViewSetImageOnstageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   END_TEST;
 }
@@ -931,7 +932,8 @@ int UtcDaliImageViewSetImageOffstageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   END_TEST;
 }
@@ -951,7 +953,8 @@ int UtcDaliImageViewSetImageN(void)
   DALI_TEST_CHECK( !value.Get( url ) );
 
   Property::Map map;
-  DALI_TEST_CHECK( !value.Get( map ) );
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );
 
   std::string resource_url;
   Property::Value val = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) );
@@ -980,7 +983,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   application.Render( 16 );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL
@@ -1006,7 +1010,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set an Image
@@ -1033,7 +1038,8 @@ int UtcDaliImageViewSetImageTypeChangesP(void)
   visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE );
 
   DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty
-  DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty
+  value.Get( map );
+  DALI_TEST_CHECK( map.Empty() );        // Value should be empty
   DALI_TEST_CHECK( ! visual );           // Visual should be invalid
 
   // Set a URL in property map
@@ -1775,3 +1781,247 @@ int UtcDaliImageViewFillMode(void)
 
   END_TEST;
 }
+
+int UtcDaliImageViewCustomShader(void)
+{
+  ToolkitTestApplication application;
+
+  // Set a custom shader with an image url
+  {
+    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;
+
+    ImageView imageView = ImageView::New();
+    imageView.SetProperty( ImageView::Property::IMAGE, properties );
+
+    Stage::GetCurrent().Add( imageView );
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    Renderer renderer = imageView.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 );
+  }
+
+  // Set a custom shader after setting an image url
+  {
+    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::SHADER] = shader;
+
+    ImageView imageView = ImageView::New( TEST_IMAGE_FILE_NAME );
+    imageView.SetProperty( ImageView::Property::IMAGE, properties );
+
+    Stage::GetCurrent().Add( imageView );
+
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    Renderer renderer = imageView.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 );
+  }
+
+  // Set a custom shader before setting an image url
+  {
+    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::SHADER] = shader;
+
+    ImageView imageView = ImageView::New();
+    imageView.SetProperty( ImageView::Property::IMAGE, properties );
+    imageView.SetProperty( ImageView::Property::IMAGE, TEST_IMAGE_FILE_NAME );
+
+    Stage::GetCurrent().Add( imageView );
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    Renderer renderer = imageView.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 );
+  }
+
+  // Set a custom shader after setting a property map
+  {
+    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::SHADER] = shader;
+
+    Property::Map properties1;
+    properties1[Visual::Property::TYPE] = Visual::IMAGE;
+    properties1[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+
+    ImageView imageView = ImageView::New();
+    imageView.SetProperty( ImageView::Property::IMAGE, properties1 );
+    imageView.SetProperty( ImageView::Property::IMAGE, properties );
+
+    Stage::GetCurrent().Add( imageView );
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    Renderer renderer = imageView.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 );
+  }
+
+  // Set a custom shader before setting a property map
+  {
+    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::SHADER] = shader;
+
+    Property::Map properties1;
+    properties1[Visual::Property::TYPE] = Visual::IMAGE;
+    properties1[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME;
+
+    ImageView imageView = ImageView::New();
+    imageView.SetProperty( ImageView::Property::IMAGE, properties );
+    imageView.SetProperty( ImageView::Property::IMAGE, properties1 );
+
+    Stage::GetCurrent().Add( imageView );
+
+    application.SendNotification();
+    application.Render();
+    DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+    Renderer renderer = imageView.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;
+}
+
+
+namespace
+{
+static int gFailCounter = 0;
+const int MAX_RETRIES(3);
+
+void ReloadImage(ImageView imageView)
+{
+  Property::Map imageImmediateLoadingMap;
+  imageImmediateLoadingMap[ ImageVisual::Property::URL ] = "Non-existant-image.jpg";
+  imageImmediateLoadingMap[ ImageVisual::Property::LOAD_POLICY ] =  ImageVisual::LoadPolicy::IMMEDIATE;
+
+  tet_infoline("Immediate load an image");
+  imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap );
+}
+
+void ResourceFailedReload( Control control )
+{
+  gFailCounter++;
+  if( gFailCounter < MAX_RETRIES )
+  {
+    ReloadImage(ImageView::DownCast(control));
+  }
+}
+}
+
+int UtcDaliImageViewReloadFailedOnResourceReadySignal(void)
+{
+  tet_infoline("Test reloading failed image from within signal handler.");
+
+  ToolkitTestApplication application;
+
+  gFailCounter = 0;
+
+  ImageView imageView = ImageView::New();
+  imageView.ResourceReadySignal().Connect( &ResourceFailedReload );
+  DALI_TEST_EQUALS( gFailCounter, 0, TEST_LOCATION );
+  ReloadImage(imageView);
+
+  // loading started, this waits for the loader thread to complete
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+
+  DALI_TEST_EQUALS( gFailCounter, 1, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+
+  DALI_TEST_EQUALS( gFailCounter, 2, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+  application.SendNotification();
+  DALI_TEST_EQUALS( gFailCounter, 3, TEST_LOCATION );
+
+  END_TEST;
+}