[AT-SPI] Require ControlAccessible for Control
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / effects-view / effects-view-impl.cpp
1 /*
2  * Copyright (c) 2021 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 "effects-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/common/stage.h>
23 #include <dali/public-api/animation/constraint.h>
24 #include <dali/public-api/animation/constraints.h>
25 #include <dali/public-api/object/property-map.h>
26 #include <dali/public-api/object/property.h>
27 #include <dali/public-api/object/type-registry-helper.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/render-tasks/render-task-list.h>
30 #include <dali/public-api/rendering/renderer.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
34 #include <dali-toolkit/devel-api/controls/control-devel.h>
35 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
36 #include <dali-toolkit/internal/controls/control/control-renderers.h>
37 #include <dali-toolkit/internal/filters/blur-two-pass-filter.h>
38 #include <dali-toolkit/internal/filters/emboss-filter.h>
39 #include <dali-toolkit/internal/filters/spread-filter.h>
40 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
41
42 namespace Dali
43 {
44 namespace Toolkit
45 {
46 namespace Internal
47 {
48 namespace
49 {
50 Dali::BaseHandle Create()
51 {
52   return EffectsView::New();
53 }
54
55 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::EffectsView, Toolkit::Control, Create)
56 DALI_PROPERTY_REGISTRATION(Toolkit, EffectsView, "effectSize", INTEGER, EFFECT_SIZE)
57 DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, EffectsView, "effectOffset", VECTOR3, EFFECT_OFFSET)
58 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, EffectsView, "effectColor", Color::WHITE, EFFECT_COLOR)
59 DALI_TYPE_REGISTRATION_END()
60
61 const Pixel::Format EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT = Pixel::RGBA8888;
62 const float         ARBITRARY_FIELD_OF_VIEW           = Math::PI / 4.0f;
63 const Vector4       EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR(0.0f, 0.0f, 0.0f, 0.0);
64 const bool          EFFECTS_VIEW_REFRESH_ON_DEMAND(false);
65
66 // clang-format off
67 const float BLUR_KERNEL0[] = {12.0f/16.0f,
68                               2.0f/16.0f, 2.0f/16.0f};
69
70 const float BLUR_KERNEL1[] = {8.0f/16.0f,
71                               4.0f/16.0f, 4.0f/16.0f };
72
73 const float BLUR_KERNEL2[] = {6.0f/16.0f,
74                               2.5f/16.0f, 2.5f/16.0f,
75                               1.5f/16.0f, 1.5f/16.0f,
76                               1.0f/16.0f, 1.0f/16.0f};
77
78 const float BLUR_KERNEL3[] = {4.0f/16.0f,
79                               3.0f/16.0f, 2.0f/16.0f,
80                               2.0f/16.0f, 2.0f/16.0f,
81                               1.0f/16.0f, 1.0f/16.0f};
82
83 const float BLUR_KERNEL4[] = {3.0f/16.0f,
84                               2.5f/16.0f,  2.5f/16.0f,
85                               1.75f/16.0f, 1.75f/16.0f,
86                               1.25f/16.0f, 1.25f/16.0f,
87                               1.0f/16.0f,  1.0f/16.0f};
88 // clang-format on
89 } // namespace
90
91 Toolkit::EffectsView EffectsView::New()
92 {
93   EffectsView* effectsView = new EffectsView;
94
95   Toolkit::EffectsView handle = Toolkit::EffectsView(*effectsView);
96
97   // Second-phase init of the implementation
98   // This can only be done after the CustomActor connection has been made...
99   effectsView->Initialize();
100
101   return handle;
102 }
103
104 EffectsView::EffectsView()
105 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
106   mChildrenRoot(Actor::New()),
107   mBackgroundColor(EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR),
108   mTargetSize(Vector2::ZERO),
109   mLastSize(Vector2::ZERO),
110   mEffectSize(0),
111   mEffectType(Toolkit::EffectsView::INVALID_TYPE),
112   mPixelFormat(EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT),
113   mEnabled(false),
114   mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND)
115 {
116 }
117
118 EffectsView::~EffectsView()
119 {
120   RemoveFilters();
121 }
122
123 void EffectsView::SetType(Toolkit::EffectsView::EffectType type)
124 {
125   if(mEffectType != type)
126   {
127     RemoveFilters();
128
129     Actor self = Self();
130
131     switch(type)
132     {
133       case Toolkit::EffectsView::DROP_SHADOW:
134       {
135         mFilters.PushBack(new SpreadFilter);
136         mFilters.PushBack(new BlurTwoPassFilter);
137         break;
138       }
139       case Toolkit::EffectsView::EMBOSS:
140       {
141         mFilters.PushBack(new SpreadFilter);
142         mFilters.PushBack(new EmbossFilter);
143         mFilters.PushBack(new BlurTwoPassFilter);
144         break;
145       }
146       default:
147       {
148         break;
149       }
150     }
151
152     mEffectType = type;
153   }
154 }
155
156 Toolkit::EffectsView::EffectType EffectsView::GetType() const
157 {
158   return mEffectType;
159 }
160
161 void EffectsView::Enable()
162 {
163   // make sure resources are allocated and start the render tasks processing
164   AllocateResources();
165   CreateRenderTasks();
166   mEnabled = true;
167 }
168
169 void EffectsView::Disable()
170 {
171   // stop render tasks processing
172   RemoveRenderTasks();
173   mLastSize = Vector2::ZERO; // Ensure resources are reallocated on subsequent enable
174   mEnabled  = false;
175 }
176
177 void EffectsView::Refresh()
178 {
179   RefreshRenderTasks();
180 }
181
182 void EffectsView::SetRefreshOnDemand(bool onDemand)
183 {
184   mRefreshOnDemand = onDemand;
185
186   RefreshRenderTasks();
187 }
188
189 void EffectsView::SetPixelFormat(Pixel::Format pixelFormat)
190 {
191   mPixelFormat = pixelFormat;
192 }
193
194 void EffectsView::SetBackgroundColor(const Vector4& color)
195 {
196   mBackgroundColor = color;
197 }
198
199 Vector4 EffectsView::GetBackgroundColor() const
200 {
201   return mBackgroundColor;
202 }
203
204 void EffectsView::SetEffectSize(int effectSize)
205 {
206   mEffectSize = effectSize;
207
208   if(mEnabled)
209   {
210     const size_t numFilters(mFilters.Size());
211     for(size_t i = 0; i < numFilters; ++i)
212     {
213       mFilters[i]->Disable();
214     }
215
216     SetupFilters();
217
218     for(size_t i = 0; i < numFilters; ++i)
219     {
220       mFilters[i]->Enable();
221     }
222   }
223 }
224
225 int EffectsView::GetEffectSize()
226 {
227   return mEffectSize;
228 }
229
230 // From Control
231 void EffectsView::OnInitialize()
232 {
233   CustomActor self = Self();
234   mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
235   self.Add(mChildrenRoot);
236
237   DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
238     return std::make_unique<DevelControl::ControlAccessible>(actor, Dali::Accessibility::Role::FILLER);
239   });
240 }
241
242 void EffectsView::OnSizeSet(const Vector3& targetSize)
243 {
244   mTargetSize = Vector2(targetSize);
245
246   // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
247   if(mEnabled)
248   {
249     if(mLastSize != Vector2::ZERO)
250     {
251       Disable();
252     }
253     Enable();
254   }
255
256   mChildrenRoot.SetProperty(Actor::Property::SIZE, targetSize);
257
258   Control::OnSizeSet(targetSize);
259 }
260
261 void EffectsView::OnSceneConnection(int depth)
262 {
263   Actor self(Self());
264
265   // Create renderers
266   mRendererPostFilter = CreateRenderer(SHADER_EFFECTS_VIEW_VERT,
267                                        SHADER_EFFECTS_VIEW_FRAG);
268   mRendererPostFilter.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT);
269   self.AddRenderer(mRendererPostFilter);
270
271   mRendererForChildren = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE);
272   mRendererForChildren.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT + 1);
273   self.AddRenderer(mRendererForChildren);
274
275   Enable();
276
277   Control::OnSceneConnection(depth);
278 }
279
280 void EffectsView::OnSceneDisconnection()
281 {
282   Actor self(Self());
283
284   Disable();
285
286   const size_t numFilters(mFilters.Size());
287   for(size_t i = 0; i < numFilters; ++i)
288   {
289     mFilters[i]->Disable();
290   }
291
292   // Remove renderers
293   self.RemoveRenderer(mRendererForChildren);
294   mRendererForChildren.Reset();
295
296   self.RemoveRenderer(mRendererPostFilter);
297   mRendererPostFilter.Reset();
298
299   Control::OnSceneDisconnection();
300 }
301
302 void EffectsView::OnChildAdd(Actor& child)
303 {
304   if(child != mChildrenRoot && child != mCameraForChildren)
305   {
306     mChildrenRoot.Add(child);
307   }
308
309   Control::OnChildAdd(child);
310 }
311
312 void EffectsView::OnChildRemove(Actor& child)
313 {
314   mChildrenRoot.Remove(child);
315
316   Control::OnChildRemove(child);
317 }
318
319 void EffectsView::SetupFilters()
320 {
321   switch(mEffectType)
322   {
323     case Toolkit::EffectsView::DROP_SHADOW:
324     {
325       SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
326       spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
327       spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
328       spreadFilter->SetRootActor(mChildrenRoot);
329       spreadFilter->SetBackgroundColor(mBackgroundColor);
330       spreadFilter->SetPixelFormat(mPixelFormat);
331       spreadFilter->SetSize(mTargetSize);
332       spreadFilter->SetSpread(mEffectSize);
333
334       BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[1]);
335       blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
336       blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
337       blurFilter->SetRootActor(mChildrenRoot);
338       blurFilter->SetBackgroundColor(mBackgroundColor);
339       blurFilter->SetPixelFormat(mPixelFormat);
340       blurFilter->SetSize(mTargetSize);
341
342       const float* kernel(NULL);
343       size_t       kernelSize(0);
344       switch(mEffectSize)
345       {
346         case 4:
347         {
348           kernel     = BLUR_KERNEL4;
349           kernelSize = sizeof(BLUR_KERNEL4) / sizeof(BLUR_KERNEL4[0]);
350           break;
351         }
352         case 3:
353         {
354           kernel     = BLUR_KERNEL3;
355           kernelSize = sizeof(BLUR_KERNEL3) / sizeof(BLUR_KERNEL3[0]);
356           break;
357         }
358         case 2:
359         {
360           kernel     = BLUR_KERNEL2;
361           kernelSize = sizeof(BLUR_KERNEL2) / sizeof(BLUR_KERNEL2[0]);
362           break;
363         }
364         case 1:
365         {
366           kernel     = BLUR_KERNEL1;
367           kernelSize = sizeof(BLUR_KERNEL1) / sizeof(BLUR_KERNEL1[0]);
368           break;
369         }
370         case 0:
371         default:
372         {
373           kernel     = BLUR_KERNEL0;
374           kernelSize = sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]);
375           break;
376         }
377       }
378       blurFilter->CreateKernel(kernel, kernelSize);
379       break;
380     }
381     case Toolkit::EffectsView::EMBOSS:
382     {
383       SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
384       spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
385       spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
386       spreadFilter->SetRootActor(mChildrenRoot);
387       spreadFilter->SetBackgroundColor(mBackgroundColor);
388       spreadFilter->SetPixelFormat(Pixel::RGBA8888);
389       spreadFilter->SetSize(mTargetSize);
390       spreadFilter->SetSpread(mEffectSize);
391
392       EmbossFilter* embossFilter = static_cast<EmbossFilter*>(mFilters[1]);
393       embossFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
394       embossFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
395       embossFilter->SetRootActor(mChildrenRoot);
396       embossFilter->SetBackgroundColor(mBackgroundColor);
397       embossFilter->SetPixelFormat(Pixel::RGBA8888);
398       embossFilter->SetSize(mTargetSize);
399
400       BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[2]);
401       blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
402       blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
403       blurFilter->SetRootActor(mChildrenRoot);
404       blurFilter->SetBackgroundColor(Vector4(0.5f, 0.5f, 0.5f, 0.0));
405       blurFilter->SetPixelFormat(Pixel::RGBA8888);
406       blurFilter->SetSize(mTargetSize);
407       blurFilter->CreateKernel(BLUR_KERNEL0, sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]));
408
409       break;
410     }
411     default:
412     {
413       break;
414     }
415   }
416 }
417
418 void EffectsView::AllocateResources()
419 {
420   if(mTargetSize != mLastSize)
421   {
422     mLastSize = mTargetSize;
423     SetupCameras();
424
425     Actor self(Self());
426
427     mFrameBufferForChildren    = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
428     Texture textureForChildren = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
429     mFrameBufferForChildren.AttachColorTexture(textureForChildren);
430
431     SetRendererTexture(mRendererForChildren, textureForChildren);
432
433     mFrameBufferPostFilter    = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
434     Texture texturePostFilter = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
435     mFrameBufferPostFilter.AttachColorTexture(texturePostFilter);
436
437     SetRendererTexture(mRendererPostFilter, texturePostFilter);
438
439     SetupFilters();
440   }
441 }
442
443 void EffectsView::SetupCameras()
444 {
445   if(!mCameraForChildren)
446   {
447     // Create a camera for the children render, corresponding to its render target size
448     mCameraForChildren = CameraActor::New(mTargetSize);
449     mCameraForChildren.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
450     mCameraForChildren.SetInvertYAxis(true);
451     Self().Add(mCameraForChildren);
452   }
453   else
454   {
455     // place the camera for the children render, corresponding to its render target size
456     const float cameraPosScale(0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f));
457     mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
458     mCameraForChildren.SetNearClippingPlane(1.0f);
459     mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
460     mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
461     mCameraForChildren.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, mTargetSize.height * cameraPosScale));
462     mCameraForChildren.SetProperty(Actor::Property::POSITION_Z, mTargetSize.height * cameraPosScale);
463   }
464 }
465
466 void EffectsView::CreateRenderTasks()
467 {
468   if(mTargetSize == Vector2::ZERO)
469   {
470     return;
471   }
472   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
473
474   // create render task to render our child actors to offscreen buffer
475   mRenderTaskForChildren = taskList.CreateTask();
476   mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
477   mRenderTaskForChildren.SetSourceActor(mChildrenRoot);
478   mRenderTaskForChildren.SetExclusive(true);
479   mRenderTaskForChildren.SetInputEnabled(false);
480   mRenderTaskForChildren.SetClearColor(mBackgroundColor);
481   mRenderTaskForChildren.SetClearEnabled(true);
482   mRenderTaskForChildren.SetFrameBuffer(mFrameBufferForChildren);
483   mRenderTaskForChildren.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
484
485   // Enable image filters
486   const size_t numFilters(mFilters.Size());
487   for(size_t i = 0; i < numFilters; ++i)
488   {
489     mFilters[i]->Enable();
490   }
491 }
492
493 void EffectsView::RemoveRenderTasks()
494 {
495   if(mTargetSize == Vector2::ZERO)
496   {
497     return;
498   }
499
500   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
501
502   taskList.RemoveTask(mRenderTaskForChildren);
503
504   const size_t numFilters(mFilters.Size());
505   for(size_t i = 0; i < numFilters; ++i)
506   {
507     mFilters[i]->Disable();
508   }
509 }
510
511 void EffectsView::RefreshRenderTasks()
512 {
513   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
514
515   if(mRenderTaskForChildren)
516   {
517     mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
518   }
519
520   const size_t numFilters(mFilters.Size());
521   for(size_t i = 0; i < numFilters; ++i)
522   {
523     mFilters[i]->Refresh();
524   }
525 }
526
527 void EffectsView::RemoveFilters()
528 {
529   const size_t numFilters(mFilters.Size());
530   for(size_t i = 0; i < numFilters; ++i)
531   {
532     delete mFilters[i];
533   }
534   mFilters.Release();
535 }
536
537 void EffectsView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
538 {
539   Toolkit::EffectsView effectsView = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
540
541   if(effectsView)
542   {
543     switch(index)
544     {
545       case Toolkit::EffectsView::Property::EFFECT_SIZE:
546       {
547         int effectSize;
548         if(value.Get(effectSize))
549         {
550           GetImpl(effectsView).SetEffectSize(effectSize);
551         }
552         break;
553       }
554       default:
555       {
556         break;
557       }
558     }
559   }
560 }
561
562 Property::Value EffectsView::GetProperty(BaseObject* object, Property::Index propertyIndex)
563 {
564   Property::Value value;
565
566   Toolkit::EffectsView imageview = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
567
568   if(imageview)
569   {
570     EffectsView& impl = GetImpl(imageview);
571     switch(propertyIndex)
572     {
573       case Toolkit::EffectsView::Property::EFFECT_SIZE:
574       {
575         value = impl.GetEffectSize();
576         break;
577       }
578       default:
579       {
580         break;
581       }
582     }
583   }
584
585   return value;
586 }
587
588 } // namespace Internal
589
590 } // namespace Toolkit
591
592 } // namespace Dali