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