(Vector) Support asynchronous file loading 93/276493/5
authorHeeyong Song <heeyong.song@samsung.com>
Fri, 17 Jun 2022 09:04:09 +0000 (18:04 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Fri, 8 Jul 2022 02:37:42 +0000 (11:37 +0900)
Change-Id: Ifd2f779cdaa4a52f0c9fc7cd25c17f2c1163f115

13 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp [changed mode: 0755->0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.h [changed mode: 0755->0644]
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp

index 6999ffa..9f4cd73 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-utils.h>
 #include <toolkit-event-thread-callback.h>
+#include <toolkit-text-utils.h>
+
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
-#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/devel-api/visuals/arc-visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
-#include <dummy-visual.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+
 #include <../dali-toolkit/dali-toolkit-test-utils/dummy-control.h>
-#include <dali-toolkit/devel-api/visuals/arc-visual-properties-devel.h>
+#include <dummy-visual.h>
 
 using namespace Dali;
 using namespace Toolkit;
 
 namespace
 {
-
-const char* TEST_VECTOR_IMAGE_FILE_NAME =  TEST_RESOURCE_DIR  "/insta_camera.json";
+const char* TEST_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json";
 
 }
 
 int UtcDaliVisualAction(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "Register an ImageVisual and and perform an Action on Visual directly" );
-  Vector2 controlSize( 20.f, 30.f );
+  tet_infoline("Register an ImageVisual and and perform an Action on Visual directly");
+  Vector2 controlSize(20.f, 30.f);
 
   //Created DummyVisual
-  Property::Map settings;
-  Toolkit::Internal::DummyVisualPtr dummyVisualPtr = Toolkit::Internal::DummyVisual::New( settings );
+  Property::Map                     settings;
+  Toolkit::Internal::DummyVisualPtr dummyVisualPtr = Toolkit::Internal::DummyVisual::New(settings);
 
-  DummyControl dummyControl = DummyControl::New( true );
-  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  DummyControl        dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
 
-  tet_infoline( "Register visual and stage control" );
+  tet_infoline("Register visual and stage control");
 
-  Toolkit::Visual::Base visualBaseHandle = Toolkit::Visual::Base( dummyVisualPtr.Get() );
-  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visualBaseHandle );
-  dummyControl.SetProperty( Actor::Property::SIZE, Vector2( 200.f, 200.f ) );
-  application.GetScene().Add( dummyControl );
+  Toolkit::Visual::Base visualBaseHandle = Toolkit::Visual::Base(dummyVisualPtr.Get());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visualBaseHandle);
+  dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  application.GetScene().Add(dummyControl);
 
   application.SendNotification();
   application.Render();
 
-  tet_infoline( "Check action counter is 0 before DoAction" );
-  DALI_TEST_EQUALS( dummyVisualPtr->GetActionCounter() , 0, TEST_LOCATION );
+  tet_infoline("Check action counter is 0 before DoAction");
+  DALI_TEST_EQUALS(dummyVisualPtr->GetActionCounter(), 0, TEST_LOCATION);
 
-  tet_infoline( "Perform TEST_ACTION action on Visual. Should increase the action counter" );
+  tet_infoline("Perform TEST_ACTION action on Visual. Should increase the action counter");
 
-  Property::Map attributes;
-  Toolkit::Internal::Visual::Base& internalVisualBase =  GetImplementation( visualBaseHandle );
-  internalVisualBase.DoAction( Dali::Toolkit::Internal::DummyVisual::TEST_ACTION, attributes );
+  Property::Map                    attributes;
+  Toolkit::Internal::Visual::Base& internalVisualBase = GetImplementation(visualBaseHandle);
+  internalVisualBase.DoAction(Dali::Toolkit::Internal::DummyVisual::TEST_ACTION, attributes);
   application.SendNotification();
-  DALI_TEST_EQUALS( dummyVisualPtr->GetActionCounter() , 1, TEST_LOCATION );
+  DALI_TEST_EQUALS(dummyVisualPtr->GetActionCounter(), 1, TEST_LOCATION);
 
   END_TEST;
 }
@@ -81,39 +82,39 @@ int UtcDaliVisualAction(void)
 int UtcDaliVisualActionNotImplemented(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "Register an ImageVisual and and perform an Action on a Visual which does not support any Actions" );
-  Vector2 controlSize( 20.f, 30.f );
+  tet_infoline("Register an ImageVisual and and perform an Action on a Visual which does not support any Actions");
+  Vector2 controlSize(20.f, 30.f);
 
   //Created DummyVisual
-  Property::Map settings;
-  Toolkit::Internal::DummyVisualPtr dummyVisualPtr = Toolkit::Internal::DummyVisual::New( settings );
+  Property::Map                     settings;
+  Toolkit::Internal::DummyVisualPtr dummyVisualPtr = Toolkit::Internal::DummyVisual::New(settings);
 
-  DummyControl dummyControl = DummyControl::New( true );
-  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+  DummyControl        dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
 
-  tet_infoline( "Register visual and stage control" );
+  tet_infoline("Register visual and stage control");
 
   VisualFactory factory = VisualFactory::Get();
   Property::Map propertyMap;
-  propertyMap.Insert(Visual::Property::TYPE,  Visual::COLOR);
-  propertyMap.Insert(ColorVisual::Property::MIX_COLOR,  Color::BLUE);
-  Visual::Base visual = factory.CreateVisual( propertyMap );
+  propertyMap.Insert(Visual::Property::TYPE, Visual::COLOR);
+  propertyMap.Insert(ColorVisual::Property::MIX_COLOR, Color::BLUE);
+  Visual::Base visual = factory.CreateVisual(propertyMap);
 
-  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
-  dummyControl.SetProperty( Actor::Property::SIZE, Vector2( 200.f, 200.f ) );
-  application.GetScene().Add( dummyControl );
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+  dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  application.GetScene().Add(dummyControl);
 
   application.SendNotification();
   application.Render();
 
-  tet_infoline( "Check action counter is 0 before DoAction" );
-  DALI_TEST_EQUALS( dummyVisualPtr->GetActionCounter() , 0, TEST_LOCATION );
+  tet_infoline("Check action counter is 0 before DoAction");
+  DALI_TEST_EQUALS(dummyVisualPtr->GetActionCounter(), 0, TEST_LOCATION);
 
-  tet_infoline( "Perform TEST_ACTION action on Color Visual which does not support it.. Should not increment the action counter" );
+  tet_infoline("Perform TEST_ACTION action on Color Visual which does not support it.. Should not increment the action counter");
   Property::Map attributes;
-  GetImplementation( visual ).DoAction( Dali::Toolkit::Internal::DummyVisual::TEST_ACTION, attributes );
+  GetImplementation(visual).DoAction(Dali::Toolkit::Internal::DummyVisual::TEST_ACTION, attributes);
   application.SendNotification();
-  DALI_TEST_EQUALS( dummyVisualPtr->GetActionCounter() , 0, TEST_LOCATION );
+  DALI_TEST_EQUALS(dummyVisualPtr->GetActionCounter(), 0, TEST_LOCATION);
 
   END_TEST;
 }
@@ -121,40 +122,40 @@ int UtcDaliVisualActionNotImplemented(void)
 int UtcDaliVisualSetProperties(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "Register a visual and SetProperties" );
+  tet_infoline("Register a visual and SetProperties");
 
   Toolkit::Internal::VisualFactoryCache* factoryCache = new Toolkit::Internal::VisualFactoryCache(false);
 
   //Created ColorVisual
   Property::Map propertyMap1;
-  propertyMap1.Insert(Visual::Property::TYPE,  Visual::COLOR);
-  propertyMap1.Insert(ColorVisual::Property::MIX_COLOR,  Color::RED);
-  Toolkit::Internal::ColorVisualPtr colorVisualPtr = Toolkit::Internal::ColorVisual::New( *factoryCache, propertyMap1 );
+  propertyMap1.Insert(Visual::Property::TYPE, Visual::COLOR);
+  propertyMap1.Insert(ColorVisual::Property::MIX_COLOR, Color::RED);
+  Toolkit::Internal::ColorVisualPtr colorVisualPtr = Toolkit::Internal::ColorVisual::New(*factoryCache, propertyMap1);
 
-  DummyControl dummyControl = DummyControl::New( true );
-  Impl::DummyControl& dummyImpl = static_cast< Impl::DummyControl& >( dummyControl.GetImplementation() );
+  DummyControl        dummyControl = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl    = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
 
-  Toolkit::Visual::Base visualBaseHandle = Toolkit::Visual::Base( colorVisualPtr.Get() );
-  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visualBaseHandle );
-  dummyControl.SetProperty( Actor::Property::SIZE, Vector2( 200.f, 200.f ) );
-  application.GetScene().Add( dummyControl );
+  Toolkit::Visual::Base visualBaseHandle = Toolkit::Visual::Base(colorVisualPtr.Get());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visualBaseHandle);
+  dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+  application.GetScene().Add(dummyControl);
 
   application.SendNotification();
   application.Render();
 
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::MIX_COLOR,  Color::BLUE );
+  propertyMap.Insert(Visual::Property::MIX_COLOR, Color::BLUE);
 
-  colorVisualPtr->SetProperties( propertyMap );
+  colorVisualPtr->SetProperties(propertyMap);
   application.SendNotification();
   application.Render();
 
   Property::Map resultMap;
-  visualBaseHandle.CreatePropertyMap( resultMap );
+  visualBaseHandle.CreatePropertyMap(resultMap);
 
-  Property::Value* colorValue = resultMap.Find( Visual::Property::MIX_COLOR,  Property::VECTOR4 );
-  DALI_TEST_CHECK( colorValue );
-  DALI_TEST_CHECK( colorValue->Get< Vector4 >() == Color::BLUE );
+  Property::Value* colorValue = resultMap.Find(Visual::Property::MIX_COLOR, Property::VECTOR4);
+  DALI_TEST_CHECK(colorValue);
+  DALI_TEST_CHECK(colorValue->Get<Vector4>() == Color::BLUE);
 
   delete factoryCache;
 
@@ -164,22 +165,22 @@ int UtcDaliVisualSetProperties(void)
 int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap" );
+  tet_infoline("UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap");
 
   Property::Map propertyMap;
-  propertyMap.Add( Toolkit::Visual::Property::TYPE,  DevelVisual::ANIMATED_VECTOR_IMAGE )
-             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  );
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME);
 
   // request AnimatedVectorImageVisual with a property map
-  VisualFactory factory = VisualFactory::Get();
-  Visual::Base visual = factory.CreateVisual( propertyMap );
-  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( visual );
+  VisualFactory                    factory    = VisualFactory::Get();
+  Visual::Base                     visual     = factory.CreateVisual(propertyMap);
+  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(visual);
 
   Property::Map resultMap;
-  visualImpl.CreateInstancePropertyMap( resultMap );
+  visualImpl.CreateInstancePropertyMap(resultMap);
 
   // check the property values from the returned map from a visual
-  DALI_TEST_CHECK( resultMap.Empty() );   // Now the map is empty
+  DALI_TEST_CHECK(resultMap.Empty()); // Now the map is empty
 
   END_TEST;
 }
@@ -187,47 +188,50 @@ int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void)
 int UtcDaliAnimatedVectorImageVisualSetProperties(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliAnimatedVectorImageVisualSetProperties" );
+  tet_infoline("UtcDaliAnimatedVectorImageVisualSetProperties");
 
   Property::Map propertyMap;
-  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE )
-             .Add( ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME  )
-             .Add( DevelImageVisual::Property::LOOP_COUNT, 3  )
-             .Add( DevelImageVisual::Property::PLAY_RANGE, Vector2( 0.2f, 0.8f )  );
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(DevelImageVisual::Property::LOOP_COUNT, 3)
+    .Add(DevelImageVisual::Property::PLAY_RANGE, Vector2(0.2f, 0.8f));
 
-  Visual::Base visual = VisualFactory::Get().CreateVisual( propertyMap );
-  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( visual );
-  DALI_TEST_CHECK( visual );
+  Visual::Base                     visual     = VisualFactory::Get().CreateVisual(propertyMap);
+  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(visual);
+  DALI_TEST_CHECK(visual);
 
-  DummyControl actor = DummyControl::New( true );
-  DummyControlImpl& dummyImpl = static_cast< DummyControlImpl& >( actor.GetImplementation() );
-  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
-  actor.SetProperty( Actor::Property::SIZE, Vector2( 200.0f, 200.0f ) );
-  application.GetScene().Add( actor );
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 200.0f));
+  application.GetScene().Add(actor);
 
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load, resource ready
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   // renderer is added to actor
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  Renderer renderer = actor.GetRendererAt( 0u );
-  DALI_TEST_CHECK( renderer );
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
 
   Property::Map propertyMap1;
-  propertyMap1.Add( DevelImageVisual::Property::LOOP_COUNT, 1  )
-              .Add( DevelImageVisual::Property::PLAY_RANGE, Vector2( 0.4f, 0.6f )  );
+  propertyMap1.Add(DevelImageVisual::Property::LOOP_COUNT, 1)
+    .Add(DevelImageVisual::Property::PLAY_RANGE, Vector2(0.4f, 0.6f));
 
-  visualImpl.SetProperties( propertyMap1 );
+  visualImpl.SetProperties(propertyMap1);
 
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
-  renderer = actor.GetRendererAt( 0u );
-  DALI_TEST_CHECK( renderer );
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
 
-  actor.Unparent( );
-  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+  actor.Unparent();
+  DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
 
   END_TEST;
 }
@@ -235,29 +239,29 @@ int UtcDaliAnimatedVectorImageVisualSetProperties(void)
 int UtcDaliArcVisualCreateInstancePropertyMap(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliArcVisualCreateInstancePropertyMap" );
+  tet_infoline("UtcDaliArcVisualCreateInstancePropertyMap");
 
   Property::Map propertyMap;
-  propertyMap.Add( Toolkit::Visual::Property::TYPE, DevelVisual::ARC )
-             .Add( DevelArcVisual::Property::THICKNESS, 20.0f );
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ARC)
+    .Add(DevelArcVisual::Property::THICKNESS, 20.0f);
 
   // request ArcVisual with a property map
-  VisualFactory factory = VisualFactory::Get();
-  Visual::Base visual = factory.CreateVisual( propertyMap );
-  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation( visual );
+  VisualFactory                    factory    = VisualFactory::Get();
+  Visual::Base                     visual     = factory.CreateVisual(propertyMap);
+  Toolkit::Internal::Visual::Base& visualImpl = GetImplementation(visual);
 
   Property::Map resultMap;
-  visualImpl.CreateInstancePropertyMap( resultMap );
+  visualImpl.CreateInstancePropertyMap(resultMap);
 
   // check the property values from the returned map from a visual
-  DALI_TEST_CHECK( resultMap.Empty() );   // Now the map is empty
+  DALI_TEST_CHECK(resultMap.Empty()); // Now the map is empty
 
   END_TEST;
 }
 int UtcDaliVisualUpdateBrokenImageRenderer(void)
 {
   ToolkitTestApplication application;
-  tet_infoline( "UpdateBrokenImageRenderer Test" );
+  tet_infoline("UpdateBrokenImageRenderer Test");
 
   Toolkit::Internal::VisualFactoryCache* factoryCache = new Toolkit::Internal::VisualFactoryCache(false);
 
@@ -268,7 +272,7 @@ int UtcDaliVisualUpdateBrokenImageRenderer(void)
 
   //Created dummy renderer
   Geometry geometry = factoryCache->GetGeometry(Toolkit::Internal::VisualFactoryCache::QUAD_GEOMETRY);
-  Shader   shader   = Shader::New("foo","bar");
+  Shader   shader   = Shader::New("foo", "bar");
   Renderer renderer = Renderer::New(geometry, shader);
 
   DALI_TEST_CHECK(renderer);
old mode 100755 (executable)
new mode 100644 (file)
index 2ccf2c1..4b6c5c8
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
  *
  */
 
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
 #include <dali/public-api/object/base-object.h>
 #include <toolkit-application.h>
-#include <toolkit-vector-animation-renderer.h>
 #include <toolkit-event-thread-callback.h>
+#include <toolkit-vector-animation-renderer.h>
+#include <chrono>
 #include <memory>
 #include <thread>
-#include <chrono>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace Adaptor
 {
-
 namespace
 {
 Dali::Internal::Adaptor::VectorAnimationRenderer* gVectorAnimationRenderer = nullptr;
 }
 
-class VectorAnimationRenderer: public Dali::BaseObject
+class VectorAnimationRenderer : public Dali::BaseObject
 {
 public:
-
   VectorAnimationRenderer()
   : mUrl(),
     mRenderer(),
-    mWidth( 0 ),
-    mHeight( 0 ),
+    mWidth(0),
+    mHeight(0),
+    mDefaultWidth(0),
+    mDefaultHeight(0),
     mTotalFrameNumber(VECTOR_ANIMATION_TOTAL_FRAME_NUMBER),
-    mPreviousFrame( 0 ),
+    mPreviousFrame(0),
     mDelayTime(0),
     mDroppedFrames(0),
-    mFrameRate( 60.0f ),
+    mFrameRate(60.0f),
     mTestFrameDrop(false),
     mNeedDroppedFrames(false),
-    mEventThreadCallback( new EventThreadCallback( MakeCallback( this, &VectorAnimationRenderer::OnTriggered ) ) )
+    mEventThreadCallback(new EventThreadCallback(MakeCallback(this, &VectorAnimationRenderer::OnTriggered)))
   {
     mCount++;
 
-    if( mCount == 2 )
+    if(mCount == 2)
     {
       mFrameRate = 0.1f;
     }
@@ -74,66 +73,66 @@ public:
     mUrl = url;
     if(mUrl == "invalid.json")
     {
+      mLoadFailed = true;
       return false;
     }
     else if(mUrl == "framedrop.json")
     {
       // Change total frame number for test
       mTotalFrameNumber = 200;
-      mTestFrameDrop = true;
+      mTestFrameDrop    = true;
     }
+
+    mDefaultWidth  = 100;
+    mDefaultHeight = 100;
+
     return true;
   }
 
-  void SetRenderer( Dali::Renderer renderer )
+  void SetRenderer(Dali::Renderer renderer)
   {
     mRenderer = renderer;
-
-    if( mWidth != 0 && mHeight != 0 )
-    {
-      Dali::TextureSet textureSet = mRenderer.GetTextures();
-      Dali::Texture texture = Dali::Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight );
-      textureSet.SetTexture( 0, texture );
-      mUploadCompletedSignal.Emit();
-    }
   }
 
-  void SetSize( uint32_t width, uint32_t height )
+  void SetSize(uint32_t width, uint32_t height)
   {
-    mWidth = width;
+    mWidth  = width;
     mHeight = height;
 
-    if( mRenderer )
+    if(!mLoadFailed)
     {
-      Dali::TextureSet textureSet = mRenderer.GetTextures();
-      Dali::Texture texture = Dali::Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight );
-      textureSet.SetTexture( 0, texture );
-      mUploadCompletedSignal.Emit();
+      mNeedTrigger   = true;
+      mResourceReady = false;
     }
   }
 
-  bool Render( uint32_t frameNumber )
+  bool Render(uint32_t frameNumber)
   {
+    if(mWidth == 0 || mHeight == 0)
+    {
+      return false;
+    }
+
     if(mTestFrameDrop)
     {
       std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int32_t>(mDelayTime)));
-      mTestFrameDrop = false;
+      mTestFrameDrop     = false;
       mNeedDroppedFrames = true;
     }
     else if(mNeedDroppedFrames)
     {
-      mDroppedFrames = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1: frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
-      mNeedTrigger = true;
+      mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
+      mNeedTrigger       = true;
       mNeedDroppedFrames = false;
     }
 
-    if( mNeedTrigger )
+    if(mNeedTrigger)
     {
       mEventThreadCallback->Trigger();
       mNeedTrigger = false;
     }
 
-    if( frameNumber == 1 && mPreviousFrame != frameNumber )
+    if(frameNumber == 1 && mPreviousFrame != frameNumber)
     {
       mPreviousFrame = frameNumber;
       // For test corverage
@@ -153,23 +152,23 @@ public:
     return mFrameRate;
   }
 
-  void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+  void GetDefaultSize(uint32_t& width, uint32_t& height) const
   {
-    width = 100;
-    height = 100;
+    width  = mDefaultWidth;
+    height = mDefaultHeight;
   }
 
-  bool GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const
+  bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
   {
-    if( marker.compare( VECTOR_ANIMATION_MARKER_NAME_1 ) == 0 )
+    if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
     {
       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
-      endFrame = VECTOR_ANIMATION_MARKER_END_FRAME_1;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
     }
-    else if( marker.compare( VECTOR_ANIMATION_MARKER_NAME_2 ) == 0 )
+    else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
     {
       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
-      endFrame = VECTOR_ANIMATION_MARKER_END_FRAME_2;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
     }
     else
     {
@@ -178,6 +177,12 @@ public:
     return true;
   }
 
+  void InvalidateBuffer()
+  {
+    mNeedTrigger   = true;
+    mResourceReady = false;
+  }
+
   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
   {
     return mUploadCompletedSignal;
@@ -185,50 +190,66 @@ public:
 
   void OnTriggered()
   {
+    if(!mResourceReady)
+    {
+      mResourceReady = true;
+
+      Dali::TextureSet textureSet = mRenderer.GetTextures();
+      Dali::Texture    texture    = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight);
+      textureSet.SetTexture(0, texture);
+
+      Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Pixel::RGBA8888);
+      Dali::PixelData    pixelData   = Devel::PixelBuffer::Convert(pixelBuffer);
+      texture.Upload(pixelData);
+
+      mUploadCompletedSignal.Emit();
+    }
   }
 
 public:
-
   static uint32_t mCount;
-  static bool mNeedTrigger;
 
-  std::string mUrl;
+  std::string    mUrl;
   Dali::Renderer mRenderer;
-  uint32_t mWidth;
-  uint32_t mHeight;
-  uint32_t mTotalFrameNumber;
-  uint32_t mPreviousFrame;
-  uint32_t mDelayTime;
-  uint32_t mDroppedFrames;
-  float mFrameRate;
-  bool mTestFrameDrop;
-  bool mNeedDroppedFrames;
+  uint32_t       mWidth;
+  uint32_t       mHeight;
+  uint32_t       mDefaultWidth;
+  uint32_t       mDefaultHeight;
+  uint32_t       mTotalFrameNumber;
+  uint32_t       mPreviousFrame;
+  uint32_t       mDelayTime;
+  uint32_t       mDroppedFrames;
+  float          mFrameRate;
+  bool           mTestFrameDrop;
+  bool           mNeedDroppedFrames;
+  bool           mLoadFailed{false};
+  bool           mResourceReady{false};
+  bool           mNeedTrigger{true};
+
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
-  std::unique_ptr< EventThreadCallback > mEventThreadCallback;
+  std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
 };
 
 uint32_t VectorAnimationRenderer::mCount = 0;
-bool VectorAnimationRenderer::mNeedTrigger = true;
 
-inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
+inline VectorAnimationRenderer& GetImplementation(Dali::VectorAnimationRenderer& renderer)
 {
-  DALI_ASSERT_ALWAYS( renderer && "VectorAnimationRenderer handle is empty." );
+  DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
   BaseObject& handle = renderer.GetBaseObject();
-  return static_cast< Internal::Adaptor::VectorAnimationRenderer& >( handle );
+  return static_cast<Internal::Adaptor::VectorAnimationRenderer&>(handle);
 }
 
-inline const VectorAnimationRenderer& GetImplementation( const Dali::VectorAnimationRenderer& renderer )
+inline const VectorAnimationRenderer& GetImplementation(const Dali::VectorAnimationRenderer& renderer)
 {
-  DALI_ASSERT_ALWAYS( renderer && "VectorAnimationRenderer handle is empty." );
+  DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
   const BaseObject& handle = renderer.GetBaseObject();
-  return static_cast< const Internal::Adaptor::VectorAnimationRenderer& >( handle );
+  return static_cast<const Internal::Adaptor::VectorAnimationRenderer&>(handle);
 }
 
 } // namespace Adaptor
 
 } // namespace Internal
 
-
 /********************************************************************************/
 /*********************************  PUBLIC CLASS  *******************************/
 /********************************************************************************/
@@ -239,7 +260,7 @@ VectorAnimationRenderer VectorAnimationRenderer::New()
 
   Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
 
-  return VectorAnimationRenderer( animationRenderer );
+  return VectorAnimationRenderer(animationRenderer);
 }
 
 VectorAnimationRenderer::VectorAnimationRenderer()
@@ -250,19 +271,19 @@ VectorAnimationRenderer::~VectorAnimationRenderer()
 {
 }
 
-VectorAnimationRenderer::VectorAnimationRenderer( Internal::Adaptor::VectorAnimationRenderer* internal )
-: BaseHandle( internal )
+VectorAnimationRenderer::VectorAnimationRenderer(Internal::Adaptor::VectorAnimationRenderer* internal)
+: BaseHandle(internal)
 {
 }
 
-VectorAnimationRenderer::VectorAnimationRenderer( const VectorAnimationRenderer& handle )
-: BaseHandle( handle )
+VectorAnimationRenderer::VectorAnimationRenderer(const VectorAnimationRenderer& handle)
+: BaseHandle(handle)
 {
 }
 
-VectorAnimationRenderer& VectorAnimationRenderer::operator=( const VectorAnimationRenderer& rhs )
+VectorAnimationRenderer& VectorAnimationRenderer::operator=(const VectorAnimationRenderer& rhs)
 {
-  BaseHandle::operator=( rhs );
+  BaseHandle::operator=(rhs);
   return *this;
 }
 
@@ -272,51 +293,56 @@ void VectorAnimationRenderer::Finalize()
 
 bool VectorAnimationRenderer::Load(const std::string& url)
 {
-  return Internal::Adaptor::GetImplementation( *this ).Load(url);
+  return Internal::Adaptor::GetImplementation(*this).Load(url);
 }
 
-void VectorAnimationRenderer::SetRenderer( Renderer renderer )
+void VectorAnimationRenderer::SetRenderer(Renderer renderer)
 {
-  Internal::Adaptor::GetImplementation( *this ).SetRenderer( renderer );
+  Internal::Adaptor::GetImplementation(*this).SetRenderer(renderer);
 }
 
-void VectorAnimationRenderer::SetSize( uint32_t width, uint32_t height )
+void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
 {
-  Internal::Adaptor::GetImplementation( *this ).SetSize( width, height );
+  Internal::Adaptor::GetImplementation(*this).SetSize(width, height);
 }
 
-bool VectorAnimationRenderer::Render( uint32_t frameNumber )
+bool VectorAnimationRenderer::Render(uint32_t frameNumber)
 {
-  return Internal::Adaptor::GetImplementation( *this ).Render( frameNumber );
+  return Internal::Adaptor::GetImplementation(*this).Render(frameNumber);
 }
 
 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
 {
-  return Internal::Adaptor::GetImplementation( *this ).GetTotalFrameNumber();
+  return Internal::Adaptor::GetImplementation(*this).GetTotalFrameNumber();
 }
 
 float VectorAnimationRenderer::GetFrameRate() const
 {
-  return Internal::Adaptor::GetImplementation( *this ).GetFrameRate();
+  return Internal::Adaptor::GetImplementation(*this).GetFrameRate();
+}
+
+void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
+{
+  Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height);
 }
 
-void VectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+void VectorAnimationRenderer::GetLayerInfo(Property::Map& map) const
 {
-  Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height );
 }
 
-void VectorAnimationRenderer::GetLayerInfo( Property::Map& map ) const
+bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
 {
+  return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
 }
 
-bool VectorAnimationRenderer::GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const
+void VectorAnimationRenderer::InvalidateBuffer()
 {
-  return Internal::Adaptor::GetImplementation( *this ).GetMarkerInfo( marker, startFrame, endFrame );
+  return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
 }
 
 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
 {
-  return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
+  return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
 }
 
 } // namespace Dali
@@ -325,12 +351,6 @@ namespace Test
 {
 namespace VectorAnimationRenderer
 {
-
-void RequestTrigger()
-{
-  Dali::Internal::Adaptor::VectorAnimationRenderer::mNeedTrigger = true;
-}
-
 void DelayRendering(uint32_t delay)
 {
   Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime = delay;
@@ -341,6 +361,5 @@ uint32_t GetDroppedFrames()
   return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
 }
 
-} // VectorAnimationRenderer
-} // Test
-
+} // namespace VectorAnimationRenderer
+} // namespace Test
old mode 100755 (executable)
new mode 100644 (file)
index a1ea51b..bc241f1
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEST_VECTOR_ANIMATION_RENDERER_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -22,7 +22,6 @@ namespace Test
 {
 namespace VectorAnimationRenderer
 {
-
 #define VECTOR_ANIMATION_TOTAL_FRAME_NUMBER 5
 #define VECTOR_ANIMATION_MARKER_NAME_1 "marker1"
 #define VECTOR_ANIMATION_MARKER_NAME_2 "marker2"
@@ -31,12 +30,10 @@ namespace VectorAnimationRenderer
 #define VECTOR_ANIMATION_MARKER_START_FRAME_2 2
 #define VECTOR_ANIMATION_MARKER_END_FRAME_2 3
 
-void RequestTrigger();
-void DelayRendering(uint32_t delay);
+void     DelayRendering(uint32_t delay);
 uint32_t GetDroppedFrames();
 
-} // VectorAnimationRenderer
-} // Test
-
+} // namespace VectorAnimationRenderer
+} // namespace Test
 
 #endif // DALI_TOOLKIT_TEST_VECTOR_ANIMATION_RENDERER_H
index 41028c1..f69ae92 100644 (file)
@@ -86,6 +86,9 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
   Renderer renderer = actor.GetRendererAt(0u);
@@ -119,6 +122,9 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual02(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
   Renderer renderer = actor.GetRendererAt(0u);
@@ -160,6 +166,9 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual03(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
   Renderer renderer = actor.GetRendererAt(0u);
@@ -210,8 +219,8 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - render a frame
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
@@ -319,7 +328,8 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   Property::Map resultMap;
   resultMap = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
@@ -558,6 +568,9 @@ int UtcDaliAnimatedVectorImageVisualCustomShader(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   Renderer        renderer = dummy.GetRendererAt(0);
   Shader          shader2  = renderer.GetShader();
   Property::Value value    = shader2.GetProperty(Shader::Property::PROGRAM);
@@ -641,8 +654,8 @@ int UtcDaliAnimatedVectorImageVisualLoopCount(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - render a frame
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
@@ -685,7 +698,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
@@ -712,10 +726,13 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array);
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
@@ -734,10 +751,13 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -751,10 +771,13 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array);
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
@@ -803,7 +826,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
   DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
@@ -830,10 +854,13 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array);
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
@@ -854,10 +881,13 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array);
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
@@ -902,8 +932,8 @@ int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
   application.SendNotification();
   application.Render();
 
-  // Wait for animation finish
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  // Wait for animation finish - load, render, finish
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   Property::Value* value = map.Find(DevelImageVisual::Property::PLAY_STATE);
@@ -921,7 +951,8 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 
   Property::Map propertyMap;
   propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
-    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME);
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(DevelImageVisual::Property::LOOP_COUNT, 3);
 
   Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
   DALI_TEST_CHECK(visual);
@@ -940,12 +971,18 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 2);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   Property::Value* value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -963,10 +1000,13 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -990,15 +1030,19 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
   application.SendNotification();
   application.Render();
 
-  // Stop and jump to 3
-  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes);
+  // Wait for animation finish
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
+  // Jump to 3
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -1009,10 +1053,13 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
   // Jump to the same position
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -1054,7 +1101,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   Property::Value* value = map.Find(DevelImageVisual::Property::LOOP_COUNT);
@@ -1079,10 +1127,13 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::LOOP_COUNT);
@@ -1105,10 +1156,13 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(20)); // wait for next rasterize thread run
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
@@ -1169,8 +1223,8 @@ int UtcDaliAnimatedVectorImageVisualStopBehavior(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - animation finished
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  // Trigger count is 3 - load, render, animation finished
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   Property::Value* value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -1217,6 +1271,14 @@ int UtcDaliAnimatedVectorImageVisualStopBehavior(void)
   // Pause
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
   map                    = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value                  = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
   int currentFrameNumber = value->Get<int>();
@@ -1224,8 +1286,13 @@ int UtcDaliAnimatedVectorImageVisualStopBehavior(void)
   // Stop
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::STOP, attributes);
 
+  // To make event trigger
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
   application.SendNotification();
-  application.Render(16);
+  application.Render();
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -1264,8 +1331,8 @@ int UtcDaliAnimatedVectorImageVisualLoopingMode(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - animation finished
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  // Trigger count is 3 - load, render, animation finished
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   Property::Value* value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
@@ -1328,13 +1395,21 @@ int UtcDaliAnimatedVectorImageVisualPropertyNotification(void)
   DummyControl      actor     = DummyControl::New(true);
   DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
 
   Vector2 controlSize(20.f, 30.f);
-  Vector3 controlScale(2.0f, 2.0f, 1.0f);
   actor.SetProperty(Actor::Property::SIZE, controlSize);
-  actor.SetProperty(Actor::Property::SCALE, controlScale);
-
-  application.GetScene().Add(actor);
 
   application.SendNotification();
   application.Render();
@@ -1342,19 +1417,17 @@ int UtcDaliAnimatedVectorImageVisualPropertyNotification(void)
   application.SendNotification();
   application.Render();
 
-  Renderer renderer = actor.GetRendererAt(0u);
-  DALI_TEST_CHECK(renderer);
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   auto textureSet = renderer.GetTextures();
   auto texture    = textureSet.GetTexture(0);
 
-  DALI_TEST_EQUALS(controlSize.width * controlScale.width, texture.GetWidth(), TEST_LOCATION);
-  DALI_TEST_EQUALS(controlSize.height * controlScale.height, texture.GetHeight(), TEST_LOCATION);
+  DALI_TEST_EQUALS(controlSize.width, texture.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(controlSize.height, texture.GetHeight(), TEST_LOCATION);
 
-  // Change scale and size
-  controlSize  = Vector2(50.f, 40.f);
-  controlScale = Vector3(0.5f, 0.5f, 1.0f);
-  actor.SetProperty(Actor::Property::SIZE, controlSize);
+  // Change scale
+  Vector3 controlScale(2.0f, 2.0f, 1.0f);
   actor.SetProperty(Actor::Property::SCALE, controlScale);
 
   application.SendNotification();
@@ -1363,6 +1436,33 @@ int UtcDaliAnimatedVectorImageVisualPropertyNotification(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  textureSet = renderer.GetTextures();
+  texture    = textureSet.GetTexture(0);
+
+  DALI_TEST_EQUALS(controlSize.width * controlScale.width, texture.GetWidth(), TEST_LOCATION);
+  DALI_TEST_EQUALS(controlSize.height * controlScale.height, texture.GetHeight(), TEST_LOCATION);
+
+  // Size animation
+  controlSize         = Vector2(50.0f, 100.0f);
+  Animation animation = Animation::New(1.0);
+  animation.AnimateTo(Property(actor, Actor::Property::SIZE), Vector3(controlSize.x, controlSize.y, 0.0f));
+  animation.Play();
+
+  application.SendNotification();
+  application.Render(1100); // After the animation
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
   renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -1411,12 +1511,18 @@ int UtcDaliAnimatedVectorImageVisualMultipleInstances(void)
 
   application.GetScene().Add(actor2);
 
+  // Trigger count is 4 - load & render a frame for each instance
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(4), true, TEST_LOCATION);
+
   DevelControl::DoAction(actor2, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, Property::Map());
 
+  // To make event trigger
+  actor2.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+
   application.SendNotification();
   application.Render();
 
-  std::this_thread::sleep_for(std::chrono::milliseconds(200));
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   Property::Map attributes;
   attributes.Add(DevelImageVisual::Property::STOP_BEHAVIOR, DevelImageVisual::StopBehavior::LAST_FRAME);
@@ -1463,6 +1569,9 @@ int UtcDaliAnimatedVectorImageVisualControlVisibilityChanged(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   Property::Map attributes;
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
 
@@ -1510,6 +1619,9 @@ int UtcDaliAnimatedVectorImageVisualWindowVisibilityChanged(void)
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
   Property::Map attributes;
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
 
@@ -1534,7 +1646,51 @@ int UtcDaliAnimatedVectorImageVisualWindowVisibilityChanged(void)
   END_TEST;
 }
 
-int UtcDaliAnimatedVectorImageVisualInvalidFile(void)
+int UtcDaliAnimatedVectorImageVisualInvalidFile01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request loading with invalid file - should draw broken image");
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_INVALID_FILE_NAME);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check resource status
+  Visual::ResourceStatus status = actor.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL);
+  DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION);
+
+  // The broken image should be shown.
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualInvalidFile02(void)
 {
   ToolkitTestApplication application;
   tet_infoline("Request loading with invalid file - should draw broken image");
@@ -1556,11 +1712,60 @@ int UtcDaliAnimatedVectorImageVisualInvalidFile(void)
 
   actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
 
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  // Add to the Scene after loading
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check resource status
+  Visual::ResourceStatus status = actor.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL);
+  DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION);
+
+  // The broken image should be shown.
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualInvalidFile03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request loading with invalid file without size set - should draw broken image");
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_INVALID_FILE_NAME);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
   application.GetScene().Add(actor);
 
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 1 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
   // Check resource status
   Visual::ResourceStatus status = actor.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL);
   DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION);
@@ -1606,8 +1811,8 @@ int UtcDaliAnimatedVectorImageVisualFrameDrops(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 2 - render the first frame & calculating frame drops
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+  // Trigger count is 3 - load, render the first frame & calculating frame drops
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
 
   // Check dropped frame
   uint32_t frames = Test::VectorAnimationRenderer::GetDroppedFrames();
@@ -1616,3 +1821,61 @@ int UtcDaliAnimatedVectorImageVisualFrameDrops(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualSize");
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base  visual  = factory.CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions());
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  // Trigger count is 2 - load, resource ready
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  textureTrace.Enable(true);
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    int               width = 100, height = 100; // 100x100 is the content default size.
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 200.0f));
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - resource ready
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  textureTrace.Reset();
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    int               width = 200, height = 200;
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  END_TEST;
+}
index 95c6abd..7a7bf26 100644 (file)
@@ -3703,7 +3703,7 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void)
 
     tet_printf("test %s [sync:%d] signal fired\n", url.c_str(), isSynchronous ? 1 : 0);
     DALI_TEST_EQUALS(gResourceReadySignalCounter, 1, location);
-    DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(Toolkit::ImageView::Property::IMAGE), loadSuccess ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED, TEST_LOCATION);
+    DALI_TEST_EQUALS(imageView.GetVisualResourceStatus(Toolkit::ImageView::Property::IMAGE), loadSuccess ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED, location);
 
     imageView.Unparent();
   };
@@ -3750,7 +3750,7 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void)
   TestResourceReadyUrl(1, 0, 1, TEST_BROKEN_IMAGE_L, "", TEST_LOCATION);
 
   TestResourceReadyUrl(2, 0, 1, TEST_GIF_FILE_NAME, "", TEST_LOCATION);                   // 2 image loading - batch size
-  TestResourceReadyUrl(1, 0, 1, TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME, "", TEST_LOCATION); // 1 rasterize
+  TestResourceReadyUrl(2, 0, 1, TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME, "", TEST_LOCATION); // load & rasterize
 
   TestResourceReadyUrl(3, 0, 1, gImage_600_RGB, gImage_34_RGBA, TEST_LOCATION); // 2 image loading + 1 applymask
 
@@ -3761,7 +3761,7 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void)
   TestResourceReadyUrl(1, 0, 0, "invalid.svg", "", TEST_LOCATION);
   TestResourceReadyUrl(1, 0, 0, "invalid.9.png", "", TEST_LOCATION);
   TestResourceReadyUrl(1, 0, 0, "invalid.gif", "", TEST_LOCATION);  // 1 image loading
-  TestResourceReadyUrl(0, 0, 0, "invalid.json", "", TEST_LOCATION); // 0 rasterize
+  TestResourceReadyUrl(1, 0, 0, "invalid.json", "", TEST_LOCATION); // 0 rasterize
 
   TestResourceReadyUrl(2, 0, 0, "invalid.jpg", "invalid.png", TEST_LOCATION);  // 2 image loading
   TestResourceReadyUrl(2, 0, 1, gImage_600_RGB, "invalid.png", TEST_LOCATION); // 2 image loading
@@ -3779,8 +3779,7 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void)
   TestResourceReadyUrl(0, 1, 1, TEST_SVG_FILE_NAME, "", TEST_LOCATION); // synchronous rasterize
   TestResourceReadyUrl(0, 1, 1, TEST_BROKEN_IMAGE_L, "", TEST_LOCATION);
 
-  TestResourceReadyUrl(1, 1, 1, TEST_GIF_FILE_NAME, "", TEST_LOCATION);                   // first frame image loading sync + second frame image loading async
-  TestResourceReadyUrl(0, 1, 1, TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME, "", TEST_LOCATION); // synchronous rasterize
+  TestResourceReadyUrl(1, 1, 1, TEST_GIF_FILE_NAME, "", TEST_LOCATION); // first frame image loading sync + second frame image loading async
 
   TestResourceReadyUrl(0, 1, 1, gImage_600_RGB, gImage_34_RGBA, TEST_LOCATION);
 
@@ -3791,7 +3790,6 @@ int UtcDaliImageViewCheckVariousCaseSendOnResourceReadySignal(void)
   TestResourceReadyUrl(0, 1, 0, "invalid.svg", "", TEST_LOCATION);
   TestResourceReadyUrl(0, 1, 0, "invalid.9.png", "", TEST_LOCATION);
   TestResourceReadyUrl(0, 1, 0, "invalid.gif", "", TEST_LOCATION);
-  TestResourceReadyUrl(0, 1, 0, "invalid.json", "", TEST_LOCATION); // 0 rasterize
 
   TestResourceReadyUrl(0, 1, 0, "invalid.jpg", "invalid.png", TEST_LOCATION);
   TestResourceReadyUrl(0, 1, 1, gImage_600_RGB, "invalid.png", TEST_LOCATION);
index f54a7f0..dae8540 100644 (file)
@@ -4197,7 +4197,8 @@ int UtcDaliVisualRoundedCorner(void)
     application.SendNotification();
     application.Render();
 
-    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    // Trigger count is 2 - load & render a frame
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
     application.SendNotification();
     application.Render();
@@ -4573,7 +4574,8 @@ int UtcDaliVisualBorderline(void)
     application.SendNotification();
     application.Render();
 
-    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+    // Trigger count is 2 - load & render a frame
+    DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
     application.SendNotification();
     application.Render();
@@ -5605,8 +5607,8 @@ int UtcDaliVisualGetVisualProperty07(void)
   application.SendNotification();
   application.Render();
 
-  // Wait for image loading
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   application.SendNotification();
   application.Render();
index 1017ae0..9636775 100644 (file)
@@ -102,12 +102,9 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Visual::Base::Impl::IS_PREMULTIPLIED_ALPHA;
 
-  if(!mVectorAnimationTask->Load(mUrl.GetUrl()))
-  {
-    mLoadFailed = true;
-  }
+  mVectorAnimationTask->RequestLoad(mUrl.GetUrl());
 
-  mVectorAnimationTask->UploadCompletedSignal().Connect(this, &AnimatedVectorImageVisual::OnUploadCompleted);
+  mVectorAnimationTask->ResourceReadySignal().Connect(this, &AnimatedVectorImageVisual::OnResourceReady);
   mVectorAnimationTask->SetAnimationFinishedCallback(new EventThreadCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnAnimationFinished)));
 
   auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
@@ -127,7 +124,7 @@ AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
     }
 
     // Finalize animation task and disconnect the signal in the main thread
-    mVectorAnimationTask->UploadCompletedSignal().Disconnect(this, &AnimatedVectorImageVisual::OnUploadCompleted);
+    mVectorAnimationTask->ResourceReadySignal().Disconnect(this, &AnimatedVectorImageVisual::OnResourceReady);
     mVectorAnimationTask->Finalize();
   }
 }
@@ -146,10 +143,28 @@ void AnimatedVectorImageVisual::GetNaturalSize(Vector2& naturalSize)
   }
   else
   {
-    uint32_t width, height;
-    mVectorAnimationTask->GetDefaultSize(width, height);
-    naturalSize.x = width;
-    naturalSize.y = height;
+    if(mLoadFailed && mImpl->mRenderer)
+    {
+      // Load failed, use broken image size
+      auto textureSet = mImpl->mRenderer.GetTextures();
+      if(textureSet && textureSet.GetTextureCount())
+      {
+        auto texture = textureSet.GetTexture(0);
+        if(texture)
+        {
+          naturalSize.x = texture.GetWidth();
+          naturalSize.y = texture.GetHeight();
+          return;
+        }
+      }
+    }
+    else
+    {
+      uint32_t width, height;
+      mVectorAnimationTask->GetDefaultSize(width, height);
+      naturalSize.x = width;
+      naturalSize.y = height;
+    }
   }
 
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::GetNaturalSize: w = %f, h = %f [%p]\n", naturalSize.width, naturalSize.height, this);
@@ -308,6 +323,8 @@ void AnimatedVectorImageVisual::OnInitialize(void)
 
   // Register transform properties
   mImpl->mTransform.SetUniforms(mImpl->mRenderer, Direction::LEFT_TO_RIGHT);
+
+  mVectorAnimationTask->SetRenderer(mImpl->mRenderer);
 }
 
 void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor)
@@ -319,16 +336,13 @@ void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor)
 
   if(mLoadFailed)
   {
-    Vector2 imageSize = Vector2::ZERO;
-    imageSize         = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+    Vector2 imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
     mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
     actor.AddRenderer(mImpl->mRenderer);
     ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
   }
   else
   {
-    mVectorAnimationTask->SetRenderer(mImpl->mRenderer);
-
     // Add property notification for scaling & size
     mScaleNotification = actor.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
     mScaleNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnScaleNotification);
@@ -343,6 +357,15 @@ void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor)
     {
       DevelWindow::VisibilityChangedSignal(window).Connect(this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged);
     }
+
+    if(mImpl->mEventObserver)
+    {
+      // The visual needs it's size set before it can be rasterized hence request relayout once on stage
+      mImpl->mEventObserver->RelayoutRequest(*this);
+    }
+
+    mAnimationData.resendFlag |= VectorAnimationTask::RESEND_NEED_RESOURCE_READY;
+    TriggerVectorRasterization();
   }
 
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOnScene [%p]\n", this);
@@ -374,8 +397,10 @@ void AnimatedVectorImageVisual::DoSetOffScene(Actor& actor)
   mPlacementActor.Reset();
 
   // Reset the visual size to zero so that when adding the actor back to stage the rasterization is forced
-  mVisualSize  = Vector2::ZERO;
-  mVisualScale = Vector2::ONE;
+  mVisualSize           = Vector2::ZERO;
+  mVisualScale          = Vector2::ONE;
+  mAnimationData.width  = 0;
+  mAnimationData.height = 0;
 
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::DoSetOffScene [%p]\n", this);
 }
@@ -464,18 +489,30 @@ void AnimatedVectorImageVisual::OnDoAction(const Property::Index actionId, const
   TriggerVectorRasterization();
 }
 
-void AnimatedVectorImageVisual::OnUploadCompleted()
+void AnimatedVectorImageVisual::OnResourceReady(bool success)
 {
+  mLoadFailed = !success;
+
   // If weak handle is holding a placement actor, it is the time to add the renderer to actor.
   Actor actor = mPlacementActor.GetHandle();
   if(actor && !mRendererAdded)
   {
-    actor.AddRenderer(mImpl->mRenderer);
-    mRendererAdded = true;
+    if(success)
+    {
+      actor.AddRenderer(mImpl->mRenderer);
+      ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+    }
+    else
+    {
+      Vector2 imageSize = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+      mFactoryCache.UpdateBrokenImageRenderer(mImpl->mRenderer, imageSize);
+      actor.AddRenderer(mImpl->mRenderer);
+      ResourceReady(Toolkit::Visual::ResourceStatus::FAILED);
+    }
 
-    ResourceReady(Toolkit::Visual::ResourceStatus::READY);
+    mRendererAdded = true;
 
-    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnUploadCompleted: Renderer is added [%p]\n", this);
+    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Renderer is added (success = %d) [%p]\n", success, this);
   }
 }
 
@@ -528,9 +565,12 @@ void AnimatedVectorImageVisual::SetVectorImageSize()
   uint32_t width  = static_cast<uint32_t>(mVisualSize.width * mVisualScale.width);
   uint32_t height = static_cast<uint32_t>(mVisualSize.height * mVisualScale.height);
 
-  mAnimationData.width  = width;
-  mAnimationData.height = height;
-  mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
+  if(mAnimationData.width != width || mAnimationData.height != height)
+  {
+    mAnimationData.width  = width;
+    mAnimationData.height = height;
+    mAnimationData.resendFlag |= VectorAnimationTask::RESEND_SIZE;
+  }
 }
 
 void AnimatedVectorImageVisual::StopAnimation()
@@ -562,7 +602,7 @@ void AnimatedVectorImageVisual::OnScaleNotification(PropertyNotification& source
   {
     Vector3 scale = actor.GetProperty<Vector3>(Actor::Property::WORLD_SCALE);
 
-    if(mRedrawInScalingDown || scale.width >= 1.0f || scale.height >= 1.0f)
+    if((mVisualScale.width != scale.width || mVisualScale.height != scale.height) && (mRedrawInScalingDown || scale.width >= 1.0f || scale.height >= 1.0f))
     {
       mVisualScale.width  = scale.width;
       mVisualScale.height = scale.height;
@@ -582,16 +622,20 @@ void AnimatedVectorImageVisual::OnSizeNotification(PropertyNotification& source)
   Actor actor = mPlacementActor.GetHandle();
   if(actor)
   {
-    Vector3 size       = actor.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
-    mVisualSize.width  = size.width;
-    mVisualSize.height = size.height;
+    Vector3 size = actor.GetCurrentProperty<Vector3>(Actor::Property::SIZE);
 
-    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this);
+    if(mVisualSize.width != size.width || mVisualSize.height != size.height)
+    {
+      mVisualSize.width  = size.width;
+      mVisualSize.height = size.height;
 
-    SetVectorImageSize();
-    SendAnimationData();
+      DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnSizeNotification: size = %f, %f [%p]\n", mVisualSize.width, mVisualSize.height, this);
 
-    Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
+      SetVectorImageSize();
+      SendAnimationData();
+
+      Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
+    }
   }
 }
 
index 4b14fc3..533fc71 100644 (file)
@@ -168,9 +168,10 @@ private:
   void DoSetProperty(Property::Index index, const Property::Value& value);
 
   /**
-   * @brief Called when the texture upload is completed.
+   * @brief Called when the resource is ready.
+   * @param[in] success True if the texture load was successful. If false, then the resource failed to load.
    */
-  void OnUploadCompleted();
+  void OnResourceReady(bool success);
 
   /**
    * @brief Event callback from rasterize thread. This is called after the animation is finished.
index 86a37ab..4d31135 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -51,7 +51,9 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mAnimationData(),
   mVectorAnimationThread(factoryCache.GetVectorAnimationManager().GetVectorAnimationThread()),
   mConditionalWait(),
+  mResourceReadySignal(),
   mAnimationFinishedTrigger(),
+  mLoadCompletedTrigger(new EventThreadCallback(MakeCallback(this, &VectorAnimationTask::OnLoadCompleted))),
   mPlayState(PlayState::STOPPED),
   mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
   mLoopingMode(DevelImageVisual::LoopingMode::RESTART),
@@ -72,8 +74,11 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mUpdateFrameNumber(false),
   mNeedAnimationFinishedTrigger(true),
   mAnimationDataUpdated(false),
-  mDestroyTask(false)
+  mDestroyTask(false),
+  mLoadRequest(false),
+  mLoadFailed(false)
 {
+  mVectorRenderer.UploadCompletedSignal().Connect(this, &VectorAnimationTask::OnUploadCompleted);
 }
 
 VectorAnimationTask::~VectorAnimationTask()
@@ -96,13 +101,14 @@ void VectorAnimationTask::Finalize()
   mDestroyTask = true;
 }
 
-bool VectorAnimationTask::Load(const std::string& url)
+bool VectorAnimationTask::Load()
 {
-  mUrl = url;
-
   if(!mVectorRenderer.Load(mUrl))
   {
     DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mUrl.c_str());
+    mLoadRequest = false;
+    mLoadFailed  = true;
+    mLoadCompletedTrigger->Trigger();
     return false;
   }
 
@@ -113,10 +119,8 @@ bool VectorAnimationTask::Load(const std::string& url)
   mFrameRate                 = mVectorRenderer.GetFrameRate();
   mFrameDurationMicroSeconds = MICROSECONDS_PER_SECOND / mFrameRate;
 
-  uint32_t width, height;
-  mVectorRenderer.GetDefaultSize(width, height);
-
-  SetSize(width, height);
+  mLoadRequest = false;
+  mLoadCompletedTrigger->Trigger();
 
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Load: file = %s [%d frames, %f fps] [%p]\n", mUrl.c_str(), mTotalFrame, mFrameRate, this);
 
@@ -132,6 +136,14 @@ void VectorAnimationTask::SetRenderer(Renderer renderer)
   DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetRenderer [%p]\n", this);
 }
 
+void VectorAnimationTask::RequestLoad(const std::string& url)
+{
+  mUrl         = url;
+  mLoadRequest = true;
+
+  mVectorAnimationThread.AddTask(this);
+}
+
 void VectorAnimationTask::SetAnimationData(const AnimationData& data)
 {
   ConditionalWait::ScopedLock lock(mConditionalWait);
@@ -293,12 +305,12 @@ void VectorAnimationTask::SetPlayRange(const Property::Array& playRange)
         mCurrentFrame = mEndFrame;
       }
 
-      DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%p]\n", mStartFrame, mEndFrame, this);
+      DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%s] [%p]\n", mStartFrame, mEndFrame, mUrl.c_str(), this);
     }
   }
   else
   {
-    DALI_LOG_ERROR("VectorAnimationTask::SetPlayRange: Invalid range (%d, %d) [%p]\n", startFrame, endFrame, this);
+    DALI_LOG_ERROR("VectorAnimationTask::SetPlayRange: Invalid range (%d, %d) [%s] [%p]\n", startFrame, endFrame, mUrl.c_str(), this);
     return;
   }
 }
@@ -326,7 +338,7 @@ void VectorAnimationTask::SetCurrentFrameNumber(uint32_t frameNumber)
   }
   else
   {
-    DALI_LOG_ERROR("Invalid frame number [%d (%d, %d)]\n", frameNumber, mStartFrame, mEndFrame);
+    DALI_LOG_ERROR("Invalid frame number [%d (%d, %d)] [%p]\n", frameNumber, mStartFrame, mEndFrame, this);
   }
 }
 
@@ -364,15 +376,16 @@ void VectorAnimationTask::GetLayerInfo(Property::Map& map) const
   mVectorRenderer.GetLayerInfo(map);
 }
 
-VectorAnimationTask::UploadCompletedSignalType& VectorAnimationTask::UploadCompletedSignal()
+VectorAnimationTask::ResourceReadySignalType& VectorAnimationTask::ResourceReadySignal()
 {
-  return mVectorRenderer.UploadCompletedSignal();
+  return mResourceReadySignal;
 }
 
-bool VectorAnimationTask::Rasterize()
+bool VectorAnimationTask::Rasterize(bool& keepAnimation)
 {
   bool     stopped = false;
   uint32_t currentFrame;
+  keepAnimation = false;
 
   {
     ConditionalWait::ScopedLock lock(mConditionalWait);
@@ -381,13 +394,27 @@ bool VectorAnimationTask::Rasterize()
       // The task will be destroyed. We don't need rasterization.
       return false;
     }
+
+    if(mLoadRequest)
+    {
+      bool result = Load();
+      if(!result)
+      {
+        return false;
+      }
+    }
+  }
+
+  if(mLoadFailed)
+  {
+    return false;
   }
 
   ApplyAnimationData();
 
   if(mPlayState == PlayState::PLAYING && mUpdateFrameNumber)
   {
-    mCurrentFrame = mForward ? mCurrentFrame + mDroppedFrames + 1 : mCurrentFrame - mDroppedFrames - 1;
+    mCurrentFrame = mForward ? mCurrentFrame + mDroppedFrames + 1 : (mCurrentFrame > mDroppedFrames ? mCurrentFrame - mDroppedFrames - 1 : 0);
     Dali::ClampInPlace(mCurrentFrame, mStartFrame, mEndFrame);
   }
 
@@ -479,13 +506,12 @@ bool VectorAnimationTask::Rasterize()
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this);
   }
 
-  bool keepAnimation = true;
-  if(mPlayState == PlayState::PAUSED || mPlayState == PlayState::STOPPED)
+  if(mPlayState != PlayState::PAUSED && mPlayState != PlayState::STOPPED)
   {
-    keepAnimation = false;
+    keepAnimation = true;
   }
 
-  return keepAnimation;
+  return true;
 }
 
 uint32_t VectorAnimationTask::GetStoppedFrame(uint32_t startFrame, uint32_t endFrame, uint32_t currentFrame)
@@ -600,6 +626,11 @@ void VectorAnimationTask::ApplyAnimationData()
     SetCurrentFrameNumber(mAnimationData[index].currentFrame);
   }
 
+  if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY)
+  {
+    mVectorRenderer.InvalidateBuffer();
+  }
+
   if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE)
   {
     if(mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING)
@@ -619,6 +650,31 @@ void VectorAnimationTask::ApplyAnimationData()
   mAnimationData[index].resendFlag = 0;
 }
 
+void VectorAnimationTask::OnUploadCompleted()
+{
+  mResourceReadySignal.Emit(true);
+}
+
+void VectorAnimationTask::OnLoadCompleted()
+{
+  if(!mLoadFailed)
+  {
+    if(mWidth == 0 && mHeight == 0)
+    {
+      uint32_t width, height;
+      mVectorRenderer.GetDefaultSize(width, height);
+
+      SetSize(width, height);
+
+      mVectorAnimationThread.AddTask(this);
+    }
+  }
+  else
+  {
+    // Load failed
+    mResourceReadySignal.Emit(false);
+  }
+}
 } // namespace Internal
 
 } // namespace Toolkit
index 3c0b8e3..fb4a55c 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_VECTOR_ANIMATION_TASK_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -42,10 +42,10 @@ typedef IntrusivePtr<VectorAnimationTask> VectorAnimationTaskPtr;
 /**
  * The task of the vector animation.
  */
-class VectorAnimationTask : public RefObject
+class VectorAnimationTask : public RefObject, public ConnectionTracker
 {
 public:
-  using UploadCompletedSignalType = Dali::VectorAnimationRenderer::UploadCompletedSignalType;
+  using ResourceReadySignalType = Signal<void(bool)>;
 
   using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
 
@@ -54,13 +54,14 @@ public:
    */
   enum ResendFlags
   {
-    RESEND_PLAY_RANGE    = 1 << 0,
-    RESEND_LOOP_COUNT    = 1 << 1,
-    RESEND_STOP_BEHAVIOR = 1 << 2,
-    RESEND_LOOPING_MODE  = 1 << 3,
-    RESEND_CURRENT_FRAME = 1 << 4,
-    RESEND_SIZE          = 1 << 5,
-    RESEND_PLAY_STATE    = 1 << 6
+    RESEND_PLAY_RANGE          = 1 << 0,
+    RESEND_LOOP_COUNT          = 1 << 1,
+    RESEND_STOP_BEHAVIOR       = 1 << 2,
+    RESEND_LOOPING_MODE        = 1 << 3,
+    RESEND_CURRENT_FRAME       = 1 << 4,
+    RESEND_SIZE                = 1 << 5,
+    RESEND_PLAY_STATE          = 1 << 6,
+    RESEND_NEED_RESOURCE_READY = 1 << 7
   };
 
   /**
@@ -124,19 +125,18 @@ public:
   void Finalize();
 
   /**
-   * @brief Loads the animation file.
+   * @brief Sets the renderer used to display the result image.
    *
-   * @param[in] url The url of the vector animation file
-   * @return True if loading success, false otherwise.
+   * @param[in] renderer The renderer used to display the result image
    */
-  bool Load(const std::string& url);
+  void SetRenderer(Renderer renderer);
 
   /**
-   * @brief Sets the renderer used to display the result image.
+   * @brief Request to load the animation file.
    *
-   * @param[in] renderer The renderer used to display the result image
+   * @param[in] url The url of the vector animation file
    */
-  void SetRenderer(Renderer renderer);
+  void RequestLoad(const std::string& url);
 
   /**
    * @brief Sets data to specify animation playback.
@@ -182,16 +182,17 @@ public:
   void GetLayerInfo(Property::Map& map) const;
 
   /**
-   * @brief Connect to this signal to be notified when the texture upload is completed.
+   * @brief Connect to this signal to be notified when the resource is ready.
    * @return The signal to connect to.
    */
-  UploadCompletedSignalType& UploadCompletedSignal();
+  ResourceReadySignalType& ResourceReadySignal();
 
   /**
    * @brief Rasterizes the current frame.
-   * @return true if the animation is running, false otherwise.
+   * @param[out] keepAnimation true if the animation is running, false otherwise.
+   * @return true if the rasterization succeeded, false otherwise.
    */
-  bool Rasterize();
+  bool Rasterize(bool& keepAnimation);
 
   /**
    * @brief Calculates the time for the next frame rasterization.
@@ -207,6 +208,13 @@ public:
 
 private:
   /**
+   * @brief Loads the animation file.
+   *
+   * @return True if loading succeeded, false otherwise.
+   */
+  bool Load();
+
+  /**
    * @brief Play the vector animation.
    */
   void PlayAnimation();
@@ -271,6 +279,16 @@ private:
    */
   void ApplyAnimationData();
 
+  /**
+   * @brief Called when the texture upload is completed.
+   */
+  void OnUploadCompleted();
+
+  /**
+   * @brief Event callback from rasterize thread. This is called when the file loading is completed.
+   */
+  void OnLoadCompleted();
+
   // Undefined
   VectorAnimationTask(const VectorAnimationTask& task) = delete;
 
@@ -291,7 +309,9 @@ private:
   AnimationData                        mAnimationData[2];
   VectorAnimationThread&               mVectorAnimationThread;
   ConditionalWait                      mConditionalWait;
+  ResourceReadySignalType              mResourceReadySignal;
   std::unique_ptr<EventThreadCallback> mAnimationFinishedTrigger;
+  std::unique_ptr<EventThreadCallback> mLoadCompletedTrigger;
   PlayState                            mPlayState;
   DevelImageVisual::StopBehavior::Type mStopBehavior;
   DevelImageVisual::LoopingMode::Type  mLoopingMode;
@@ -313,6 +333,8 @@ private:
   bool                                 mNeedAnimationFinishedTrigger;
   bool                                 mAnimationDataUpdated;
   bool                                 mDestroyTask;
+  bool                                 mLoadRequest;
+  bool                                 mLoadFailed;
 };
 
 } // namespace Internal
index 97634f6..7e505c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -112,7 +112,7 @@ void VectorAnimationThread::AddTask(VectorAnimationTaskPtr task)
   }
 }
 
-void VectorAnimationThread::OnTaskCompleted(VectorAnimationTaskPtr task, bool keepAnimation)
+void VectorAnimationThread::OnTaskCompleted(VectorAnimationTaskPtr task, bool success, bool keepAnimation)
 {
   if(!mDestroyThread)
   {
@@ -131,7 +131,7 @@ void VectorAnimationThread::OnTaskCompleted(VectorAnimationTaskPtr task, bool ke
       needRasterize = true;
     }
 
-    if(keepAnimation)
+    if(keepAnimation && success)
     {
       if(mCompletedTasks.end() == std::find(mCompletedTasks.begin(), mCompletedTasks.end(), task))
       {
@@ -220,9 +220,9 @@ void VectorAnimationThread::Rasterize()
     auto nextFrameTime = nextTask->GetNextFrameTime();
 
 #if defined(DEBUG_ENABLED)
-    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(nextFrameTime - currentTime);
+//    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(nextFrameTime - currentTime);
 
-    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationThread::Rasterize: [next time = %lld]\n", duration.count());
+//    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationThread::Rasterize: [next time = %lld]\n", duration.count());
 #endif
 
     if(nextFrameTime <= currentTime)
@@ -330,9 +330,9 @@ void VectorAnimationThread::SleepThread::Run()
     if(needToSleep)
     {
 #if defined(DEBUG_ENABLED)
-      auto sleepDuration = std::chrono::duration_cast<std::chrono::milliseconds>(mSleepTimePoint - std::chrono::steady_clock::now());
+//      auto sleepDuration = std::chrono::duration_cast<std::chrono::milliseconds>(mSleepTimePoint - std::chrono::steady_clock::now());
 
-      DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationThread::SleepThread::Run: [sleep duration = %lld]\n", sleepDuration.count());
+//      DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationThread::SleepThread::Run: [sleep duration = %lld]\n", sleepDuration.count());
 #endif
 
       std::this_thread::sleep_until(sleepTimePoint);
index 8190e7b..b752105 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_VECTOR_ANIMATION_THREAD_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -60,9 +60,11 @@ public:
 
   /**
    * @brief Called when the rasterization is completed from the rasterize thread.
-   * @param task The completed task
+   * @param[in] task The completed task
+   * @param[in] success true if the task succeeded, false otherwise.
+   * @param[in] keepAnimation true if the animation is running, false otherwise.
    */
-  void OnTaskCompleted(VectorAnimationTaskPtr task, bool stopped);
+  void OnTaskCompleted(VectorAnimationTaskPtr task, bool success, bool keepAnimation);
 
   /**
    * @brief Called when the sleep thread is awaken.
index 9a3f909..0ba9f52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -125,11 +125,12 @@ void VectorRasterizeThread::Rasterize()
 
   if(nextTask)
   {
-    bool keepAnimation = nextTask->Rasterize();
+    bool keepAnimation;
+    bool success = nextTask->Rasterize(keepAnimation);
 
     if(mCompletedCallback)
     {
-      CallbackBase::Execute(*mCompletedCallback, nextTask, keepAnimation);
+      CallbackBase::Execute(*mCompletedCallback, nextTask, success, keepAnimation);
     }
   }
 }