From 27de3fbcd7105d89cbe3854bcf908f80176b31f0 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Mon, 26 Nov 2018 15:11:17 +0900 Subject: [PATCH] (AnimatedVectorImageVisual) Add some functions - Support size change - Add loop count - Add play range Change-Id: Ic3e02708081d3314f664fa25a73db46b8cfaa901 --- .../src/dali-toolkit-internal/CMakeLists.txt | 1 + .../utc-Dali-Visuals-internal.cpp | 52 +++++++ automated-tests/src/dali-toolkit/CMakeLists.txt | 1 + .../toolkit-vector-animation-renderer.cpp | 156 +++++++++++++++++++ .../utc-Dali-AnimatedVectorImageVisual.cpp | 166 ++++++++++++++++++++- .../visuals/image-visual-properties-devel.h | 11 ++ dali-toolkit/internal/file.list | 2 +- .../animated-vector-image-visual.cpp | 68 ++++++++- .../animated-vector-image-visual.h | 3 + ...rize-thread.cpp => vector-rasterize-thread.cpp} | 77 +++++++++- ...asterize-thread.h => vector-rasterize-thread.h} | 36 ++++- .../internal/visuals/visual-string-constants.cpp | 1 + .../internal/visuals/visual-string-constants.h | 1 + 13 files changed, 559 insertions(+), 16 deletions(-) create mode 100755 automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp rename dali-toolkit/internal/visuals/animated-vector-image/{vector-image-rasterize-thread.cpp => vector-rasterize-thread.cpp} (73%) rename dali-toolkit/internal/visuals/animated-vector-image/{vector-image-rasterize-thread.h => vector-rasterize-thread.h} (77%) diff --git a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt index df591a7..7a71661 100755 --- a/automated-tests/src/dali-toolkit-internal/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit-internal/CMakeLists.txt @@ -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 diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp index 8c31999..4ead28e 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals-internal.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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; +} diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 05e2ccc..bd9848f 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -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 index 0000000..003b8ea --- /dev/null +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp @@ -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 +#include +#include + +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; + diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp index 57733dd..c0fee41 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp @@ -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; +} diff --git a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h index b007485..eb39aa6 100644 --- a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h @@ -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 diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 89a3d66..3a0375e 100755 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -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 \ diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 11f2f24..96c7ddd 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -26,11 +26,12 @@ // INTERNAL INCLUDES #include #include +#include #include #include #include #include -#include +#include 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 ); } } } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h index 33c46b6..268cb06 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h @@ -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-rasterize-thread.cpp similarity index 73% rename from dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp rename to dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp index 50bf304..52c6541 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include +#include // EXTERNAL INCLUDES #include @@ -37,6 +37,8 @@ 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 @@ -46,11 +48,18 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New( Debug::NoLogging, 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 ), @@ -94,6 +103,14 @@ void VectorRasterizeThread::Run() } } +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 ); @@ -153,9 +170,34 @@ void VectorRasterizeThread::RenderFrame() 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 ); @@ -166,7 +208,8 @@ bool VectorRasterizeThread::IsThreadReady() if( !mPlaying ) { - mCurrentFrame = 0; + mCurrentFrame = mStartFrame; + mCurrentLoop = 0; } mConditionalWait.Wait( lock ); @@ -183,7 +226,12 @@ bool VectorRasterizeThread::StartRender() mTotalFrame = mVectorRenderer.GetTotalFrameNumber(); - DALI_LOG_INFO( gVectorAnimationLogFilter, Debug::Verbose, "VectorRasterizeThread::StartRender: Renderer is started [%d]\n", mTotalFrame ); + 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; } @@ -197,11 +245,26 @@ void VectorRasterizeThread::Rasterize() if( mPlaying && !mPaused ) { - mCurrentFrame++; - - if( mCurrentFrame >= mTotalFrame ) + if( ++mCurrentFrame >= mEndFrame ) { - mCurrentFrame = 0; + if( mLoopCount < 0 ) + { + // repeat forever + mCurrentFrame = mStartFrame; + } + else + { + mCurrentLoop++; + if( mCurrentLoop >= mLoopCount ) + { + // Animation is finished + mPlaying = false; + } + else + { + mCurrentFrame = mStartFrame; + } + } } } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h similarity index 77% rename from dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h rename to dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h index 05a5bba..f05f8b6 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-image-rasterize-thread.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-rasterize-thread.h @@ -58,22 +58,30 @@ public: virtual ~VectorRasterizeThread(); /** - * @brief Play the vector animation + * @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 + * @brief Stop the vector animation. */ void StopAnimation(); /** - * @brief Pause the vector animation + * @brief Pause the vector animation. */ void PauseAnimation(); /** - * @brief Resume the vector animation + * @brief Resume the vector animation. */ void ResumeAnimation(); @@ -84,10 +92,23 @@ public: /** * @brief This callback is called after the first frame is ready. - * @param callback The resource ready callback + * @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: /** @@ -127,10 +148,15 @@ private: 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; diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index 9257a74..e0382b3 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -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" ); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index 89b73a7..6ae808b 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -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; -- 2.7.4