[dali_1.1.30] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / filters / spread-filter.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 "spread-filter.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/constraints.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/object/property-map.h>
25 #include <dali/public-api/render-tasks/render-task-list.h>
26
27 // INTERNAL INCLUDES
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40
41 const char* const SPREAD_FRAGMENT_SOURCE =
42 {
43  "precision highp float;\n"
44  "varying mediump vec2 vTexCoord;\n"
45  "uniform sampler2D sTexture;\n"
46  "uniform int uSpread;\n"
47  "uniform vec2 uTexScale;\n"
48  "void main()\n"
49  "{\n"
50  "  vec4 color = texture2D( sTexture, vTexCoord);\n"
51  "  for( int i = 1; i <= uSpread; ++i )\n"
52  "  {\n"
53  "    vec2 offset = uTexScale * float(i);\n"
54  "    color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
55  "    color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
56  "  }\n"
57  "  gl_FragColor = color;\n"
58  "}\n"
59 };
60
61 const char* const SPREAD_UNIFORM_NAME( "uSpread" );
62 const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" );
63
64 } // namespace
65
66
67 SpreadFilter::SpreadFilter()
68 : ImageFilter(),
69   mSpread(2)
70 {
71 }
72
73 SpreadFilter::~SpreadFilter()
74 {
75 }
76
77 void SpreadFilter::SetSpread( float spread )
78 {
79   mSpread = spread;
80 }
81
82 void SpreadFilter::Enable()
83 {
84   // create actor to render input with applied emboss effect
85   mActorForInput = Toolkit::ImageView::New( mInputImage );
86   mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
87   mActorForInput.SetSize(mTargetSize);
88   // register properties as shader uniforms
89   mActorForInput.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
90   mActorForInput.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 1.0f / mTargetSize.width, 0.0f ) );
91
92   // create internal offscreen for result of horizontal pass
93   mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
94   // create an actor to render mImageForHorz for vertical blur pass
95   mActorForHorz = Toolkit::ImageView::New( mImageForHorz );
96   mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
97   mActorForHorz.SetSize(mTargetSize);
98   // register properties as shader uniforms
99   mActorForHorz.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
100   mActorForHorz.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 0.0f, 1.0f / mTargetSize.height ) );
101
102   Property::Map customShader;
103   customShader[ "fragmentShader" ] = SPREAD_FRAGMENT_SOURCE;
104   Property::Map rendererMap;
105   rendererMap.Insert( "shader", customShader );
106
107   // set SPREAD custom shader
108   mActorForInput.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
109   mActorForHorz.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
110
111   mRootActor.Add( mActorForInput );
112   mRootActor.Add( mActorForHorz );
113
114   SetupCamera();
115   CreateRenderTasks();
116 }
117
118 void SpreadFilter::Disable()
119 {
120   if( mRootActor )
121   {
122     if( mCameraActor )
123     {
124       mRootActor.Remove( mCameraActor );
125       mCameraActor.Reset();
126     }
127
128     if( mActorForInput )
129     {
130       mRootActor.Remove( mActorForInput );
131       mActorForInput.Reset();
132     }
133
134     if( mActorForHorz )
135     {
136       mRootActor.Remove( mActorForHorz );
137       mActorForHorz.Reset();
138     }
139
140     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
141
142     if( mRenderTaskForHorz )
143     {
144       taskList.RemoveTask(mRenderTaskForHorz);
145     }
146     if( mRenderTaskForVert )
147     {
148       taskList.RemoveTask(mRenderTaskForVert);
149     }
150
151     mRootActor.Reset();
152   }
153 }
154
155 void SpreadFilter::Refresh()
156 {
157   if( mRenderTaskForHorz )
158   {
159     mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
160   }
161
162   if( mRenderTaskForVert )
163   {
164     mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
165   }
166 }
167
168 void SpreadFilter::SetSize( const Vector2& size )
169 {
170   mTargetSize = size;
171   if( mActorForInput )
172   {
173     mActorForInput.SetSize(mTargetSize);
174   }
175   if( mActorForHorz )
176   {
177     mActorForHorz.SetSize(mTargetSize);
178   }
179 }
180
181 void SpreadFilter::CreateRenderTasks()
182 {
183   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
184
185   // perform a horizontal blur targeting the internal buffer
186   mRenderTaskForHorz = taskList.CreateTask();
187   mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
188   mRenderTaskForHorz.SetSourceActor( mActorForInput );
189   mRenderTaskForHorz.SetExclusive(true);
190   mRenderTaskForHorz.SetInputEnabled( false );
191   mRenderTaskForHorz.SetClearEnabled( true );
192   mRenderTaskForHorz.SetClearColor( mBackgroundColor );
193   mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
194   mRenderTaskForHorz.SetCameraActor( mCameraActor );
195
196   // use the internal buffer and perform a horizontal blur targeting the output buffer
197   mRenderTaskForVert = taskList.CreateTask();
198   mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
199   mRenderTaskForVert.SetSourceActor( mActorForHorz );
200   mRenderTaskForVert.SetExclusive(true);
201   mRenderTaskForVert.SetInputEnabled( false );
202   mRenderTaskForVert.SetClearEnabled( true );
203   mRenderTaskForVert.SetClearColor( mBackgroundColor );
204   mRenderTaskForVert.SetTargetFrameBuffer( mOutputImage );
205   mRenderTaskForVert.SetCameraActor( mCameraActor );
206 }
207
208 } // namespace Internal
209
210 } // namespace Toolkit
211
212 } // namespace Dali