[AT-SPI] Remove SetAccessibilityConstructor()
[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   self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::FILLER);
238 }
239
240 void EffectsView::OnSizeSet(const Vector3& targetSize)
241 {
242   mTargetSize = Vector2(targetSize);
243
244   // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
245   if(mEnabled)
246   {
247     if(mLastSize != Vector2::ZERO)
248     {
249       Disable();
250     }
251     Enable();
252   }
253
254   mChildrenRoot.SetProperty(Actor::Property::SIZE, targetSize);
255
256   Control::OnSizeSet(targetSize);
257 }
258
259 void EffectsView::OnSceneConnection(int depth)
260 {
261   Actor self(Self());
262
263   // Create renderers
264   mRendererPostFilter = CreateRenderer(SHADER_EFFECTS_VIEW_VERT,
265                                        SHADER_EFFECTS_VIEW_FRAG);
266   mRendererPostFilter.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT);
267   self.AddRenderer(mRendererPostFilter);
268
269   mRendererForChildren = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE);
270   mRendererForChildren.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT + 1);
271   self.AddRenderer(mRendererForChildren);
272
273   Enable();
274
275   Control::OnSceneConnection(depth);
276 }
277
278 void EffectsView::OnSceneDisconnection()
279 {
280   Actor self(Self());
281
282   Disable();
283
284   const size_t numFilters(mFilters.Size());
285   for(size_t i = 0; i < numFilters; ++i)
286   {
287     mFilters[i]->Disable();
288   }
289
290   // Remove renderers
291   self.RemoveRenderer(mRendererForChildren);
292   mRendererForChildren.Reset();
293
294   self.RemoveRenderer(mRendererPostFilter);
295   mRendererPostFilter.Reset();
296
297   Control::OnSceneDisconnection();
298 }
299
300 void EffectsView::OnChildAdd(Actor& child)
301 {
302   if(child != mChildrenRoot && child != mCameraForChildren)
303   {
304     mChildrenRoot.Add(child);
305   }
306
307   Control::OnChildAdd(child);
308 }
309
310 void EffectsView::OnChildRemove(Actor& child)
311 {
312   mChildrenRoot.Remove(child);
313
314   Control::OnChildRemove(child);
315 }
316
317 void EffectsView::SetupFilters()
318 {
319   switch(mEffectType)
320   {
321     case Toolkit::EffectsView::DROP_SHADOW:
322     {
323       SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
324       spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
325       spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
326       spreadFilter->SetRootActor(mChildrenRoot);
327       spreadFilter->SetBackgroundColor(mBackgroundColor);
328       spreadFilter->SetPixelFormat(mPixelFormat);
329       spreadFilter->SetSize(mTargetSize);
330       spreadFilter->SetSpread(mEffectSize);
331
332       BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[1]);
333       blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
334       blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
335       blurFilter->SetRootActor(mChildrenRoot);
336       blurFilter->SetBackgroundColor(mBackgroundColor);
337       blurFilter->SetPixelFormat(mPixelFormat);
338       blurFilter->SetSize(mTargetSize);
339
340       const float* kernel(NULL);
341       size_t       kernelSize(0);
342       switch(mEffectSize)
343       {
344         case 4:
345         {
346           kernel     = BLUR_KERNEL4;
347           kernelSize = sizeof(BLUR_KERNEL4) / sizeof(BLUR_KERNEL4[0]);
348           break;
349         }
350         case 3:
351         {
352           kernel     = BLUR_KERNEL3;
353           kernelSize = sizeof(BLUR_KERNEL3) / sizeof(BLUR_KERNEL3[0]);
354           break;
355         }
356         case 2:
357         {
358           kernel     = BLUR_KERNEL2;
359           kernelSize = sizeof(BLUR_KERNEL2) / sizeof(BLUR_KERNEL2[0]);
360           break;
361         }
362         case 1:
363         {
364           kernel     = BLUR_KERNEL1;
365           kernelSize = sizeof(BLUR_KERNEL1) / sizeof(BLUR_KERNEL1[0]);
366           break;
367         }
368         case 0:
369         default:
370         {
371           kernel     = BLUR_KERNEL0;
372           kernelSize = sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]);
373           break;
374         }
375       }
376       blurFilter->CreateKernel(kernel, kernelSize);
377       break;
378     }
379     case Toolkit::EffectsView::EMBOSS:
380     {
381       SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
382       spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
383       spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
384       spreadFilter->SetRootActor(mChildrenRoot);
385       spreadFilter->SetBackgroundColor(mBackgroundColor);
386       spreadFilter->SetPixelFormat(Pixel::RGBA8888);
387       spreadFilter->SetSize(mTargetSize);
388       spreadFilter->SetSpread(mEffectSize);
389
390       EmbossFilter* embossFilter = static_cast<EmbossFilter*>(mFilters[1]);
391       embossFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
392       embossFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
393       embossFilter->SetRootActor(mChildrenRoot);
394       embossFilter->SetBackgroundColor(mBackgroundColor);
395       embossFilter->SetPixelFormat(Pixel::RGBA8888);
396       embossFilter->SetSize(mTargetSize);
397
398       BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[2]);
399       blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
400       blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
401       blurFilter->SetRootActor(mChildrenRoot);
402       blurFilter->SetBackgroundColor(Vector4(0.5f, 0.5f, 0.5f, 0.0));
403       blurFilter->SetPixelFormat(Pixel::RGBA8888);
404       blurFilter->SetSize(mTargetSize);
405       blurFilter->CreateKernel(BLUR_KERNEL0, sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]));
406
407       break;
408     }
409     default:
410     {
411       break;
412     }
413   }
414 }
415
416 void EffectsView::AllocateResources()
417 {
418   if(mTargetSize != mLastSize)
419   {
420     mLastSize = mTargetSize;
421     SetupCameras();
422
423     Actor self(Self());
424
425     mFrameBufferForChildren    = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
426     Texture textureForChildren = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
427     mFrameBufferForChildren.AttachColorTexture(textureForChildren);
428
429     SetRendererTexture(mRendererForChildren, textureForChildren);
430
431     mFrameBufferPostFilter    = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
432     Texture texturePostFilter = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
433     mFrameBufferPostFilter.AttachColorTexture(texturePostFilter);
434
435     SetRendererTexture(mRendererPostFilter, texturePostFilter);
436
437     SetupFilters();
438   }
439 }
440
441 void EffectsView::SetupCameras()
442 {
443   if(!mCameraForChildren)
444   {
445     // Create a camera for the children render, corresponding to its render target size
446     mCameraForChildren = CameraActor::New(mTargetSize);
447     mCameraForChildren.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
448     mCameraForChildren.SetInvertYAxis(true);
449     Self().Add(mCameraForChildren);
450   }
451   else
452   {
453     // place the camera for the children render, corresponding to its render target size
454     const float cameraPosScale(0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f));
455     mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
456     mCameraForChildren.SetNearClippingPlane(1.0f);
457     mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
458     mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
459     mCameraForChildren.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, mTargetSize.height * cameraPosScale));
460     mCameraForChildren.SetProperty(Actor::Property::POSITION_Z, mTargetSize.height * cameraPosScale);
461   }
462 }
463
464 void EffectsView::CreateRenderTasks()
465 {
466   if(mTargetSize == Vector2::ZERO)
467   {
468     return;
469   }
470   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
471
472   // create render task to render our child actors to offscreen buffer
473   mRenderTaskForChildren = taskList.CreateTask();
474   mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
475   mRenderTaskForChildren.SetSourceActor(mChildrenRoot);
476   mRenderTaskForChildren.SetExclusive(true);
477   mRenderTaskForChildren.SetInputEnabled(false);
478   mRenderTaskForChildren.SetClearColor(mBackgroundColor);
479   mRenderTaskForChildren.SetClearEnabled(true);
480   mRenderTaskForChildren.SetFrameBuffer(mFrameBufferForChildren);
481   mRenderTaskForChildren.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
482
483   // Enable image filters
484   const size_t numFilters(mFilters.Size());
485   for(size_t i = 0; i < numFilters; ++i)
486   {
487     mFilters[i]->Enable();
488   }
489 }
490
491 void EffectsView::RemoveRenderTasks()
492 {
493   if(mTargetSize == Vector2::ZERO)
494   {
495     return;
496   }
497
498   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
499
500   taskList.RemoveTask(mRenderTaskForChildren);
501
502   const size_t numFilters(mFilters.Size());
503   for(size_t i = 0; i < numFilters; ++i)
504   {
505     mFilters[i]->Disable();
506   }
507 }
508
509 void EffectsView::RefreshRenderTasks()
510 {
511   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
512
513   if(mRenderTaskForChildren)
514   {
515     mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
516   }
517
518   const size_t numFilters(mFilters.Size());
519   for(size_t i = 0; i < numFilters; ++i)
520   {
521     mFilters[i]->Refresh();
522   }
523 }
524
525 void EffectsView::RemoveFilters()
526 {
527   const size_t numFilters(mFilters.Size());
528   for(size_t i = 0; i < numFilters; ++i)
529   {
530     delete mFilters[i];
531   }
532   mFilters.Release();
533 }
534
535 void EffectsView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
536 {
537   Toolkit::EffectsView effectsView = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
538
539   if(effectsView)
540   {
541     switch(index)
542     {
543       case Toolkit::EffectsView::Property::EFFECT_SIZE:
544       {
545         int effectSize;
546         if(value.Get(effectSize))
547         {
548           GetImpl(effectsView).SetEffectSize(effectSize);
549         }
550         break;
551       }
552       default:
553       {
554         break;
555       }
556     }
557   }
558 }
559
560 Property::Value EffectsView::GetProperty(BaseObject* object, Property::Index propertyIndex)
561 {
562   Property::Value value;
563
564   Toolkit::EffectsView imageview = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
565
566   if(imageview)
567   {
568     EffectsView& impl = GetImpl(imageview);
569     switch(propertyIndex)
570     {
571       case Toolkit::EffectsView::Property::EFFECT_SIZE:
572       {
573         value = impl.GetEffectSize();
574         break;
575       }
576       default:
577       {
578         break;
579       }
580     }
581   }
582
583   return value;
584 }
585
586 } // namespace Internal
587
588 } // namespace Toolkit
589
590 } // namespace Dali