(Rive) Make rasterize callback as unique_ptr
[platform/core/uifw/dali-extension.git] / dali-extension / internal / rive-animation-view / rive-animation-view-impl.cpp
1 /*
2  * Copyright (c) 2023 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 // CLASS HEADER
19 #include "rive-animation-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/window-devel.h>
23 #include <dali/devel-api/common/stage.h>
24 #include <dali/devel-api/rendering/renderer-devel.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/object/type-registry-helper.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali-toolkit/devel-api/controls/control-devel.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-extension/devel-api/rive-animation-view/rive-animation-view.h>
32
33 namespace Dali
34 {
35 namespace Extension
36 {
37 namespace Internal
38 {
39 namespace
40 {
41
42 Geometry CreateQuadGeometry()
43 {
44   const float halfWidth  = 0.5f;
45   const float halfHeight = 0.5f;
46   struct QuadVertex
47   {
48     Vector2 position;
49   };
50   QuadVertex quadVertexData[4] =
51     {
52       {Vector2(-halfWidth, -halfHeight)},
53       {Vector2(-halfWidth, halfHeight)},
54       {Vector2(halfWidth, -halfHeight)},
55       {Vector2(halfWidth, halfHeight)}};
56
57   Property::Map quadVertexFormat;
58   quadVertexFormat["aPosition"] = Property::VECTOR2;
59   VertexBuffer quadVertices     = VertexBuffer::New(quadVertexFormat);
60   quadVertices.SetData(quadVertexData, 4);
61
62   // Create the geometry object
63   Geometry geometry = Geometry::New();
64   geometry.AddVertexBuffer(quadVertices);
65   geometry.SetType(Geometry::TRIANGLE_STRIP);
66
67   return geometry;
68 }
69
70 BaseHandle Create()
71 {
72   return Extension::RiveAnimationView::New();
73 }
74
75 // Setup properties, signals and actions using the type-registry.
76 DALI_TYPE_REGISTRATION_BEGIN(Extension::RiveAnimationView, Toolkit::Control, Create);
77 DALI_PROPERTY_REGISTRATION(Extension, RiveAnimationView, "url", STRING, URL)
78 DALI_PROPERTY_REGISTRATION(Extension, RiveAnimationView, "playState", INTEGER, PLAY_STATE)
79 DALI_TYPE_REGISTRATION_END()
80
81 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
82   attribute mediump vec2 aPosition;\n
83   uniform highp   mat4 uMvpMatrix;\n
84   uniform highp   vec3 uSize;\n
85   varying mediump vec2 vTexCoord;\n
86   \n
87   void main()\n
88   {\n
89     gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n
90     vTexCoord = aPosition + vec2(0.5);\n
91   }\n
92 );
93
94 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
95   varying mediump vec2 vTexCoord;\n
96   uniform sampler2D sTexture;\n
97   uniform lowp vec4 uColor;\n
98   \n
99   void main()\n
100   {\n
101       gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
102   }\n
103 );
104
105 #if defined(DEBUG_ENABLED)
106 Debug::Filter* gRiveAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RIVE_ANIMATION");
107 #endif
108
109 } // unnamed namespace
110
111 RiveAnimationView::RiveAnimationView()
112 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
113   mRiveAnimationTask(new RiveAnimationTask())
114 {
115 }
116
117 RiveAnimationView::~RiveAnimationView()
118 {
119   if(!mCoreShutdown)
120   {
121     auto& riveAnimationManager = RiveAnimationManager::GetInstance();
122     riveAnimationManager.RemoveObserver(*this);
123
124     if(mEventCallback)
125     {
126       riveAnimationManager.UnregisterEventCallback(mEventCallback);
127       mEventCallback = nullptr;
128     }
129
130     // Finalize animation task and disconnect the signal in the main thread
131     mRiveAnimationTask->UploadCompletedSignal().Disconnect(this, &RiveAnimationView::OnUploadCompleted);
132     mRiveAnimationTask->Finalize();
133   }
134 }
135
136 Extension::RiveAnimationView RiveAnimationView::New()
137 {
138   RiveAnimationView* impl = new RiveAnimationView();
139
140   Dali::Extension::RiveAnimationView handle = Dali::Extension::RiveAnimationView(*impl);
141
142   // Second-phase init of the implementation
143   // This can only be done after the CustomActor connection has been made...
144   impl->Initialize();
145
146   return handle;
147 }
148
149 void RiveAnimationView::OnSceneConnection(int depth)
150 {
151   Control::OnSceneConnection(depth);
152
153   if(mLoadFailed)
154   {
155     //TODO: do something
156   }
157   else
158   {
159     mRiveAnimationTask->SetRenderer(mRenderer);
160     Actor actor = Self();
161
162     // Add property notification for scaling & size
163     mScaleNotification = actor.AddPropertyNotification(Actor::Property::WORLD_SCALE, StepCondition(0.1f, 1.0f));
164     mScaleNotification.NotifySignal().Connect(this, &RiveAnimationView::OnScaleNotification);
165
166     mSizeNotification = actor.AddPropertyNotification(Actor::Property::SIZE, StepCondition(3.0f));
167     mSizeNotification.NotifySignal().Connect(this, &RiveAnimationView::OnSizeNotification);
168
169     DevelActor::VisibilityChangedSignal(actor).Connect(this, &RiveAnimationView::OnControlVisibilityChanged);
170
171     Window window = DevelWindow::Get(actor);
172     if(window)
173     {
174       DevelWindow::VisibilityChangedSignal(window).Connect(this, &RiveAnimationView::OnWindowVisibilityChanged);
175     }
176   }
177
178   DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnSceneConnection [%p]\n", this);
179
180 }
181
182 void RiveAnimationView::OnSceneDisconnection()
183 {
184   Control::OnSceneDisconnection();
185
186   StopAnimation();
187   SendAnimationData();
188
189   Actor actor = Self();
190
191   if(mRenderer)
192   {
193     actor.RemoveRenderer(mRenderer);
194     mRendererAdded = false;
195   }
196
197   // Remove property notification
198   actor.RemovePropertyNotification(mScaleNotification);
199   actor.RemovePropertyNotification(mSizeNotification);
200
201   DevelActor::VisibilityChangedSignal(actor).Disconnect(this, &RiveAnimationView::OnControlVisibilityChanged);
202
203   Window window = DevelWindow::Get(actor);
204   if(window)
205   {
206     DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &RiveAnimationView::OnWindowVisibilityChanged);
207   }
208
209   // Reset the visual size to zero so that when adding the actor back to stage the rasterization is forced
210   mSize  = Vector2::ZERO;
211   mScale = Vector2::ONE;
212
213   DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnSceneDisconnection [%p]\n", this);
214 }
215
216 void RiveAnimationView::OnInitialize()
217 {
218   // Accessibility
219   Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
220   Self().SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
221 }
222
223 Vector3 RiveAnimationView::GetNaturalSize()
224 {
225   Vector3 naturalSize;
226
227   if(mSize != Vector2::ZERO)
228   {
229     naturalSize = mSize;
230   }
231   else
232   {
233     uint32_t width, height;
234     mRiveAnimationTask->GetDefaultSize(width, height);
235     naturalSize.x = width;
236     naturalSize.y = height;
237   }
238
239   DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::GetNaturalSize: w = %f, h = %f [%p]\n", naturalSize.width, naturalSize.height, this);
240
241   return naturalSize;
242 }
243
244 void RiveAnimationView::OnRelayout(const Vector2& size, RelayoutContainer& container)
245 {
246   Control::OnRelayout(size, container);
247
248   if(Self()[Actor::Property::CONNECTED_TO_SCENE] && size != mSize)
249   {
250     DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnRelayout: width = %f, height = %f [%p]\n", size.width, size.height, this);
251
252     mSize = size;
253
254     SetVectorImageSize();
255
256     if(mPlayState == Dali::Extension::RiveAnimationView::PlayState::PLAYING && mAnimationData.playState != Dali::Extension::RiveAnimationView::PlayState::PLAYING)
257     {
258       mAnimationData.playState = Dali::Extension::RiveAnimationView::PlayState::PLAYING;
259       mAnimationData.resendFlag |= RiveAnimationTask::RESEND_PLAY_STATE;
260     }
261
262     SendAnimationData();
263   }
264 }
265
266 ///////////////////////////////////////////////////////////
267 //
268 // Properties
269 //
270
271 void RiveAnimationView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
272 {
273   Dali::Extension::RiveAnimationView riveAnimationView = Dali::Extension::RiveAnimationView::DownCast(Dali::BaseHandle(object));
274
275   if(riveAnimationView)
276   {
277     RiveAnimationView& impl = GetImplementation(riveAnimationView);
278     switch(index)
279     {
280       case Dali::Extension::RiveAnimationView::Property::URL:
281       {
282         std::string url;
283         if(value.Get(url))
284         {
285           impl.SetUrl(url);
286         }
287         break;
288       }
289     }
290   }
291 }
292
293 Property::Value RiveAnimationView::GetProperty(BaseObject* object, Property::Index propertyIndex)
294 {
295   Property::Value value;
296
297   Dali::Extension::RiveAnimationView riveAnimationView = Dali::Extension::RiveAnimationView::DownCast(Dali::BaseHandle(object));
298
299   if(riveAnimationView)
300   {
301     RiveAnimationView& impl = GetImplementation(riveAnimationView);
302     switch(propertyIndex)
303     {
304       case Dali::Extension::RiveAnimationView::Property::URL:
305       {
306         value = impl.mUrl;
307         break;
308       }
309     }
310   }
311
312   return value;
313 }
314
315 void RiveAnimationView::PlayAnimation()
316 {
317   Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
318
319   if(Self()[Actor::Property::CONNECTED_TO_SCENE] && size != Vector3::ZERO)
320   {
321     if(mAnimationData.playState != Dali::Extension::RiveAnimationView::PlayState::PLAYING)
322     {
323       mAnimationData.playState = Dali::Extension::RiveAnimationView::PlayState::PLAYING;
324       mAnimationData.resendFlag |= RiveAnimationTask::RESEND_PLAY_STATE;
325     }
326   }
327   mPlayState = Dali::Extension::RiveAnimationView::PlayState::PLAYING;
328
329   TriggerVectorRasterization();
330 }
331
332 void RiveAnimationView::StopAnimation()
333 {
334   if(mAnimationData.playState != Dali::Extension::RiveAnimationView::PlayState::STOPPED)
335   {
336     mAnimationData.playState = Dali::Extension::RiveAnimationView::PlayState::STOPPED;
337     mAnimationData.resendFlag |= RiveAnimationTask::RESEND_PLAY_STATE;
338   }
339   mPlayState = Dali::Extension::RiveAnimationView::PlayState::STOPPED;
340
341   TriggerVectorRasterization();
342 }
343
344 void RiveAnimationView::PauseAnimation()
345 {
346   if(mAnimationData.playState == Dali::Extension::RiveAnimationView::PlayState::PLAYING)
347   {
348     mAnimationData.playState = Dali::Extension::RiveAnimationView::PlayState::PAUSED;
349     mAnimationData.resendFlag |= RiveAnimationTask::RESEND_PLAY_STATE;
350   }
351   mPlayState = Dali::Extension::RiveAnimationView::PlayState::PAUSED;
352
353   TriggerVectorRasterization();
354 }
355
356 void RiveAnimationView::EnableAnimation(const std::string& animationName, bool enable)
357 {
358   mAnimationData.animations.push_back(std::pair<std::string, bool>(animationName, enable));
359   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_ENABLE_ANIMATION;
360
361   TriggerVectorRasterization();
362 }
363
364 void RiveAnimationView::SetAnimationElapsedTime(const std::string& animationName, float elapsed)
365 {
366   mAnimationData.elapsedTimes.push_back(std::pair<std::string, float>(animationName, elapsed));
367   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_ANIMATION_ELAPSED_TIME;
368
369   TriggerVectorRasterization();
370 }
371
372 void RiveAnimationView::SetShapeFillColor(const std::string& fillName, Vector4 color)
373 {
374   mAnimationData.fillColors.push_back(std::pair<std::string, Vector4>(fillName, color));
375   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_FILL_COLOR;
376
377   TriggerVectorRasterization();
378 }
379
380 void RiveAnimationView::SetShapeStrokeColor(const std::string& strokeName, Vector4 color)
381 {
382   mAnimationData.strokeColors.push_back(std::pair<std::string, Vector4>(strokeName, color));
383   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_STROKE_COLOR;
384
385   TriggerVectorRasterization();
386 }
387
388 void RiveAnimationView::SetNodeOpacity(const std::string& nodeName, float opacity)
389 {
390   mAnimationData.opacities.push_back(std::pair<std::string, float>(nodeName, opacity));
391   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_OPACITY;
392
393   TriggerVectorRasterization();
394 }
395
396 void RiveAnimationView::SetNodeScale(const std::string& nodeName, Vector2 scale)
397 {
398   mAnimationData.scales.push_back(std::pair<std::string, Vector2>(nodeName, scale));
399   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_SCALE;
400
401   TriggerVectorRasterization();
402 }
403
404 void RiveAnimationView::SetNodeRotation(const std::string& nodeName, Degree degree)
405 {
406   mAnimationData.rotations.push_back(std::pair<std::string, Degree>(nodeName, degree));
407   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_ROTATION;
408
409   TriggerVectorRasterization();
410 }
411
412 void RiveAnimationView::SetNodePosition(const std::string& nodeName, Vector2 position)
413 {
414   mAnimationData.positions.push_back(std::pair<std::string, Vector2>(nodeName, position));
415   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_POSITION;
416
417   TriggerVectorRasterization();
418 }
419
420 void RiveAnimationView::PointerMove(float x, float y)
421 {
422   mRiveAnimationTask->PointerMove(x, y);
423 }
424
425 void RiveAnimationView::PointerDown(float x, float y)
426 {
427   mRiveAnimationTask->PointerDown(x, y);
428 }
429
430 void RiveAnimationView::PointerUp(float x, float y)
431 {
432   mRiveAnimationTask->PointerUp(x, y);
433 }
434
435 bool RiveAnimationView::SetNumberState(const std::string& stateMachineName, const std::string& inputName, float value)
436 {
437   return mRiveAnimationTask->SetNumberState(stateMachineName, inputName, value);
438 }
439
440 bool RiveAnimationView::SetBooleanState(const std::string& stateMachineName, const std::string& inputName, bool value)
441 {
442   return mRiveAnimationTask->SetBooleanState(stateMachineName, inputName, value);
443 }
444
445 bool RiveAnimationView::FireState(const std::string& stateMachineName, const std::string& inputName)
446 {
447   return mRiveAnimationTask->FireState(stateMachineName, inputName);
448 }
449
450 Dali::Extension::RiveAnimationView::AnimationSignalType& RiveAnimationView::AnimationFinishedSignal()
451 {
452   return mFinishedSignal;
453 }
454
455 void RiveAnimationView::RiveAnimationManagerDestroyed()
456 {
457   mCoreShutdown = true;
458 }
459
460 void RiveAnimationView::SetUrl(const std::string& url)
461 {
462   mUrl = url;
463
464   if(!mRiveAnimationTask->Load(mUrl))
465   {
466     mLoadFailed = true;
467   }
468
469   mRiveAnimationTask->UploadCompletedSignal().Connect(this, &RiveAnimationView::OnUploadCompleted);
470   mRiveAnimationTask->SetAnimationFinishedCallback(new EventThreadCallback(MakeCallback(this, &RiveAnimationView::OnAnimationFinished)));
471
472   auto& vectorAnimationManager = RiveAnimationManager::GetInstance();
473   vectorAnimationManager.AddObserver(*this);
474
475   Geometry geometry = CreateQuadGeometry();
476   Shader   shader   = Shader::New(VERTEX_SHADER, FRAGMENT_SHADER);
477   mRenderer  = Renderer::New(geometry, shader);
478
479   TextureSet textureSet = TextureSet::New();
480   mRenderer.SetTextures(textureSet);
481
482   mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
483
484   mRiveAnimationTask->SetRenderer(mRenderer);
485
486   TriggerVectorRasterization();
487 }
488
489 void RiveAnimationView::OnUploadCompleted()
490 {
491   if(!mRendererAdded)
492   {
493     Self().AddRenderer(mRenderer);
494     mRendererAdded = true;
495
496     //TODO: do something - resource ready
497
498     DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnUploadCompleted: Renderer is added [%p]\n", this);
499   }
500 }
501
502 void RiveAnimationView::OnAnimationFinished()
503 {
504   DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnAnimationFinished: action state = %d [%p]\n", mPlayState, this);
505
506   if(mPlayState != Dali::Extension::RiveAnimationView::PlayState::STOPPED)
507   {
508     mPlayState = Dali::Extension::RiveAnimationView::PlayState::STOPPED;
509
510     mAnimationData.playState = Dali::Extension::RiveAnimationView::PlayState::STOPPED;
511
512     Dali::Extension::RiveAnimationView handle(GetOwner());
513     mFinishedSignal.Emit(handle);
514   }
515
516   if(mRenderer)
517   {
518     mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
519   }
520 }
521
522 void RiveAnimationView::SendAnimationData()
523 {
524   if(mAnimationData.resendFlag)
525   {
526     mRiveAnimationTask->SetAnimationData(mAnimationData);
527     ClearAnimationsData();
528
529     if(mRenderer)
530     {
531       if(mAnimationData.playState == Dali::Extension::RiveAnimationView::PlayState::PLAYING)
532       {
533         mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
534       }
535       else
536       {
537         mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
538       }
539     }
540
541     mAnimationData.resendFlag = 0;
542   }
543 }
544
545 void RiveAnimationView::ClearAnimationsData()
546 {
547     mAnimationData.animations.clear();
548     mAnimationData.elapsedTimes.clear();
549     mAnimationData.fillColors.clear();
550     mAnimationData.strokeColors.clear();
551     mAnimationData.opacities.clear();
552     mAnimationData.scales.clear();
553     mAnimationData.rotations.clear();
554     mAnimationData.positions.clear();
555 }
556
557 void RiveAnimationView::SetVectorImageSize()
558 {
559   uint32_t width  = static_cast<uint32_t>(mSize.width * mScale.width);
560   uint32_t height = static_cast<uint32_t>(mSize.height * mScale.height);
561
562   mAnimationData.width  = width;
563   mAnimationData.height = height;
564   mAnimationData.resendFlag |= RiveAnimationTask::RESEND_SIZE;
565 }
566
567 void RiveAnimationView::TriggerVectorRasterization()
568 {
569   if(!mEventCallback && !mCoreShutdown)
570   {
571     mEventCallback             = MakeCallback(this, &RiveAnimationView::OnProcessEvents);
572     auto& riveAnimationManager = RiveAnimationManager::GetInstance();
573     riveAnimationManager.RegisterEventCallback(mEventCallback);
574     Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
575   }
576 }
577
578 void RiveAnimationView::OnScaleNotification(PropertyNotification& source)
579 {
580   Vector3 scale = Self().GetProperty<Vector3>(Actor::Property::WORLD_SCALE);
581
582   if(scale.width >= 1.0f || scale.height >= 1.0f)
583   {
584     mScale.width  = scale.width;
585     mScale.height = scale.height;
586
587     DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnScaleNotification: scale = %f, %f [%p]\n", mScale.width, mScale.height, this);
588
589     SetVectorImageSize();
590     SendAnimationData();
591
592     Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
593   }
594 }
595
596 void RiveAnimationView::OnSizeNotification(PropertyNotification& source)
597 {
598   Vector3 size       = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
599   mSize.width  = size.width;
600   mSize.height = size.height;
601
602   DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnSizeNotification: size = %f, %f [%p]\n", mSize.width, mSize.height, this);
603
604   SetVectorImageSize();
605   SendAnimationData();
606
607   Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing
608 }
609
610 void RiveAnimationView::OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type)
611 {
612   if(!visible)
613   {
614     StopAnimation();
615     TriggerVectorRasterization();
616
617     DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this);
618   }
619 }
620
621 void RiveAnimationView::OnWindowVisibilityChanged(Window window, bool visible)
622 {
623   if(!visible)
624   {
625     StopAnimation();
626     TriggerVectorRasterization();
627
628     DALI_LOG_INFO(gRiveAnimationLogFilter, Debug::Verbose, "RiveAnimationView::OnWindowVisibilityChanged: invisibile. Pause animation [%p]\n", this);
629   }
630 }
631
632 void RiveAnimationView::OnProcessEvents()
633 {
634   SendAnimationData();
635
636   mEventCallback = nullptr; // The callback will be deleted in the RiveAnimationManager
637 }
638
639 } // namespace Internal
640 } // namespace Extension
641 } // namespace Dali