DALi Version 2.1.32
[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   void SetRenderer(Dali::Renderer renderer)
94   {
95     mRenderer = renderer;
96   }
97
98   void SetSize(uint32_t width, uint32_t height)
99   {
100     Dali::Mutex::ScopedLock lock(mMutex);
101     mWidth  = width;
102     mHeight = height;
103
104     if(!mLoadFailed)
105     {
106       mNeedTrigger   = true;
107       mResourceReady = false;
108     }
109   }
110
111   bool Render(uint32_t frameNumber)
112   {
113     Dali::Mutex::ScopedLock lock(mMutex);
114     if(mWidth == 0 || mHeight == 0)
115     {
116       return false;
117     }
118
119     if(mTestFrameDrop)
120     {
121       std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int32_t>(mDelayTime)));
122       mTestFrameDrop     = false;
123       mNeedDroppedFrames = true;
124     }
125     else if(mNeedDroppedFrames)
126     {
127       mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
128       mNeedTrigger       = true;
129       mNeedDroppedFrames = false;
130     }
131
132     if(mNeedTrigger)
133     {
134       mEventThreadCallback->Trigger();
135       mNeedTrigger = false;
136     }
137
138     if(frameNumber == 1 && mPreviousFrame != frameNumber)
139     {
140       mPreviousFrame = frameNumber;
141       // For test corverage
142       return false;
143     }
144     mPreviousFrame = frameNumber;
145     return true;
146   }
147
148   uint32_t GetTotalFrameNumber() const
149   {
150     return mTotalFrameNumber;
151   }
152
153   float GetFrameRate() const
154   {
155     return mFrameRate;
156   }
157
158   void GetDefaultSize(uint32_t& width, uint32_t& height) const
159   {
160     width  = mDefaultWidth;
161     height = mDefaultHeight;
162   }
163
164   bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
165   {
166     if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
167     {
168       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
169       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
170     }
171     else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
172     {
173       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
174       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
175     }
176     else
177     {
178       return false;
179     }
180     return true;
181   }
182
183   void InvalidateBuffer()
184   {
185     Dali::Mutex::ScopedLock lock(mMutex);
186     if(mResourceReady)
187     {
188       mNeedTrigger   = true;
189       mResourceReady = false;
190     }
191   }
192
193   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
194   {
195     return mUploadCompletedSignal;
196   }
197
198   void OnTriggered()
199   {
200     if(!mResourceReady)
201     {
202       mResourceReady = true;
203
204       Dali::TextureSet textureSet = mRenderer.GetTextures();
205       Dali::Texture    texture    = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight);
206       textureSet.SetTexture(0, texture);
207
208       Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Pixel::RGBA8888);
209       Dali::PixelData    pixelData   = Devel::PixelBuffer::Convert(pixelBuffer);
210       texture.Upload(pixelData);
211
212       mUploadCompletedSignal.Emit();
213     }
214   }
215
216 public:
217   static uint32_t mCount;
218
219   std::string    mUrl;
220   Dali::Renderer mRenderer;
221   Dali::Mutex    mMutex;
222   uint32_t       mWidth;
223   uint32_t       mHeight;
224   uint32_t       mDefaultWidth;
225   uint32_t       mDefaultHeight;
226   uint32_t       mTotalFrameNumber;
227   uint32_t       mPreviousFrame;
228   uint32_t       mDelayTime;
229   uint32_t       mDroppedFrames;
230   float          mFrameRate;
231   bool           mTestFrameDrop;
232   bool           mNeedDroppedFrames;
233   bool           mLoadFailed{false};
234   bool           mResourceReady{false};
235   bool           mNeedTrigger{true};
236
237   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
238   std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
239 };
240
241 uint32_t VectorAnimationRenderer::mCount = 0;
242
243 inline VectorAnimationRenderer& GetImplementation(Dali::VectorAnimationRenderer& renderer)
244 {
245   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
246   BaseObject& handle = renderer.GetBaseObject();
247   return static_cast<Internal::Adaptor::VectorAnimationRenderer&>(handle);
248 }
249
250 inline const VectorAnimationRenderer& GetImplementation(const Dali::VectorAnimationRenderer& renderer)
251 {
252   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
253   const BaseObject& handle = renderer.GetBaseObject();
254   return static_cast<const Internal::Adaptor::VectorAnimationRenderer&>(handle);
255 }
256
257 } // namespace Adaptor
258
259 } // namespace Internal
260
261 /********************************************************************************/
262 /*********************************  PUBLIC CLASS  *******************************/
263 /********************************************************************************/
264
265 VectorAnimationRenderer VectorAnimationRenderer::New()
266 {
267   Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer();
268
269   Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
270
271   return VectorAnimationRenderer(animationRenderer);
272 }
273
274 VectorAnimationRenderer::VectorAnimationRenderer()
275 {
276 }
277
278 VectorAnimationRenderer::~VectorAnimationRenderer()
279 {
280 }
281
282 VectorAnimationRenderer::VectorAnimationRenderer(Internal::Adaptor::VectorAnimationRenderer* internal)
283 : BaseHandle(internal)
284 {
285 }
286
287 VectorAnimationRenderer::VectorAnimationRenderer(const VectorAnimationRenderer& handle)
288 : BaseHandle(handle)
289 {
290 }
291
292 VectorAnimationRenderer& VectorAnimationRenderer::operator=(const VectorAnimationRenderer& rhs)
293 {
294   BaseHandle::operator=(rhs);
295   return *this;
296 }
297
298 void VectorAnimationRenderer::Finalize()
299 {
300 }
301
302 bool VectorAnimationRenderer::Load(const std::string& url)
303 {
304   return Internal::Adaptor::GetImplementation(*this).Load(url);
305 }
306
307 void VectorAnimationRenderer::SetRenderer(Renderer renderer)
308 {
309   Internal::Adaptor::GetImplementation(*this).SetRenderer(renderer);
310 }
311
312 void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
313 {
314   Internal::Adaptor::GetImplementation(*this).SetSize(width, height);
315 }
316
317 bool VectorAnimationRenderer::Render(uint32_t frameNumber)
318 {
319   return Internal::Adaptor::GetImplementation(*this).Render(frameNumber);
320 }
321
322 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
323 {
324   return Internal::Adaptor::GetImplementation(*this).GetTotalFrameNumber();
325 }
326
327 float VectorAnimationRenderer::GetFrameRate() const
328 {
329   return Internal::Adaptor::GetImplementation(*this).GetFrameRate();
330 }
331
332 void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
333 {
334   Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height);
335 }
336
337 void VectorAnimationRenderer::GetLayerInfo(Property::Map& map) const
338 {
339 }
340
341 bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
342 {
343   return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
344 }
345
346 void VectorAnimationRenderer::InvalidateBuffer()
347 {
348   return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
349 }
350
351 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
352 {
353   return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
354 }
355
356 } // namespace Dali
357
358 namespace Test
359 {
360 namespace VectorAnimationRenderer
361 {
362 void DelayRendering(uint32_t delay)
363 {
364   Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime     = delay;
365   Dali::Internal::Adaptor::gVectorAnimationRenderer->mTestFrameDrop = true;
366 }
367
368 uint32_t GetDroppedFrames()
369 {
370   return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
371 }
372
373 } // namespace VectorAnimationRenderer
374 } // namespace Test