Convert more shaders in dali-toolkit and dali-scene-loader to use shader compilation...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / filters / spread-filter.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 "spread-filter.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/constraints.h>
23 #include <dali/devel-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 #include <dali-toolkit/internal/controls/control/control-renderers.h>
29 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
30
31 namespace Dali
32 {
33
34 namespace Toolkit
35 {
36
37 namespace Internal
38 {
39
40 namespace
41 {
42
43 const char* const SPREAD_UNIFORM_NAME( "uSpread" );
44 const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" );
45
46 } // namespace
47
48
49 SpreadFilter::SpreadFilter()
50 : ImageFilter(),
51   mSpread(2)
52 {
53 }
54
55 SpreadFilter::~SpreadFilter()
56 {
57 }
58
59 void SpreadFilter::SetSpread( float spread )
60 {
61   mSpread = spread;
62 }
63
64 void SpreadFilter::Enable()
65 {
66   // create actor to render input with applied emboss effect
67   mActorForInput = Actor::New();
68   mActorForInput.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
69   mActorForInput.SetProperty( Actor::Property::SIZE, mTargetSize);
70   // register properties as shader uniforms
71   mActorForInput.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
72   mActorForInput.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 1.0f / mTargetSize.width, 0.0f ) );
73
74   Renderer rendererForInput = CreateRenderer( BASIC_VERTEX_SOURCE, SHADER_SPREAD_FILTER_SHADER_FRAG );
75   SetRendererTexture( rendererForInput, mInputTexture );
76   mActorForInput.AddRenderer( rendererForInput );
77
78   // create internal offscreen for result of horizontal pass
79   mFrameBufferForHorz = FrameBuffer::New( mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE );
80   Texture textureForHorz = Texture::New( TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height) );
81   mFrameBufferForHorz.AttachColorTexture( textureForHorz );
82
83   // create an actor to render mImageForHorz for vertical blur pass
84   mActorForHorz = Actor::New();
85   mActorForHorz.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
86   mActorForHorz.SetProperty( Actor::Property::SIZE, mTargetSize);
87   // register properties as shader uniforms
88   mActorForHorz.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
89   mActorForHorz.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 0.0f, 1.0f / mTargetSize.height ) );
90   Renderer rendererForHorz = CreateRenderer( BASIC_VERTEX_SOURCE, SHADER_SPREAD_FILTER_SHADER_FRAG );
91   SetRendererTexture( rendererForHorz, textureForHorz );
92   mActorForHorz.AddRenderer( rendererForHorz );
93
94   mRootActor.Add( mActorForInput );
95   mRootActor.Add( mActorForHorz );
96
97   SetupCamera();
98   CreateRenderTasks();
99 }
100
101 void SpreadFilter::Disable()
102 {
103   if( mRootActor )
104   {
105     if( mCameraActor )
106     {
107       mRootActor.Remove( mCameraActor );
108       mCameraActor.Reset();
109     }
110
111     if( mActorForInput )
112     {
113       mRootActor.Remove( mActorForInput );
114       mActorForInput.Reset();
115     }
116
117     if( mActorForHorz )
118     {
119       mRootActor.Remove( mActorForHorz );
120       mActorForHorz.Reset();
121     }
122
123     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
124
125     if( mRenderTaskForHorz )
126     {
127       taskList.RemoveTask(mRenderTaskForHorz);
128     }
129     if( mRenderTaskForVert )
130     {
131       taskList.RemoveTask(mRenderTaskForVert);
132     }
133
134     mRootActor.Reset();
135   }
136 }
137
138 void SpreadFilter::Refresh()
139 {
140   if( mRenderTaskForHorz )
141   {
142     mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
143   }
144
145   if( mRenderTaskForVert )
146   {
147     mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
148   }
149 }
150
151 void SpreadFilter::SetSize( const Vector2& size )
152 {
153   mTargetSize = size;
154   if( mActorForInput )
155   {
156     mActorForInput.SetProperty( Actor::Property::SIZE, mTargetSize);
157   }
158   if( mActorForHorz )
159   {
160     mActorForHorz.SetProperty( Actor::Property::SIZE, mTargetSize);
161   }
162 }
163
164 void SpreadFilter::CreateRenderTasks()
165 {
166   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
167
168   // perform a horizontal blur targeting the internal buffer
169   mRenderTaskForHorz = taskList.CreateTask();
170   mRenderTaskForHorz.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
171   mRenderTaskForHorz.SetSourceActor( mActorForInput );
172   mRenderTaskForHorz.SetExclusive(true);
173   mRenderTaskForHorz.SetInputEnabled( false );
174   mRenderTaskForHorz.SetClearEnabled( true );
175   mRenderTaskForHorz.SetClearColor( mBackgroundColor );
176   mRenderTaskForHorz.SetFrameBuffer( mFrameBufferForHorz );
177   mRenderTaskForHorz.SetCameraActor( mCameraActor );
178
179   // use the internal buffer and perform a horizontal blur targeting the output buffer
180   mRenderTaskForVert = taskList.CreateTask();
181   mRenderTaskForVert.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
182   mRenderTaskForVert.SetSourceActor( mActorForHorz );
183   mRenderTaskForVert.SetExclusive(true);
184   mRenderTaskForVert.SetInputEnabled( false );
185   mRenderTaskForVert.SetClearEnabled( true );
186   mRenderTaskForVert.SetClearColor( mBackgroundColor );
187   mRenderTaskForVert.SetFrameBuffer( mOutputFrameBuffer );
188   mRenderTaskForVert.SetCameraActor( mCameraActor );
189 }
190
191 } // namespace Internal
192
193 } // namespace Toolkit
194
195 } // namespace Dali