(AnimatedVectorImageVisual) Add some functions 57/193757/4
authorHeeyong Song <heeyong.song@samsung.com>
Mon, 26 Nov 2018 06:11:17 +0000 (15:11 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 10 Dec 2018 01:24:52 +0000 (10:24 +0900)
- Support size change
- Add loop count
- Add play range

Change-Id: Ic3e02708081d3314f664fa25a73db46b8cfaa901

15 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp [new file with mode: 0755]
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/file.list
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-image-rasterize-thread.cpp [deleted file]
dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h [deleted file]
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h

index df591a79fc5a647c669e18e75cc893ed9b009875..7a71661781c796af7e71a3c0aed724a7571d4c65 100755 (executable)
@@ -47,6 +47,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-singleton-service.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-timer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/toolkit-tts-player.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dali-test-suite-utils.cpp
    ../dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
    ../dali-toolkit/dali-toolkit-test-utils/mesh-builder.cpp
index 8c3199902e0734e6246629429e32a303285f6b34..4ead28ef9075da8d7fc2491681c950985f2e674b 100644 (file)
@@ -22,6 +22,7 @@
 #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 <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/color/color-visual.h>
@@ -320,3 +321,54 @@ int UtcDaliAnimatedVectorImageVisualCreateInstancePropertyMap(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualSetProperties(void)
+{
+  ToolkitTestApplication application;
+  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 )  );
+
+  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.SetSize( 200.0f, 200.0f );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for resource ready event callback
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  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 )  );
+
+  visualImpl.SetProperties( propertyMap1 );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  actor.Unparent( );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
index 05e2ccc4201a06174b174f9e6be955b70dd49f8f..bd9848fec1c362355b8e145bcd77f402dc14027b 100755 (executable)
@@ -99,6 +99,7 @@ LIST(APPEND TC_SOURCES
   dali-toolkit-test-utils/toolkit-timer.cpp
   dali-toolkit-test-utils/toolkit-tts-player.cpp
   dali-toolkit-test-utils/toolkit-native-image-source.cpp
+  dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
   dali-toolkit-test-utils/toolkit-video-player.cpp
   dali-toolkit-test-utils/toolkit-web-engine.cpp
   dali-toolkit-test-utils/toolkit-trigger-event-factory.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp
new file mode 100755 (executable)
index 0000000..003b8ea
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
+#include <dali/public-api/object/base-object.h>
+#include <toolkit-application.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class VectorAnimationRenderer: public Dali::BaseObject
+{
+public:
+
+  VectorAnimationRenderer( const std::string& url, Dali::Renderer renderer, uint32_t width, uint32_t height )
+  : mUrl( url ),
+    mRenderer( renderer ),
+    mWidth( width ),
+    mHeight( height )
+  {
+  }
+
+  void SetSize( uint32_t width, uint32_t height )
+  {
+    mWidth = width;
+    mHeight = height;
+  }
+
+  bool StartRender()
+  {
+    return true;
+  }
+
+  void StopRender()
+  {
+  }
+
+  void Render( uint32_t frameNumber )
+  {
+  }
+
+  uint32_t GetTotalFrameNumber()
+  {
+    return 5;
+  }
+
+public:
+
+  std::string mUrl;
+  Dali::Renderer mRenderer;
+  uint32_t mWidth;
+  uint32_t mHeight;
+
+};
+
+inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorAnimationRenderer handle is empty." );
+  BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< Internal::Adaptor::VectorAnimationRenderer& >( handle );
+}
+
+inline const VectorAnimationRenderer& GetImplementation( const Dali::VectorAnimationRenderer& renderer )
+{
+  DALI_ASSERT_ALWAYS( renderer && "VectorAnimationRenderer handle is empty." );
+  const BaseObject& handle = renderer.GetBaseObject();
+  return static_cast< const Internal::Adaptor::VectorAnimationRenderer& >( handle );
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+
+/********************************************************************************/
+/*********************************  PUBLIC CLASS  *******************************/
+/********************************************************************************/
+
+VectorAnimationRenderer VectorAnimationRenderer::New( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
+{
+  Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer( url, renderer, width, height );
+
+  return VectorAnimationRenderer( animationRenderer );
+}
+
+VectorAnimationRenderer::VectorAnimationRenderer()
+{
+}
+
+VectorAnimationRenderer::~VectorAnimationRenderer()
+{
+}
+
+VectorAnimationRenderer::VectorAnimationRenderer( Internal::Adaptor::VectorAnimationRenderer* internal )
+: BaseHandle( internal )
+{
+}
+
+VectorAnimationRenderer::VectorAnimationRenderer( const VectorAnimationRenderer& handle )
+: BaseHandle( handle )
+{
+}
+
+VectorAnimationRenderer& VectorAnimationRenderer::operator=( const VectorAnimationRenderer& rhs )
+{
+  BaseHandle::operator=( rhs );
+  return *this;
+}
+
+void VectorAnimationRenderer::SetSize( uint32_t width, uint32_t height )
+{
+  Internal::Adaptor::GetImplementation( *this ).SetSize( width, height );
+}
+
+bool VectorAnimationRenderer::StartRender()
+{
+  return Internal::Adaptor::GetImplementation( *this ).StartRender();
+}
+
+void VectorAnimationRenderer::StopRender()
+{
+  Internal::Adaptor::GetImplementation( *this ).StopRender();
+}
+
+void VectorAnimationRenderer::Render( uint32_t frameNumber )
+{
+  Internal::Adaptor::GetImplementation( *this ).Render( frameNumber );
+}
+
+uint32_t VectorAnimationRenderer::GetTotalFrameNumber()
+{
+  return Internal::Adaptor::GetImplementation( *this ).GetTotalFrameNumber();
+}
+
+} // namespace Dali;
+
index 57733dd547ac5e1a12141d6fca03901c2682c782..c0fee4158fd5d3932ec8d2e1339e33fb2e8d10d7 100644 (file)
@@ -115,14 +115,92 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual02(void)
   END_TEST;
 }
 
+int UtcDaliVisualFactoryGetAnimatedVectorImageVisual03(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetAnimatedVectorImageVisual03: Request animated vector image visual with a Property::Map" );
+
+  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 )  );
+
+  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.SetSize( 200.0f, 200.0f );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for resource ready event callback
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  actor.Unparent( );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
+
+int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetAnimatedVectorImageVisual04: Request animated vector image visual with a Property::Map" );
+
+  Property::Map propertyMap;
+  propertyMap.Add( "visualType", DevelVisual::ANIMATED_VECTOR_IMAGE )
+             .Add( "url", TEST_VECTOR_IMAGE_FILE_NAME  )
+             .Add( "loopCount", 3  )
+             .Add( "playRange", Vector2( 0.2f, 0.8f )  );
+
+  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.SetSize( 200.0f, 200.0f );
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  // Wait for resource ready event callback
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  actor.Unparent( );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
 {
   ToolkitTestApplication application;
   tet_infoline( "UtcDaliAnimatedVectorImageVisualGetPropertyMap01" );
 
+  Vector2 playRange( 0.2f, 0.8f );
+
   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  )
+             .Add( DevelImageVisual::Property::PLAY_RANGE, playRange  );
 
   // request AnimatedVectorImageVisual with a property map
   VisualFactory factory = VisualFactory::Get();
@@ -140,6 +218,14 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( value->Get< std::string >() == TEST_VECTOR_IMAGE_FILE_NAME );
 
+  value = resultMap.Find( DevelImageVisual::Property::LOOP_COUNT, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< int >() == 3 );
+
+  value = resultMap.Find( DevelImageVisual::Property::PLAY_RANGE, Property::VECTOR2 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< Vector2 >() == playRange );
+
   // request AnimatedVectorImageVisual with an URL
   Visual::Base visual2 = factory.CreateVisual( TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions() );
 
@@ -324,3 +410,81 @@ int UtcDaliAnimatedVectorImageVisualNaturalSize(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualLoopCount(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualLoopCount" );
+
+  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  );
+
+  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 );
+
+  Vector2 controlSize( 20.f, 30.f );
+  actor.SetSize( controlSize );
+
+  Stage::GetCurrent().Add( actor );
+
+  Property::Map attributes;
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  END_TEST;
+}
+
+int UtcDaliAnimatedVectorImageVisualPlayRange(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliAnimatedVectorImageVisualPlayRange" );
+
+  Vector2 playRange( 0.8f, 0.2f );
+
+  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::PLAY_RANGE, playRange  );
+
+  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 );
+
+  Vector2 controlSize( 20.f, 30.f );
+  actor.SetSize( controlSize );
+
+  Stage::GetCurrent().Add( actor );
+
+  Property::Map attributes;
+  DevelControl::DoAction( actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+  Renderer renderer = actor.GetRendererAt( 0u );
+  DALI_TEST_CHECK( renderer );
+
+  END_TEST;
+}
index b007485543148264d79923d9f7ea582cb27ada13..eb39aa6ad3e570f157b3ec3cf45f85d302bbf1fd 100644 (file)
@@ -83,6 +83,17 @@ enum Type
    */
   LOOP_COUNT = ORIENTATION_CORRECTION + 3,
 
+  /**
+   * @brief The playing range the AnimatedVectorImageVisual will use.
+   *
+   * Animation will play between the values specified. Both values should be between 0-1,
+   * otherwise they will be ignored. If the range provided is not in proper order ( minimum,maximum ), it will be reordered.
+   *
+   * @details Name "playRange", Type Property::VECTOR2, between 0 and 1
+   * @note Default 0 and 1
+   */
+  PLAY_RANGE = ORIENTATION_CORRECTION + 4
+
 };
 
 } //namespace Property
index 89a3d66a314f1aef9d1978339c15f9bbcc57f351..3a0375ed20f45596f2e29acb735cbb80d7199419 100755 (executable)
@@ -29,7 +29,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/visuals/animated-image/rolling-image-cache.cpp \
    $(toolkit_src_dir)/visuals/animated-image/rolling-gif-image-cache.cpp \
    $(toolkit_src_dir)/visuals/animated-vector-image/animated-vector-image-visual.cpp \
-   $(toolkit_src_dir)/visuals/animated-vector-image/vector-image-rasterize-thread.cpp \
+   $(toolkit_src_dir)/visuals/animated-vector-image/vector-rasterize-thread.cpp \
    $(toolkit_src_dir)/visuals/border/border-visual.cpp \
    $(toolkit_src_dir)/visuals/color/color-visual.cpp \
    $(toolkit_src_dir)/visuals/gradient/gradient-visual.cpp \
index 11f2f2495e37d1323a7d5f265694606cb410256b..96c7dddc2b8fd163aade4e130d054de1c4be3bf6 100644 (file)
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
-#include <dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h>
+#include <dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h>
 
 namespace Dali
 {
@@ -45,6 +46,7 @@ namespace
 {
 
 const Dali::Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
+constexpr auto LOOP_FOREVER = -1;
 
 } // unnamed namespace
 
@@ -68,8 +70,10 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual( VisualFactoryCache& factor
   mImageVisualShaderFactory( shaderFactory ),
   mUrl( imageUrl ),
   mVisualSize(),
+  mPlayRange( 0.0f, 1.0f ),
   mPlacementActor(),
   mVectorRasterizeThread(),
+  mLoopCount( LOOP_FOREVER ),
   mActionStatus( DevelAnimatedVectorImageVisual::Action::STOP )
 {
   // the rasterized image is with pre-multiplied alpha format
@@ -93,6 +97,8 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   {
     map.Insert( Toolkit::ImageVisual::Property::URL, mUrl.GetUrl() );
   }
+  map.Insert( Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast< int >( mLoopCount ) );
+  map.Insert( Toolkit::DevelImageVisual::Property::PLAY_RANGE, static_cast< Vector2 >( mPlayRange ) );
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -110,11 +116,63 @@ void AnimatedVectorImageVisual::DoSetProperties( const Property::Map& propertyMa
     {
       DoSetProperty( keyValue.first.indexKey, keyValue.second );
     }
+    else
+    {
+       if( keyValue.first == LOOP_COUNT_NAME )
+       {
+          DoSetProperty( Toolkit::DevelImageVisual::Property::LOOP_COUNT, keyValue.second );
+       }
+       else if( keyValue.first == PLAY_RANGE_NAME )
+       {
+          DoSetProperty( Toolkit::DevelImageVisual::Property::PLAY_RANGE, keyValue.second );
+       }
+    }
   }
 }
 
 void AnimatedVectorImageVisual::DoSetProperty( Property::Index index, const Property::Value& value )
 {
+  switch(index)
+  {
+    case Toolkit::DevelImageVisual::Property::LOOP_COUNT:
+    {
+      int32_t loopCount;
+      if( value.Get( loopCount ) )
+      {
+        mLoopCount = loopCount;
+        if( mVectorRasterizeThread )
+        {
+          mVectorRasterizeThread->SetLoopCount( loopCount );
+        }
+      }
+      break;
+    }
+    case Toolkit::DevelImageVisual::Property::PLAY_RANGE:
+    {
+      Vector2 range;
+      if( value.Get( range ) )
+      {
+        // Make sure the range specified is between 0.0 and 1.0
+        if( range.x >= 0.0f && range.x <= 1.0f && range.y >= 0.0f && range.y <= 1.0f )
+        {
+          Vector2 orderedRange( range );
+          // If the range is not in order swap values
+          if( range.x > range.y )
+          {
+            orderedRange = Vector2( range.y, range.x );
+          }
+
+          mPlayRange = orderedRange;
+
+          if( mVectorRasterizeThread )
+          {
+            mVectorRasterizeThread->SetPlayRange( mPlayRange );
+          }
+        }
+      }
+      break;
+    }
+  }
 }
 
 void AnimatedVectorImageVisual::DoSetOnStage( Actor& actor )
@@ -192,6 +250,9 @@ void AnimatedVectorImageVisual::OnSetTransform()
         mVectorRasterizeThread = std::unique_ptr< VectorRasterizeThread >( new VectorRasterizeThread( mUrl.GetUrl(), mImpl->mRenderer, width, height ) );
 
         mVectorRasterizeThread->SetResourceReadyCallback( new EventThreadCallback( MakeCallback( this, &AnimatedVectorImageVisual::OnResourceReady ) ) );
+        mVectorRasterizeThread->SetLoopCount( mLoopCount );
+        mVectorRasterizeThread->SetPlayRange( mPlayRange );
+
         mVectorRasterizeThread->Start();
 
         if( mActionStatus == DevelAnimatedVectorImageVisual::Action::PLAY )
@@ -207,7 +268,10 @@ void AnimatedVectorImageVisual::OnSetTransform()
       }
       else
       {
-        // TODO: change size
+        uint32_t width = static_cast< uint32_t >( visualSize.width );
+        uint32_t height = static_cast< uint32_t >( visualSize.height );
+
+        mVectorRasterizeThread->SetSize( width, height );
       }
     }
   }
index 33c46b66edc12080c56a028af23068556bb72271..268cb06916a74a50c649143d5096e638cd11d166 100644 (file)
@@ -160,8 +160,11 @@ private:
   ImageVisualShaderFactory&                    mImageVisualShaderFactory;
   VisualUrl                                    mUrl;
   Vector2                                      mVisualSize;
+  Vector2                                      mPlayRange;
   WeakHandle< Actor >                          mPlacementActor;
   std::unique_ptr< VectorRasterizeThread >     mVectorRasterizeThread;
+
+  int32_t                                      mLoopCount;
   DevelAnimatedVectorImageVisual::Action::Type mActionStatus;
 };
 
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp
deleted file mode 100644 (file)
index 50bf304..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// CLASS HEADER
-#include <dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h>
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/thread-settings.h>
-#include <dali/integration-api/adaptors/adaptor.h>
-#include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-namespace
-{
-
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
-#endif
-
-} // unnamed namespace
-
-VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
-: mUrl( url ),
-  mVectorRenderer(),
-  mResourceReadyTrigger( NULL ),
-  mCurrentFrame( 0 ),
-  mTotalFrame( 0 ),
-  mWidth( width ),
-  mHeight( height ),
-  mNeedRender( false ),
-  mPlaying( false ),
-  mPaused( false ),
-  mDestroyThread( false ),
-  mResourceReady( false ),
-  mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
-{
-  mVectorRenderer = VectorAnimationRenderer::New( mUrl, renderer, width, height );
-}
-
-VectorRasterizeThread::~VectorRasterizeThread()
-{
-  // Stop the thread
-  {
-    ConditionalWait::ScopedLock lock( mConditionalWait );
-    mDestroyThread = true;
-    mConditionalWait.Notify( lock );
-
-    // This should be called in the main thread to stop waiting for the dequeuable buffer.
-    mVectorRenderer.StopRender();
-  }
-
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
-
-  Join();
-
-  delete mResourceReadyTrigger;
-}
-
-void VectorRasterizeThread::Run()
-{
-  SetThreadName( "VectorImageThread" );
-  mLogFactory.InstallLogFunction();
-
-  //TODO: check the return value
-  StartRender();
-
-  while( IsThreadReady() )
-  {
-    Rasterize();
-  }
-}
-
-void VectorRasterizeThread::StartAnimation()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( !mPlaying )
-  {
-    mPlaying = true;
-    mPaused = false;
-    mConditionalWait.Notify( lock );
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
-  }
-}
-
-void VectorRasterizeThread::StopAnimation()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying )
-  {
-    mPlaying = false;
-    mPaused = false;
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
-  }
-}
-
-void VectorRasterizeThread::PauseAnimation()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying && !mPaused )
-  {
-    mPaused = true;
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
-  }
-}
-
-void VectorRasterizeThread::ResumeAnimation()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  if( mPlaying && mPaused )
-  {
-    mPaused = false;
-    mConditionalWait.Notify( lock );
-
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::ResumeAnimation: Resume\n" );
-  }
-}
-
-void VectorRasterizeThread::RenderFrame()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-  mNeedRender = true;
-  mConditionalWait.Notify( lock );
-
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
-}
-
-void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
-{
-  mResourceReadyTrigger = callback;
-}
-
-bool VectorRasterizeThread::IsThreadReady()
-{
-  ConditionalWait::ScopedLock lock( mConditionalWait );
-
-  if( ( !mPlaying || mPaused ) && !mNeedRender && !mDestroyThread )
-  {
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
-
-    if( !mPlaying )
-    {
-      mCurrentFrame = 0;
-    }
-
-    mConditionalWait.Wait( lock );
-  }
-
-  // Keep the thread alive if this thread is NOT to be destroyed
-  return !mDestroyThread;
-}
-
-bool VectorRasterizeThread::StartRender()
-{
-  //TODO: check the return value
-  mVectorRenderer.StartRender();
-
-  mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
-
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d]\n", mTotalFrame );
-
-  return true;
-}
-
-void VectorRasterizeThread::Rasterize()
-{
-  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
-
-  // Rasterize
-  mVectorRenderer.Render( mCurrentFrame );
-
-  if( mPlaying && !mPaused )
-  {
-    mCurrentFrame++;
-
-    if( mCurrentFrame >= mTotalFrame )
-    {
-      mCurrentFrame = 0;
-    }
-  }
-
-  mNeedRender = false;
-
-  if( !mResourceReady )
-  {
-    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
-
-    mResourceReadyTrigger->Trigger();
-    mResourceReady = true;
-  }
-}
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h
deleted file mode 100644 (file)
index 05a5bba..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#ifndef DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
-#define DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
-
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
-#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
-#include <dali/devel-api/threading/conditional-wait.h>
-#include <dali/devel-api/threading/mutex.h>
-#include <dali/devel-api/threading/thread.h>
-#include <dali/integration-api/adaptors/log-factory-interface.h>
-#include <string>
-
-namespace Dali
-{
-
-namespace Toolkit
-{
-
-namespace Internal
-{
-
-/**
- * The worker thread for vector image rasterization.
- */
-class VectorRasterizeThread : public Thread
-{
-public:
-
-  /**
-   * @brief Constructor.
-   *
-   * @param[in] url The url of the vector animation file
-   * @param[in] renderer The renderer used to render the image
-   * @param[in] width The width of the content
-   * @param[in] height The height of the content
-   */
-  VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height );
-
-  /**
-   * @brief Destructor.
-   */
-  virtual ~VectorRasterizeThread();
-
-  /**
-   * @brief Play the vector animation
-   */
-  void StartAnimation();
-
-  /**
-   * @brief Stop the vector animation
-   */
-  void StopAnimation();
-
-  /**
-   * @brief Pause the vector animation
-   */
-  void PauseAnimation();
-
-  /**
-   * @brief Resume the vector animation
-   */
-  void ResumeAnimation();
-
-  /**
-   * @brief Render one frame. The current frame number will be increased.
-   */
-  void RenderFrame();
-
-  /**
-   * @brief This callback is called after the first frame is ready.
-   * @param callback The resource ready callback
-   */
-  void SetResourceReadyCallback( EventThreadCallback* callback );
-
-protected:
-
-  /**
-   * @brief The entry function of the worker thread.
-   *        It rasterizes the vector image.
-   */
-  void Run() override;
-
-private:
-
-  /**
-   * @brief Called by the rasterize thread which ensures a wait if required.
-   * @return false if the thread should stop.
-   */
-  bool IsThreadReady();
-
-  /**
-   * @brief Start rendering
-   */
-  bool StartRender();
-
-  /**
-   * @brief Rasterize the current frame.
-   */
-  void Rasterize();
-
-  // Undefined
-  VectorRasterizeThread( const VectorRasterizeThread& thread ) = delete;
-
-  // Undefined
-  VectorRasterizeThread& operator=( const VectorRasterizeThread& thread ) = delete;
-
-private:
-
-  std::string                mUrl;
-  VectorAnimationRenderer    mVectorRenderer;
-  ConditionalWait            mConditionalWait;
-  Dali::Mutex                mMutex;
-  EventThreadCallback*       mResourceReadyTrigger;
-  uint32_t                   mCurrentFrame;
-  uint32_t                   mTotalFrame;
-  uint32_t                   mWidth;
-  uint32_t                   mHeight;
-  bool                       mNeedRender;
-  bool                       mPlaying;
-  bool                       mPaused;
-  bool                       mDestroyThread;  ///< Whether the thread be destroyed
-  bool                       mResourceReady;
-  const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
-
-};
-
-} // namespace Internal
-
-} // namespace Toolkit
-
-} // namespace Dali
-
-#endif // DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp
new file mode 100644 (file)
index 0000000..52c6541
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+constexpr auto LOOP_FOREVER = -1;
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_VECTOR_ANIMATION" );
+#endif
+
+} // unnamed namespace
+
+VectorRasterizeThread::VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height )
+: mUrl( url ),
+  mVectorRenderer(),
+  mConditionalWait(),
+  mMutex(),
+  mResourceReadyTrigger( NULL ),
+  mPlayRange( 0.0f, 1.0f ),
+  mCurrentFrame( 0 ),
+  mTotalFrame( 0 ),
+  mStartFrame( 0 ),
+  mEndFrame( 0 ),
+  mWidth( width ),
+  mHeight( height ),
+  mLoopCount( LOOP_FOREVER ),
+  mCurrentLoop( 0 ),
+  mNeedRender( false ),
+  mPlaying( false ),
+  mPaused( false ),
+  mDestroyThread( false ),
+  mResourceReady( false ),
+  mLogFactory( Dali::Adaptor::Get().GetLogFactory() )
+{
+  mVectorRenderer = VectorAnimationRenderer::New( mUrl, renderer, width, height );
+}
+
+VectorRasterizeThread::~VectorRasterizeThread()
+{
+  // Stop the thread
+  {
+    ConditionalWait::ScopedLock lock( mConditionalWait );
+    mDestroyThread = true;
+    mConditionalWait.Notify( lock );
+
+    // This should be called in the main thread to stop waiting for the dequeuable buffer.
+    mVectorRenderer.StopRender();
+  }
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::~VectorRasterizeThread: Join\n" );
+
+  Join();
+
+  delete mResourceReadyTrigger;
+}
+
+void VectorRasterizeThread::Run()
+{
+  SetThreadName( "VectorImageThread" );
+  mLogFactory.InstallLogFunction();
+
+  //TODO: check the return value
+  StartRender();
+
+  while( IsThreadReady() )
+  {
+    Rasterize();
+  }
+}
+
+void VectorRasterizeThread::SetSize( uint32_t width, uint32_t height )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  mVectorRenderer.SetSize( width, height );
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::SetSize: width = %d, height = %d\n", width, height );
+}
+
+void VectorRasterizeThread::StartAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( !mPlaying )
+  {
+    mPlaying = true;
+    mPaused = false;
+    mConditionalWait.Notify( lock );
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartAnimation: Start\n" );
+  }
+}
+
+void VectorRasterizeThread::StopAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying )
+  {
+    mPlaying = false;
+    mPaused = false;
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StopAnimation: Stop\n" );
+  }
+}
+
+void VectorRasterizeThread::PauseAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying && !mPaused )
+  {
+    mPaused = true;
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::PauseAnimation: Pause\n" );
+  }
+}
+
+void VectorRasterizeThread::ResumeAnimation()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  if( mPlaying && mPaused )
+  {
+    mPaused = false;
+    mConditionalWait.Notify( lock );
+
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::ResumeAnimation: Resume\n" );
+  }
+}
+
+void VectorRasterizeThread::RenderFrame()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  mNeedRender = true;
+  mConditionalWait.Notify( lock );
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::RenderFrame: Render\n" );
+}
+
+void VectorRasterizeThread::SetResourceReadyCallback( EventThreadCallback* callback )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+  mResourceReadyTrigger = callback;
+}
+
+void VectorRasterizeThread::SetLoopCount( int16_t count )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  mLoopCount = count;
+
+  // Reset progress
+  mCurrentLoop = 0;
+  mCurrentFrame = mStartFrame;
+}
+
+void VectorRasterizeThread::SetPlayRange( Vector2 range )
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  mPlayRange = range;
+
+  if( mTotalFrame != 0 )
+  {
+    mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
+    mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
+  }
+}
+
+bool VectorRasterizeThread::IsThreadReady()
+{
+  ConditionalWait::ScopedLock lock( mConditionalWait );
+
+  if( ( !mPlaying || mPaused ) && !mNeedRender && !mDestroyThread )
+  {
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::IsThreadReady: Wait\n" );
+
+    if( !mPlaying )
+    {
+      mCurrentFrame = mStartFrame;
+      mCurrentLoop = 0;
+    }
+
+    mConditionalWait.Wait( lock );
+  }
+
+  // Keep the thread alive if this thread is NOT to be destroyed
+  return !mDestroyThread;
+}
+
+bool VectorRasterizeThread::StartRender()
+{
+  //TODO: check the return value
+  mVectorRenderer.StartRender();
+
+  mTotalFrame = mVectorRenderer.GetTotalFrameNumber();
+
+  mStartFrame = static_cast< uint32_t >( mPlayRange.x * mTotalFrame + 0.5f );
+  mEndFrame = static_cast< uint32_t >( mPlayRange.y * mTotalFrame + 0.5f );
+
+  mCurrentFrame = mStartFrame;
+
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d (%d, %d)]\n", mTotalFrame, mStartFrame, mEndFrame );
+
+  return true;
+}
+
+void VectorRasterizeThread::Rasterize()
+{
+  DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: [%d]\n", mCurrentFrame );
+
+  // Rasterize
+  mVectorRenderer.Render( mCurrentFrame );
+
+  if( mPlaying && !mPaused )
+  {
+    if( ++mCurrentFrame >= mEndFrame )
+    {
+      if( mLoopCount < 0 )
+      {
+        // repeat forever
+        mCurrentFrame = mStartFrame;
+      }
+      else
+      {
+        mCurrentLoop++;
+        if( mCurrentLoop >= mLoopCount )
+        {
+          // Animation is finished
+          mPlaying = false;
+        }
+        else
+        {
+          mCurrentFrame = mStartFrame;
+        }
+      }
+    }
+  }
+
+  mNeedRender = false;
+
+  if( !mResourceReady )
+  {
+    DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::Rasterize: Resource ready trigger\n" );
+
+    mResourceReadyTrigger->Trigger();
+    mResourceReady = true;
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h
new file mode 100644 (file)
index 0000000..f05f8b6
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
+#define DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
+#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/integration-api/adaptors/log-factory-interface.h>
+#include <string>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * The worker thread for vector image rasterization.
+ */
+class VectorRasterizeThread : public Thread
+{
+public:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] url The url of the vector animation file
+   * @param[in] renderer The renderer used to render the image
+   * @param[in] width The width of the content
+   * @param[in] height The height of the content
+   */
+  VectorRasterizeThread( const std::string& url, Renderer renderer, uint32_t width, uint32_t height );
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~VectorRasterizeThread();
+
+  /**
+   * @brief Sets the target image size.
+   *
+   * @param[in] width The target image width
+   * @param[in] height The target image height
+   */
+  void SetSize( uint32_t width, uint32_t height );
+
+  /**
+   * @brief Play the vector animation.
+   */
+  void StartAnimation();
+
+  /**
+   * @brief Stop the vector animation.
+   */
+  void StopAnimation();
+
+  /**
+   * @brief Pause the vector animation.
+   */
+  void PauseAnimation();
+
+  /**
+   * @brief Resume the vector animation.
+   */
+  void ResumeAnimation();
+
+  /**
+   * @brief Render one frame. The current frame number will be increased.
+   */
+  void RenderFrame();
+
+  /**
+   * @brief This callback is called after the first frame is ready.
+   * @param[in] callback The resource ready callback
+   */
+  void SetResourceReadyCallback( EventThreadCallback* callback );
+
+  /**
+   * @brief Enable looping for 'count' repeats. -1 means to repeat forever.
+   * @param[in] count The number of times to loop
+   */
+  void SetLoopCount( int16_t count );
+
+  /**
+   * @brief Set the playing range.
+   * @param[in] range Two values between [0,1] to specify minimum and maximum progress.
+   * The animation will play between those values.
+   */
+  void SetPlayRange( Vector2 range );
+
+protected:
+
+  /**
+   * @brief The entry function of the worker thread.
+   *        It rasterizes the vector image.
+   */
+  void Run() override;
+
+private:
+
+  /**
+   * @brief Called by the rasterize thread which ensures a wait if required.
+   * @return false if the thread should stop.
+   */
+  bool IsThreadReady();
+
+  /**
+   * @brief Start rendering
+   */
+  bool StartRender();
+
+  /**
+   * @brief Rasterize the current frame.
+   */
+  void Rasterize();
+
+  // Undefined
+  VectorRasterizeThread( const VectorRasterizeThread& thread ) = delete;
+
+  // Undefined
+  VectorRasterizeThread& operator=( const VectorRasterizeThread& thread ) = delete;
+
+private:
+
+  std::string                mUrl;
+  VectorAnimationRenderer    mVectorRenderer;
+  ConditionalWait            mConditionalWait;
+  Dali::Mutex                mMutex;
+  EventThreadCallback*       mResourceReadyTrigger;
+  Vector2                    mPlayRange;
+  uint32_t                   mCurrentFrame;
+  uint32_t                   mTotalFrame;
+  uint32_t                   mStartFrame;
+  uint32_t                   mEndFrame;
+  uint32_t                   mWidth;
+  uint32_t                   mHeight;
+  int16_t                    mLoopCount;
+  int16_t                    mCurrentLoop;
+  bool                       mNeedRender;
+  bool                       mPlaying;
+  bool                       mPaused;
+  bool                       mDestroyThread;  ///< Whether the thread be destroyed
+  bool                       mResourceReady;
+  const Dali::LogFactoryInterface& mLogFactory; ///< The log factory
+
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_VECTOR_IMAGE_RASTERIZE_THREAD_H
index 9257a74bf87facc7f578c2ec7b2e37e833ca90a8..e0382b35b60b48ba09e15a6d6c9f9cf8f9b18c9b 100644 (file)
@@ -100,6 +100,7 @@ const char * const RELEASE_POLICY_NAME("releasePolicy");
 const char * const ORIENTATION_CORRECTION_NAME("orientationCorrection");
 const char * const AUXILIARY_IMAGE_NAME("auxiliaryImage");
 const char * const AUXILIARY_IMAGE_ALPHA_NAME("auxiliaryImageAlpha");
+const char * const PLAY_RANGE_NAME("playRange");
 
 // Text visual
 const char * const TEXT_PROPERTY( "text" );
index 89b73a7ca939fca8ff71953ca895dd46a4516b8d..6ae808b97ae86ac145e4c950b880ae097bcd1dfe 100644 (file)
@@ -85,6 +85,7 @@ extern const char * const RELEASE_POLICY_NAME;
 extern const char * const ORIENTATION_CORRECTION_NAME;
 extern const char * const AUXILLARY_IMAGE_NAME;
 extern const char * const AUXILLARY_IMAGE_ALPHA_NAME;
+extern const char * const PLAY_RANGE_NAME;
 
 // Text visual
 extern const char * const TEXT_PROPERTY;