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