/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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/devel-api/threading/mutex.h>
#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/object/property-array.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;
}
bool Load(const std::string& url)
{
+ Dali::Mutex::ScopedLock lock(mMutex);
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;
}
+
+ mDefaultWidth = 100;
+ mDefaultHeight = 100;
+
return true;
}
- void SetRenderer( Dali::Renderer renderer )
+ bool Load(const Dali::Vector<uint8_t>& data)
{
- mRenderer = renderer;
+ Dali::Mutex::ScopedLock lock(mMutex);
- 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();
- }
+ mDefaultWidth = 100;
+ mDefaultHeight = 100;
+
+ return true;
}
- void SetSize( uint32_t width, uint32_t height )
+ void SetRenderer(Dali::Renderer renderer)
{
- mWidth = width;
+ mRenderer = renderer;
+ }
+
+ void SetSize(uint32_t width, uint32_t height)
+ {
+ Dali::Mutex::ScopedLock lock(mMutex);
+ 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)
{
+ Dali::Mutex::ScopedLock lock(mMutex);
+ 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(mDynamicPropertyCallback)
+ {
+ CallbackBase::ExecuteReturn<Property::Value>(*mDynamicPropertyCallback, 0, 0, frameNumber);
+ }
+
+ if(mNeedTrigger)
{
mEventThreadCallback->Trigger();
mNeedTrigger = false;
}
- if( frameNumber == 1 && mPreviousFrame != frameNumber )
+ if(frameNumber == 1 && mPreviousFrame != frameNumber)
{
mPreviousFrame = frameNumber;
// For test corverage
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
{
return true;
}
+ void InvalidateBuffer()
+ {
+ Dali::Mutex::ScopedLock lock(mMutex);
+ if(mResourceReady)
+ {
+ mNeedTrigger = true;
+ mResourceReady = false;
+ }
+ }
+
+ void AddPropertyValueCallback(const std::string& keyPath, Dali::VectorAnimationRenderer::VectorProperty property, CallbackBase* callback, int32_t id)
+ {
+ mDynamicPropertyCallback = std::unique_ptr<CallbackBase>(callback);
+ }
+
Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
{
return mUploadCompletedSignal;
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;
- Dali::Renderer mRenderer;
+ std::string mUrl;
+ Dali::Renderer mRenderer;
+ Dali::Mutex mMutex;
+ std::unique_ptr<CallbackBase> mDynamicPropertyCallback{nullptr};
+
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;
+ 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 *******************************/
/********************************************************************************/
Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
- return VectorAnimationRenderer( animationRenderer );
+ return VectorAnimationRenderer(animationRenderer);
}
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;
}
bool VectorAnimationRenderer::Load(const std::string& url)
{
- return Internal::Adaptor::GetImplementation( *this ).Load(url);
+ return Internal::Adaptor::GetImplementation(*this).Load(url);
+}
+
+bool VectorAnimationRenderer::Load(const Dali::Vector<uint8_t>& data)
+{
+ return Internal::Adaptor::GetImplementation(*this).Load(data);
}
-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);
+}
+
+void VectorAnimationRenderer::RenderStopped()
{
- 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::GetLayerInfo(Property::Map& map) const
+{
}
-void VectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
{
- Internal::Adaptor::GetImplementation( *this ).GetDefaultSize( width, height );
+ return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
}
-void VectorAnimationRenderer::GetLayerInfo( Property::Map& map ) const
+void VectorAnimationRenderer::GetMarkerInfo(Property::Map& map) const
{
+ map.Add(VECTOR_ANIMATION_MARKER_NAME_1, Property::Array({VECTOR_ANIMATION_MARKER_START_FRAME_1, VECTOR_ANIMATION_MARKER_END_FRAME_1}));
+ map.Add(VECTOR_ANIMATION_MARKER_NAME_2, Property::Array({VECTOR_ANIMATION_MARKER_START_FRAME_2, VECTOR_ANIMATION_MARKER_END_FRAME_2}));
}
-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();
+}
+
+void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPath, VectorProperty property, CallbackBase* callback, int32_t id)
+{
+ Internal::Adaptor::GetImplementation(*this).AddPropertyValueCallback(keyPath, property, callback, id);
}
VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
{
- return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
+ return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
}
} // namespace Dali
{
namespace VectorAnimationRenderer
{
-
-void RequestTrigger()
-{
- Dali::Internal::Adaptor::VectorAnimationRenderer::mNeedTrigger = true;
-}
-
void DelayRendering(uint32_t delay)
{
- Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime = delay;
+ Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime = delay;
+ Dali::Internal::Adaptor::gVectorAnimationRenderer->mTestFrameDrop = true;
}
uint32_t GetDroppedFrames()
return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
}
-} // VectorAnimationRenderer
-} // Test
-
+} // namespace VectorAnimationRenderer
+} // namespace Test