(Vector) Support asynchronous file loading
[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/public-api/object/base-object.h>
21 #include <toolkit-application.h>
22 #include <toolkit-event-thread-callback.h>
23 #include <toolkit-vector-animation-renderer.h>
24 #include <chrono>
25 #include <memory>
26 #include <thread>
27
28 namespace Dali
29 {
30 namespace Internal
31 {
32 namespace Adaptor
33 {
34 namespace
35 {
36 Dali::Internal::Adaptor::VectorAnimationRenderer* gVectorAnimationRenderer = nullptr;
37 }
38
39 class VectorAnimationRenderer : public Dali::BaseObject
40 {
41 public:
42   VectorAnimationRenderer()
43   : mUrl(),
44     mRenderer(),
45     mWidth(0),
46     mHeight(0),
47     mDefaultWidth(0),
48     mDefaultHeight(0),
49     mTotalFrameNumber(VECTOR_ANIMATION_TOTAL_FRAME_NUMBER),
50     mPreviousFrame(0),
51     mDelayTime(0),
52     mDroppedFrames(0),
53     mFrameRate(60.0f),
54     mTestFrameDrop(false),
55     mNeedDroppedFrames(false),
56     mEventThreadCallback(new EventThreadCallback(MakeCallback(this, &VectorAnimationRenderer::OnTriggered)))
57   {
58     mCount++;
59
60     if(mCount == 2)
61     {
62       mFrameRate = 0.1f;
63     }
64   }
65
66   ~VectorAnimationRenderer()
67   {
68     mCount--;
69   }
70
71   bool Load(const std::string& url)
72   {
73     mUrl = url;
74     if(mUrl == "invalid.json")
75     {
76       mLoadFailed = true;
77       return false;
78     }
79     else if(mUrl == "framedrop.json")
80     {
81       // Change total frame number for test
82       mTotalFrameNumber = 200;
83       mTestFrameDrop    = true;
84     }
85
86     mDefaultWidth  = 100;
87     mDefaultHeight = 100;
88
89     return true;
90   }
91
92   void SetRenderer(Dali::Renderer renderer)
93   {
94     mRenderer = renderer;
95   }
96
97   void SetSize(uint32_t width, uint32_t height)
98   {
99     mWidth  = width;
100     mHeight = height;
101
102     if(!mLoadFailed)
103     {
104       mNeedTrigger   = true;
105       mResourceReady = false;
106     }
107   }
108
109   bool Render(uint32_t frameNumber)
110   {
111     if(mWidth == 0 || mHeight == 0)
112     {
113       return false;
114     }
115
116     if(mTestFrameDrop)
117     {
118       std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int32_t>(mDelayTime)));
119       mTestFrameDrop     = false;
120       mNeedDroppedFrames = true;
121     }
122     else if(mNeedDroppedFrames)
123     {
124       mDroppedFrames     = (frameNumber > mPreviousFrame) ? frameNumber - mPreviousFrame - 1 : frameNumber + (mTotalFrameNumber - mPreviousFrame) - 1;
125       mNeedTrigger       = true;
126       mNeedDroppedFrames = false;
127     }
128
129     if(mNeedTrigger)
130     {
131       mEventThreadCallback->Trigger();
132       mNeedTrigger = false;
133     }
134
135     if(frameNumber == 1 && mPreviousFrame != frameNumber)
136     {
137       mPreviousFrame = frameNumber;
138       // For test corverage
139       return false;
140     }
141     mPreviousFrame = frameNumber;
142     return true;
143   }
144
145   uint32_t GetTotalFrameNumber() const
146   {
147     return mTotalFrameNumber;
148   }
149
150   float GetFrameRate() const
151   {
152     return mFrameRate;
153   }
154
155   void GetDefaultSize(uint32_t& width, uint32_t& height) const
156   {
157     width  = mDefaultWidth;
158     height = mDefaultHeight;
159   }
160
161   bool GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
162   {
163     if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_1) == 0)
164     {
165       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_1;
166       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_1;
167     }
168     else if(marker.compare(VECTOR_ANIMATION_MARKER_NAME_2) == 0)
169     {
170       startFrame = VECTOR_ANIMATION_MARKER_START_FRAME_2;
171       endFrame   = VECTOR_ANIMATION_MARKER_END_FRAME_2;
172     }
173     else
174     {
175       return false;
176     }
177     return true;
178   }
179
180   void InvalidateBuffer()
181   {
182     mNeedTrigger   = true;
183     mResourceReady = false;
184   }
185
186   Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
187   {
188     return mUploadCompletedSignal;
189   }
190
191   void OnTriggered()
192   {
193     if(!mResourceReady)
194     {
195       mResourceReady = true;
196
197       Dali::TextureSet textureSet = mRenderer.GetTextures();
198       Dali::Texture    texture    = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, mWidth, mHeight);
199       textureSet.SetTexture(0, texture);
200
201       Devel::PixelBuffer pixelBuffer = Devel::PixelBuffer::New(mWidth, mHeight, Pixel::RGBA8888);
202       Dali::PixelData    pixelData   = Devel::PixelBuffer::Convert(pixelBuffer);
203       texture.Upload(pixelData);
204
205       mUploadCompletedSignal.Emit();
206     }
207   }
208
209 public:
210   static uint32_t mCount;
211
212   std::string    mUrl;
213   Dali::Renderer mRenderer;
214   uint32_t       mWidth;
215   uint32_t       mHeight;
216   uint32_t       mDefaultWidth;
217   uint32_t       mDefaultHeight;
218   uint32_t       mTotalFrameNumber;
219   uint32_t       mPreviousFrame;
220   uint32_t       mDelayTime;
221   uint32_t       mDroppedFrames;
222   float          mFrameRate;
223   bool           mTestFrameDrop;
224   bool           mNeedDroppedFrames;
225   bool           mLoadFailed{false};
226   bool           mResourceReady{false};
227   bool           mNeedTrigger{true};
228
229   Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal;
230   std::unique_ptr<EventThreadCallback>                     mEventThreadCallback;
231 };
232
233 uint32_t VectorAnimationRenderer::mCount = 0;
234
235 inline VectorAnimationRenderer& GetImplementation(Dali::VectorAnimationRenderer& renderer)
236 {
237   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
238   BaseObject& handle = renderer.GetBaseObject();
239   return static_cast<Internal::Adaptor::VectorAnimationRenderer&>(handle);
240 }
241
242 inline const VectorAnimationRenderer& GetImplementation(const Dali::VectorAnimationRenderer& renderer)
243 {
244   DALI_ASSERT_ALWAYS(renderer && "VectorAnimationRenderer handle is empty.");
245   const BaseObject& handle = renderer.GetBaseObject();
246   return static_cast<const Internal::Adaptor::VectorAnimationRenderer&>(handle);
247 }
248
249 } // namespace Adaptor
250
251 } // namespace Internal
252
253 /********************************************************************************/
254 /*********************************  PUBLIC CLASS  *******************************/
255 /********************************************************************************/
256
257 VectorAnimationRenderer VectorAnimationRenderer::New()
258 {
259   Internal::Adaptor::VectorAnimationRenderer* animationRenderer = new Internal::Adaptor::VectorAnimationRenderer();
260
261   Internal::Adaptor::gVectorAnimationRenderer = animationRenderer;
262
263   return VectorAnimationRenderer(animationRenderer);
264 }
265
266 VectorAnimationRenderer::VectorAnimationRenderer()
267 {
268 }
269
270 VectorAnimationRenderer::~VectorAnimationRenderer()
271 {
272 }
273
274 VectorAnimationRenderer::VectorAnimationRenderer(Internal::Adaptor::VectorAnimationRenderer* internal)
275 : BaseHandle(internal)
276 {
277 }
278
279 VectorAnimationRenderer::VectorAnimationRenderer(const VectorAnimationRenderer& handle)
280 : BaseHandle(handle)
281 {
282 }
283
284 VectorAnimationRenderer& VectorAnimationRenderer::operator=(const VectorAnimationRenderer& rhs)
285 {
286   BaseHandle::operator=(rhs);
287   return *this;
288 }
289
290 void VectorAnimationRenderer::Finalize()
291 {
292 }
293
294 bool VectorAnimationRenderer::Load(const std::string& url)
295 {
296   return Internal::Adaptor::GetImplementation(*this).Load(url);
297 }
298
299 void VectorAnimationRenderer::SetRenderer(Renderer renderer)
300 {
301   Internal::Adaptor::GetImplementation(*this).SetRenderer(renderer);
302 }
303
304 void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
305 {
306   Internal::Adaptor::GetImplementation(*this).SetSize(width, height);
307 }
308
309 bool VectorAnimationRenderer::Render(uint32_t frameNumber)
310 {
311   return Internal::Adaptor::GetImplementation(*this).Render(frameNumber);
312 }
313
314 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
315 {
316   return Internal::Adaptor::GetImplementation(*this).GetTotalFrameNumber();
317 }
318
319 float VectorAnimationRenderer::GetFrameRate() const
320 {
321   return Internal::Adaptor::GetImplementation(*this).GetFrameRate();
322 }
323
324 void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
325 {
326   Internal::Adaptor::GetImplementation(*this).GetDefaultSize(width, height);
327 }
328
329 void VectorAnimationRenderer::GetLayerInfo(Property::Map& map) const
330 {
331 }
332
333 bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
334 {
335   return Internal::Adaptor::GetImplementation(*this).GetMarkerInfo(marker, startFrame, endFrame);
336 }
337
338 void VectorAnimationRenderer::InvalidateBuffer()
339 {
340   return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer();
341 }
342
343 VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
344 {
345   return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal();
346 }
347
348 } // namespace Dali
349
350 namespace Test
351 {
352 namespace VectorAnimationRenderer
353 {
354 void DelayRendering(uint32_t delay)
355 {
356   Dali::Internal::Adaptor::gVectorAnimationRenderer->mDelayTime = delay;
357 }
358
359 uint32_t GetDroppedFrames()
360 {
361   return Dali::Internal::Adaptor::gVectorAnimationRenderer->mDroppedFrames;
362 }
363
364 } // namespace VectorAnimationRenderer
365 } // namespace Test