(Vector) Fix occasional tc failure
[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 558cdec..e6456ec
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
+#include <dali/devel-api/threading/mutex.h>
 #include <dali/public-api/object/base-object.h>
 #include <toolkit-application.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( const std::string& url )
-  : mUrl( url ),
+  VectorAnimationRenderer()
+  : mUrl(),
     mRenderer(),
-    mWidth( 0 ),
-    mHeight( 0 ),
-    mPreviousFrame( 0 )
+    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),
+    mEventThreadCallback(new EventThreadCallback(MakeCallback(this, &VectorAnimationRenderer::OnTriggered)))
   {
+    mCount++;
+
+    if(mCount == 2)
+    {
+      mFrameRate = 0.1f;
+    }
   }
 
-  void SetRenderer( Dali::Renderer renderer )
+  ~VectorAnimationRenderer()
   {
-    mRenderer = renderer;
+    mCount--;
+  }
 
-    if( mWidth != 0 && mHeight != 0 )
+  bool Load(const std::string& url)
+  {
+    Dali::Mutex::ScopedLock lock(mMutex);
+    mUrl = url;
+    if(mUrl == "invalid.json")
     {
-      Dali::TextureSet textureSet = mRenderer.GetTextures();
-      Dali::Texture texture = Dali::Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight );
-      textureSet.SetTexture( 0, texture );
-      mUploadCompletedSignal.Emit();
+      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)
+  {
+    mRenderer = renderer;
   }
 
-  void SetSize( uint32_t width, uint32_t height )
+  void SetSize(uint32_t width, uint32_t height)
   {
-    mWidth = width;
+    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( frameNumber == 1 && mPreviousFrame != 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;
+      mNeedDroppedFrames = true;
+    }
+    else if(mNeedDroppedFrames)
+    {
+      mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
+      mNeedTrigger       = true;
+      mNeedDroppedFrames = false;
+    }
+
+    if(mNeedTrigger)
+    {
+      mEventThreadCallback->Trigger();
+      mNeedTrigger = false;
+    }
+
+    if(frameNumber == 1 && mPreviousFrame != frameNumber)
     {
       mPreviousFrame = frameNumber;
       // For test corverage
@@ -82,18 +147,47 @@ public:
 
   uint32_t GetTotalFrameNumber() const
   {
-    return 5;
+    return mTotalFrameNumber;
   }
 
   float GetFrameRate() const
   {
-    return 60.0f;
+    return mFrameRate;
+  }
+
+  void GetDefaultSize(uint32_t& width, uint32_t& height) const
+  {
+    width  = mDefaultWidth;
+    height = mDefaultHeight;
+  }
+
+  bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
+  {
+    if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
+    {
+      startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
+    }
+    else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
+    {
+      startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
+      endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
+    }
+    else
+    {
+      return false;
+    }
+    return true;
   }
 
-  void GetDefaultSize( uint32_t& width, uint32_t& height ) const
+  void InvalidateBuffer()
   {
-    width = 100;
-    height = 100;
+    Dali::Mutex::ScopedLock lock(mMutex);
+    if(mResourceReady)
+    {
+      mNeedTrigger   = true;
+      mResourceReady = false;
+    }
   }
 
   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
@@ -101,44 +195,80 @@ public:
     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;
 
-  std::string mUrl;
+  std::string    mUrl;
   Dali::Renderer mRenderer;
-  uint32_t mWidth;
-  uint32_t mHeight;
-  uint32_t mPreviousFrame;
+  Dali::Mutex    mMutex;
+  uint32_t       mWidth;
+  uint32_t       mHeight;
+  uint32_t       mDefaultWidth;
+  uint32_t       mDefaultHeight;
+  uint32_t       mTotalFrameNumber;
+  uint32_t       mPreviousFrame;
+  uint32_t       mDelayTime;
+  uint32_t       mDroppedFrames;
+  float          mFrameRate;
+  bool           mTestFrameDrop;
+  bool           mNeedDroppedFrames;
+  bool           mLoadFailed{false};
+  bool           mResourceReady{false};
+  bool           mNeedTrigger{true};
+
   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
+  std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
 };
 
-inline VectorAnimationRenderer& GetImplementation( Dali::VectorAnimationRenderer& renderer )
+uint32_t VectorAnimationRenderer::mCount = 0;
+
+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  *******************************/
 /********************************************************************************/
 
-VectorAnimationRenderer VectorAnimationRenderer::New( const std::string& url )
+VectorAnimationRenderer VectorAnimationRenderer::New()
 {
-  Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer( url );
+  Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer();
 
-  return VectorAnimationRenderer( animationRenderer );
+  Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
+
+  return VectorAnimationRenderer(animationRenderer);
 }
 
 VectorAnimationRenderer::VectorAnimationRenderer()
@@ -149,56 +279,96 @@ 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;
 }
 
-void VectorAnimationRenderer::SetRenderer( Renderer renderer )
+void VectorAnimationRenderer::Finalize()
 {
-  Internal::Adaptor::GetImplementation( *this ).SetRenderer( renderer );
 }
 
-void VectorAnimationRenderer::SetSize( uint32_t width, uint32_t height )
+bool VectorAnimationRenderer::Load(const std::string& url)
 {
-  Internal::Adaptor::GetImplementation( *this ).SetSize( width, height );
+  return Internal::Adaptor::GetImplementation(*this).Load(url);
 }
 
-bool VectorAnimationRenderer::Render( uint32_t frameNumber )
+void VectorAnimationRenderer::SetRenderer(Renderer renderer)
 {
-  return Internal::Adaptor::GetImplementation( *this ).Render( frameNumber );
+  Internal::Adaptor::GetImplementation(*this).SetRenderer(renderer);
+}
+
+void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
+{
+  Internal::Adaptor::GetImplementation(*this).SetSize(width, height);
+}
+
+bool VectorAnimationRenderer::Render(uint32_t frameNumber)
+{
+  return Internal::Adaptor::GetImplementation(*this).Render(frameNumber);
 }
 
 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
 {
-  return Internal::Adaptor::GetImplementation( *this ).GetTotalFrameNumber();
+  return Internal::Adaptor::GetImplementation(*this).GetTotalFrameNumber();
 }
 
 float VectorAnimationRenderer::GetFrameRate() const
 {
-  return Internal::Adaptor::GetImplementation( *this ).GetFrameRate();
+  return Internal::Adaptor::GetImplementation(*this).GetFrameRate();
+}
+
+void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
+{
+  Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height);
+}
+
+void VectorAnimationRenderer::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::InvalidateBuffer()
+{
+  return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
 }
 
 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
 {
-  return Internal::Adaptor::GetImplementation( *this ).UploadCompletedSignal();
+  return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
 }
 
-} // namespace Dali;
+} // namespace Dali
+
+namespace Test
+{
+namespace VectorAnimationRenderer
+{
+void DelayRendering(uint32_t delay)
+{
+  Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime     = delay;
+  Dali::Internal::Adaptor::gVectorAnimationRenderer->mTestFrameDrop = true;
+}
+
+uint32_t GetDroppedFrames()
+{
+  return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
+}
 
+} // namespace VectorAnimationRenderer
+} // namespace Test