2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "spread-filter.h"
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>
28 #include <dali-toolkit/internal/controls/control/control-renderers.h>
29 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
39 const char* const SPREAD_UNIFORM_NAME("uSpread");
40 const char* const TEX_SCALE_UNIFORM_NAME("uTexScale");
44 SpreadFilter::SpreadFilter()
50 SpreadFilter::~SpreadFilter()
54 void SpreadFilter::SetSpread(float spread)
59 void SpreadFilter::Enable()
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));
69 Renderer rendererForInput = CreateRenderer(BASIC_VERTEX_SOURCE, SHADER_SPREAD_FILTER_SHADER_FRAG);
70 SetRendererTexture(rendererForInput, mInputTexture);
71 mActorForInput.AddRenderer(rendererForInput);
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);
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);
89 mRootActor.Add(mActorForInput);
90 mRootActor.Add(mActorForHorz);
96 void SpreadFilter::Disable()
102 mRootActor.Remove(mCameraActor);
103 mCameraActor.Reset();
108 mRootActor.Remove(mActorForInput);
109 mActorForInput.Reset();
114 mRootActor.Remove(mActorForHorz);
115 mActorForHorz.Reset();
118 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
120 if(mRenderTaskForHorz)
122 taskList.RemoveTask(mRenderTaskForHorz);
124 if(mRenderTaskForVert)
126 taskList.RemoveTask(mRenderTaskForVert);
133 void SpreadFilter::Refresh()
135 if(mRenderTaskForHorz)
137 mRenderTaskForHorz.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
140 if(mRenderTaskForVert)
142 mRenderTaskForVert.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
146 void SpreadFilter::SetSize(const Vector2& size)
151 mActorForInput.SetProperty(Actor::Property::SIZE, mTargetSize);
155 mActorForHorz.SetProperty(Actor::Property::SIZE, mTargetSize);
159 void SpreadFilter::CreateRenderTasks()
161 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
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);
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);
186 } // namespace Internal
188 } // namespace Toolkit