(AnimatedVector) Sync AnimatedVectorRenderer for UTC
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / toolkit-vector-animation-renderer.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
19 #include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
20 #include <dali/devel-api/threading/mutex.h>
21 #include <dali/public-api/object/base-object.h>
22 #include <toolkit-application.h>
23 #include <toolkit-event-thread-callback.h>
24 #include <toolkit-vector-animation-renderer.h>
25 #include <chrono>
26 #include <memory>
27 #include <thread>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 namespace Adaptor
34 {
35 namespace
36 {
37 Dali::Internal::Adaptor::VectorAnimationRenderer* gVectorAnimationRenderer = nullptr;
38 }
39
40 class VectorAnimationRenderer : public Dali::BaseObject
41 {
42 public:
43   VectorAnimationRenderer()
44   : mUrl(),
45     mRenderer(),
46     mWidth(0),
47     mHeight(0),
48     mDefaultWidth(0),
49     mDefaultHeight(0),
50     mTotalFrameNumber(VECTOR_ANIMATION_TOTAL_FRAME_NUMBER),
51     mPreviousFrame(0),
52     mDelayTime(0),
53     mDroppedFrames(0),
54     mFrameRate(60.0f),
55     mTestFrameDrop(false),
56     mNeedDroppedFrames(false),
57     mEventThreadCallback(new EventThreadCallback(MakeCallback(this, &VectorAnimationRenderer::OnTriggered)))
58   {
59     mCount++;
60
61     if(mCount == 2)
62     {
63       mFrameRate = 0.1f;
64     }
65   }
66
67   ~VectorAnimationRenderer()
68   {
69     mCount--;
70   }
71
72   bool Load(const std::string& url)
73   {
74     Dali::Mutex::ScopedLock lock(mMutex);
75     mUrl = url;
76     if(mUrl == "invalid.json")
77     {
78       mLoadFailed = true;
79       return false;
80     }
81     else if(mUrl == "framedrop.json")
82     {
83       // Change total frame number for test
84       mTotalFrameNumber = 200;
85     }
86
87     mDefaultWidth  = 100;
88     mDefaultHeight = 100;
89
90     return true;
91   }
92
93   bool Load(const Dali::Vector<uint8_t>& data)
94   {
95     Dali::Mutex::ScopedLock lock(mMutex);
96
97     mDefaultWidth  = 100;
98     mDefaultHeight = 100;
99
100     return true;
101   }
102
103   void SetRenderer(Dali::Renderer renderer)
104   {
105     mRenderer = renderer;
106   }
107
108   void SetSize(uint32_t width, uint32_t height)
109   {
110     Dali::Mutex::ScopedLock lock(mMutex);
111     mWidth  = width;
112     mHeight = height;
113
114     if(!mLoadFailed)
115     {
116       mNeedTrigger   = true;
117       mResourceReady = false;
118     }
119   }
120
121   bool Render(uint32_t frameNumber)
122   {
123     Dali::Mutex::ScopedLock lock(mMutex);
124     if(mWidth == 0 || mHeight == 0)
125     {
126       return false;
127     }
128
129     if(mTestFrameDrop)
130     {
131       std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int32_t>(mDelayTime)));
132       mTestFrameDrop     = false;
133       mNeedDroppedFrames = true;
134     }
135     else if(mNeedDroppedFrames)
136     {
137       mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
138       mNeedTrigger       = true;
139       mNeedDroppedFrames = false;
140     }
141
142     if(mDynamicPropertyCallback)
143     {
144       CallbackBase::ExecuteReturn<Property::Value>(*mDynamicPropertyCallback, 0, 0, frameNumber);
145     }
146
147     if(mNeedTrigger)
148     {
149       mEventThreadCallback->Trigger();
150       mNeedTrigger = false;
151     }
152
153     if(frameNumber == 1 && mPreviousFrame != frameNumber)
154     {
155       mPreviousFrame = frameNumber;
156       // For test corverage
157       return false;
158     }
159     mPreviousFrame = frameNumber;
160     return true;
161   }
162
163   uint32_t GetTotalFrameNumber() const
164   {
165     return mTotalFrameNumber;
166   }
167
168   float GetFrameRate() const
169   {
170     return mFrameRate;
171   }
172
173   void GetDefaultSize(uint32_t& width, uint32_t& height) const
174   {
175     width  = mDefaultWidth;
176     height = mDefaultHeight;
177   }
178
179   bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
180   {
181     if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
182     {
183       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
184       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
185     }
186     else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
187     {
188       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
189       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
190     }
191     else
192     {
193       return false;
194     }
195     return true;
196   }
197
198   void InvalidateBuffer()
199   {
200     Dali::Mutex::ScopedLock lock(mMutex);
201     if(mResourceReady)
202     {
203       mNeedTrigger   = true;
204       mResourceReady = false;
205     }
206   }
207
208   void AddPropertyValueCallback(const std::string& keyPath, Dali::VectorAnimationRenderer::VectorProperty property, CallbackBase* callback, int32_t id)
209   {
210     mDynamicPropertyCallback = std::unique_ptr<CallbackBase>(callback);
211   }
212
213   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
214   {
215     return mUploadCompletedSignal;
216   }
217
218   void OnTriggered()
219   {
220     if(!mResourceReady)
221     {
222       mResourceReady = true;
223
224       Dali::TextureSet textureSet = mRenderer.GetTextures();
225       Dali::Texture    texture    = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight);
226       textureSet.SetTexture(0, texture);
227
228       Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Pixel::RGBA8888);
229       Dali::PixelData    pixelData   = Devel::PixelBuffer::Convert(pixelBuffer);
230       texture.Upload(pixelData);
231
232       mUploadCompletedSignal.Emit();
233     }
234   }
235
236 public:
237   static uint32_t mCount;
238
239   std::string                   mUrl;
240   Dali::Renderer                mRenderer;
241   Dali::Mutex                   mMutex;
242   std::unique_ptr<CallbackBase> mDynamicPropertyCallback{nullptr};
243
244   uint32_t mWidth;
245   uint32_t mHeight;
246   uint32_t mDefaultWidth;
247   uint32_t mDefaultHeight;
248   uint32_t mTotalFrameNumber;
249   uint32_t mPreviousFrame;
250   uint32_t mDelayTime;
251   uint32_t mDroppedFrames;
252   float    mFrameRate;
253   bool     mTestFrameDrop;
254   bool     mNeedDroppedFrames;
255   bool     mLoadFailed{false};
256   bool     mResourceReady{false};
257   bool     mNeedTrigger{true};
258
259   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
260   std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
261 };
262
263 uint32_t VectorAnimationRenderer::mCount = 0;
264
265 inline VectorAnimationRenderer& GetImplementation(Dali::VectorAnimationRenderer& renderer)
266 {
267   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
268   BaseObject& handle = renderer.GetBaseObject();
269   return static_cast<Internal::Adaptor::VectorAnimationRenderer&>(handle);
270 }
271
272 inline const VectorAnimationRenderer& GetImplementation(const Dali::VectorAnimationRenderer& renderer)
273 {
274   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
275   const BaseObject& handle = renderer.GetBaseObject();
276   return static_cast<const Internal::Adaptor::VectorAnimationRenderer&>(handle);
277 }
278
279 } // namespace Adaptor
280
281 } // namespace Internal
282
283 /********************************************************************************/
284 /*********************************  PUBLIC CLASS  *******************************/
285 /********************************************************************************/
286
287 VectorAnimationRenderer VectorAnimationRenderer::New()
288 {
289   Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer();
290
291   Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
292
293   return VectorAnimationRenderer(animationRenderer);
294 }
295
296 VectorAnimationRenderer::VectorAnimationRenderer()
297 {
298 }
299
300 VectorAnimationRenderer::~VectorAnimationRenderer()
301 {
302 }
303
304 VectorAnimationRenderer::VectorAnimationRenderer(Internal::Adaptor::VectorAnimationRenderer* internal)
305 : BaseHandle(internal)
306 {
307 }
308
309 VectorAnimationRenderer::VectorAnimationRenderer(const VectorAnimationRenderer& handle)
310 : BaseHandle(handle)
311 {
312 }
313
314 VectorAnimationRenderer& VectorAnimationRenderer::operator=(const VectorAnimationRenderer& rhs)
315 {
316   BaseHandle::operator=(rhs);
317   return *this;
318 }
319
320 void VectorAnimationRenderer::Finalize()
321 {
322 }
323
324 bool VectorAnimationRenderer::Load(const std::string& url)
325 {
326   return Internal::Adaptor::GetImplementation(*this).Load(url);
327 }
328
329 bool VectorAnimationRenderer::Load(const Dali::Vector<uint8_t>& data)
330 {
331   return Internal::Adaptor::GetImplementation(*this).Load(data);
332 }
333
334 void VectorAnimationRenderer::SetRenderer(Renderer renderer)
335 {
336   Internal::Adaptor::GetImplementation(*this).SetRenderer(renderer);
337 }
338
339 void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
340 {
341   Internal::Adaptor::GetImplementation(*this).SetSize(width, height);
342 }
343
344 bool VectorAnimationRenderer::Render(uint32_t frameNumber)
345 {
346   return Internal::Adaptor::GetImplementation(*this).Render(frameNumber);
347 }
348
349 void VectorAnimationRenderer::RenderStopped()
350 {
351 }
352
353 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
354 {
355   return Internal::Adaptor::GetImplementation(*this).GetTotalFrameNumber();
356 }
357
358 float VectorAnimationRenderer::GetFrameRate() const
359 {
360   return Internal::Adaptor::GetImplementation(*this).GetFrameRate();
361 }
362
363 void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
364 {
365   Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height);
366 }
367
368 void VectorAnimationRenderer::GetLayerInfo(Property::Map& map) const
369 {
370 }
371
372 bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
373 {
374   return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
375 }
376
377 void VectorAnimationRenderer::InvalidateBuffer()
378 {
379   return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
380 }
381
382 void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPath, VectorProperty property, CallbackBase* callback, int32_t id)
383 {
384   Internal::Adaptor::GetImplementation(*this).AddPropertyValueCallback(keyPath, property, callback, id);
385 }
386
387 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
388 {
389   return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
390 }
391
392 } // namespace Dali
393
394 namespace Test
395 {
396 namespace VectorAnimationRenderer
397 {
398 void DelayRendering(uint32_t delay)
399 {
400   Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime     = delay;
401   Dali::Internal::Adaptor::gVectorAnimationRenderer->mTestFrameDrop = true;
402 }
403
404 uint32_t GetDroppedFrames()
405 {
406   return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
407 }
408
409 } // namespace VectorAnimationRenderer
410 } // namespace Test