[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / toolkit-vector-animation-renderer.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 18ce2ef..aec90ad
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/adaptor-framework/native-image-source.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>
 
 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 ),
-    mPreviousFrame( 0 ),
-    mFrameRate( 60.0f ),
-    mEventThreadCallback( new EventThreadCallback( MakeCallback( this, &VectorAnimationRenderer::OnTriggered ) ) )
+    mWidth(0),
+    mHeight(0),
+    mDefaultWidth(0),
+    mDefaultHeight(0),
+    mTotalFrameNumber(VECTOR_ANIMATION_TOTAL_FRAME_NUMBER),
+    mPreviousFrame(0),
+    mDelayTime(0),
+    mDroppedFrames(0),
+    mFrameRate(60.0f),
+    mTestFrameDrop(false),
+    mNeedDroppedFrames(false),
+    mUseNativeImage(false),
+    mEventThreadCallback(new EventThreadCallback(MakeCallback(this, &VectorAnimationRenderer::OnTriggered)))
   {
     mCount++;
 
-    if( mCount == 2 )
+    if(mCount == 2)
     {
       mFrameRate = 0.1f;
     }
@@ -59,50 +74,86 @@ public:
 
   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;
+    }
+
+    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)
   {
-    if( mNeedTrigger )
+    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;
+      mNeedDroppedFrames = true;
+    }
+    else if(mNeedDroppedFrames)
+    {
+      mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
+      mNeedTrigger       = true;
+      mNeedDroppedFrames = false;
+    }
+
+    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
@@ -114,7 +165,7 @@ public:
 
   uint32_t GetTotalFrameNumber() const
   {
-    return VECTOR_ANIMATION_TOTAL_FRAME_NUMBER;
+    return mTotalFrameNumber;
   }
 
   float GetFrameRate() const
@@ -122,23 +173,23 @@ public:
     return mFrameRate;
   }
 
-  void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+  void GetDefaultSize(uint32_t& width, uint32_t& height) const
   {
-    width = 100;
-    height = 100;
+    width  = mDefaultWidth;
+    height = mDefaultHeight;
   }
 
-  bool GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const
+  bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
   {
-    if( marker.compare( VECTOR_ANIMATION_MARKER_NAME_1 ) == 0 )
+    if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
     {
       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
-      endFrame = VECTOR_ANIMATION_MARKER_END_FRAME_1;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
     }
-    else if( marker.compare( VECTOR_ANIMATION_MARKER_NAME_2 ) == 0 )
+    else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
     {
       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
-      endFrame = VECTOR_ANIMATION_MARKER_END_FRAME_2;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
     }
     else
     {
@@ -147,6 +198,27 @@ public:
     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);
+  }
+
+  void KeepRasterizedBuffer()
+  {
+    Dali::Mutex::ScopedLock lock(mMutex);
+    mEnableFixedCache = true;
+  }
+
   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
   {
     return mUploadCompletedSignal;
@@ -154,45 +226,81 @@ public:
 
   void OnTriggered()
   {
+    if(!mResourceReady)
+    {
+      mResourceReady = true;
+
+      Dali::TextureSet textureSet = mRenderer.GetTextures();
+
+      if(mUseNativeImage)
+      {
+        Dali::NativeImageSourcePtr nativeImageSource = Dali::NativeImageSource::New(mWidth, mHeight, Dali::NativeImageSource::COLOR_DEPTH_32);
+        Dali::Texture              texture           = Dali::Texture::New(*nativeImageSource);
+        textureSet.SetTexture(0, texture);
+      }
+      else
+      {
+        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;
-  float mFrameRate;
+  uint32_t mDelayTime;
+  uint32_t mDroppedFrames;
+  float    mFrameRate;
+  bool     mTestFrameDrop;
+  bool     mNeedDroppedFrames;
+  bool     mLoadFailed{false};
+  bool     mResourceReady{false};
+  bool     mNeedTrigger{true};
+  bool     mEnableFixedCache{false};
+  bool     mUseNativeImage{false};
+
   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  *******************************/
 /********************************************************************************/
@@ -201,7 +309,9 @@ VectorAnimationRenderer VectorAnimationRenderer::New()
 {
   Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer();
 
-  return VectorAnimationRenderer( animationRenderer );
+  Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
+
+  return VectorAnimationRenderer(animationRenderer);
 }
 
 VectorAnimationRenderer::VectorAnimationRenderer()
@@ -212,19 +322,19 @@ VectorAnimationRenderer::~VectorAnimationRenderer()
 {
 }
 
-VectorAnimationRenderer::VectorAnimationRenderer( Internal::Adaptor::VectorAnimationRenderer* internal )
-: BaseHandle( internal )
+VectorAnimationRenderer::VectorAnimationRenderer(Internal::Adaptor::VectorAnimationRenderer* internal)
+: BaseHandle(internal)
 {
 }
 
-VectorAnimationRenderer::VectorAnimationRenderer( const VectorAnimationRenderer& handle )
-: BaseHandle( handle )
+VectorAnimationRenderer::VectorAnimationRenderer(const VectorAnimationRenderer& handle)
+: BaseHandle(handle)
 {
 }
 
-VectorAnimationRenderer& VectorAnimationRenderer::operator=( const VectorAnimationRenderer& rhs )
+VectorAnimationRenderer& VectorAnimationRenderer::operator=(const VectorAnimationRenderer& rhs)
 {
-  BaseHandle::operator=( rhs );
+  BaseHandle::operator=(rhs);
   return *this;
 }
 
@@ -234,51 +344,81 @@ void VectorAnimationRenderer::Finalize()
 
 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);
+}
+
+void VectorAnimationRenderer::KeepRasterizedBuffer()
+{
+  Internal::Adaptor::GetImplementation(*this).KeepRasterizedBuffer();
 }
 
 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
 {
-  return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
+  return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
 }
 
 } // namespace Dali
@@ -287,12 +427,21 @@ namespace Test
 {
 namespace VectorAnimationRenderer
 {
+void DelayRendering(uint32_t delay)
+{
+  Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime     = delay;
+  Dali::Internal::Adaptor::gVectorAnimationRenderer->mTestFrameDrop = true;
+}
 
-void RequestTrigger()
+uint32_t GetDroppedFrames()
 {
-  Dali::Internal::Adaptor::VectorAnimationRenderer::mNeedTrigger = true;
+  return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
 }
 
-} // VectorAnimationRenderer
-} // Test
+void UseNativeImageTexture(bool useNativeImage)
+{
+  Dali::Internal::Adaptor::gVectorAnimationRenderer->mUseNativeImage = useNativeImage;
+}
 
+} // namespace VectorAnimationRenderer
+} // namespace Test