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