mOnActivated = false;
}
+ void OnRefresh() override
+ {
+ }
+
public:
Dali::Toolkit::Control GetOwnerControl() const
{
application.SendNotification();
application.Render();
+ control.SetProperty(Actor::Property::SIZE, Vector2(200.0f, 200.0f));
+ tet_infoline("Size set");
+ application.SendNotification();
+ application.Render();
+
control.SetProperty(DevelControl::Property::OFFSCREEN_RENDERING, DevelControl::OffScreenRenderingType::NONE);
DALI_TEST_EQUALS(control.GetProperty(DevelControl::Property::OFFSCREEN_RENDERING).Get<int>(), (int)DevelControl::OffScreenRenderingType::NONE, TEST_LOCATION);
tet_infoline("Turn off offscreen rendering");
}
DevelControl::OffScreenRenderingType newType = static_cast<DevelControl::OffScreenRenderingType>(offScreenRenderingType);
- if(newType != mOffScreenRenderingType)
+ if(newType == DevelControl::OffScreenRenderingType::NONE)
{
- // update type
- mOffScreenRenderingType = newType;
-
- // update effect
if(mOffScreenRenderingImpl)
{
mOffScreenRenderingImpl->ClearOwnerControl();
mOffScreenRenderingImpl.reset();
}
- mOffScreenRenderingImpl = std::make_unique<OffScreenRenderingImpl>(mOffScreenRenderingType);
+ }
+ else if(mOffScreenRenderingType == DevelControl::OffScreenRenderingType::NONE)
+ {
+ mOffScreenRenderingImpl = std::make_unique<OffScreenRenderingImpl>(newType);
Dali::Toolkit::Control handle(mControlImpl.GetOwner());
mOffScreenRenderingImpl->SetOwnerControl(handle);
}
+ else
+ {
+ mOffScreenRenderingImpl->SetType(newType);
+ }
+ mOffScreenRenderingType = newType;
}
void Control::Impl::SetCornerRadius(Vector4 vector, Toolkit::Visual::Transform::Policy::Type policy)
mVerticalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight));
// Set blur
- CreateFrameBuffers(size, ImageDimensions(downsampledWidth, downsampledHeight));
+ CreateFrameBuffers(ImageDimensions(downsampledWidth, downsampledHeight));
CreateRenderTasks(GetSceneHolder(), ownerControl);
SetShaderConstants(downsampledWidth, downsampledHeight);
renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, Dali::Toolkit::DepthIndex::CONTENT);
}
ownerControl.AddRenderer(renderer);
- SetRendererTexture(renderer, mSourceFrameBuffer);
+ SetRendererTexture(renderer, mBlurredOutputFrameBuffer);
ownerControl.Add(mInternalRoot);
mInternalRoot.Unparent();
- mInputBackgroundFrameBuffer.Reset();
- mTemporaryFrameBuffer.Reset();
- mSourceFrameBuffer.Reset();
+ DestroyFrameBuffers();
+ DestroyRenderTasks();
+}
- auto sceneHolder = GetSceneHolder();
- if(DALI_LIKELY(sceneHolder))
+void BlurEffectImpl::OnRefresh()
+{
+ if(DALI_UNLIKELY(mSkipBlur))
{
- RenderTaskList taskList = sceneHolder.GetRenderTaskList();
- taskList.RemoveTask(mHorizontalBlurTask);
- taskList.RemoveTask(mVerticalBlurTask);
- taskList.RemoveTask(mSourceRenderTask);
+ return;
}
- mHorizontalBlurTask.Reset();
- mVerticalBlurTask.Reset();
- mSourceRenderTask.Reset();
+ mInputBackgroundFrameBuffer.Reset();
+ mTemporaryFrameBuffer.Reset();
+ mBlurredOutputFrameBuffer.Reset();
+
+ Vector2 size = GetTargetSize();
+ uint32_t downsampledWidth = std::max(static_cast<uint32_t>(size.width * mDownscaleFactor), 1u);
+ uint32_t downsampledHeight = std::max(static_cast<uint32_t>(size.height * mDownscaleFactor), 1u);
+
+ // Set size
+ mRenderDownsampledCamera.SetPerspectiveProjection(Size(downsampledWidth, downsampledHeight));
+ mHorizontalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight));
+ mVerticalBlurActor.SetProperty(Actor::Property::SIZE, Vector2(downsampledWidth, downsampledHeight));
+
+ CreateFrameBuffers(ImageDimensions(downsampledWidth, downsampledHeight));
+ SetShaderConstants(downsampledWidth, downsampledHeight);
+
+ mSourceRenderTask.SetFrameBuffer(mInputBackgroundFrameBuffer);
+ mHorizontalBlurTask.SetFrameBuffer(mTemporaryFrameBuffer);
+ mVerticalBlurTask.SetFrameBuffer(mBlurredOutputFrameBuffer);
}
-void BlurEffectImpl::CreateFrameBuffers(const Vector2 size, const ImageDimensions downsampledSize)
+void BlurEffectImpl::CreateFrameBuffers(const ImageDimensions downsampledSize)
{
uint32_t downsampledWidth = downsampledSize.GetWidth();
uint32_t downsampledHeight = downsampledSize.GetHeight();
mTemporaryFrameBuffer.AttachColorTexture(temporaryTexture);
// buffer to draw blurred output
- mSourceFrameBuffer = FrameBuffer::New(downsampledWidth, downsampledHeight, FrameBuffer::Attachment::DEPTH_STENCIL);
- Texture sourceTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, downsampledWidth, downsampledHeight);
- mSourceFrameBuffer.AttachColorTexture(sourceTexture);
+ mBlurredOutputFrameBuffer = FrameBuffer::New(downsampledWidth, downsampledHeight, FrameBuffer::Attachment::DEPTH_STENCIL);
+ Texture sourceTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, downsampledWidth, downsampledHeight);
+ mBlurredOutputFrameBuffer.AttachColorTexture(sourceTexture);
+}
+
+void BlurEffectImpl::DestroyFrameBuffers()
+{
+ mInputBackgroundFrameBuffer.Reset();
+ mTemporaryFrameBuffer.Reset();
+ mBlurredOutputFrameBuffer.Reset();
}
void BlurEffectImpl::CreateRenderTasks(Integration::SceneHolder sceneHolder, const Toolkit::Control sourceControl)
mVerticalBlurTask.SetExclusive(true);
mVerticalBlurTask.SetInputEnabled(false);
mVerticalBlurTask.SetCameraActor(mRenderDownsampledCamera);
- mVerticalBlurTask.SetFrameBuffer(mSourceFrameBuffer);
+ mVerticalBlurTask.SetFrameBuffer(mBlurredOutputFrameBuffer);
// Clear sourceTexture as Transparent.
mVerticalBlurTask.SetClearEnabled(true);
mVerticalBlurTask.SetClearColor(Color::TRANSPARENT);
}
+void BlurEffectImpl::DestroyRenderTasks()
+{
+ auto sceneHolder = GetSceneHolder();
+ if(DALI_LIKELY(sceneHolder))
+ {
+ RenderTaskList taskList = sceneHolder.GetRenderTaskList();
+ taskList.RemoveTask(mHorizontalBlurTask);
+ taskList.RemoveTask(mVerticalBlurTask);
+ taskList.RemoveTask(mSourceRenderTask);
+ }
+
+ mHorizontalBlurTask.Reset();
+ mVerticalBlurTask.Reset();
+ mSourceRenderTask.Reset();
+}
+
void BlurEffectImpl::ApplyRenderTaskSourceActor(RenderTask sourceRenderTask, const Toolkit::Control sourceControl)
{
if(DALI_UNLIKELY(!sourceRenderTask || !sourceControl))
*/
void OnDeactivate() override;
+ /**
+ * @brief Redraw effect without deactivation
+ */
+ void OnRefresh() override;
+
private:
// Inner functions
/**
* @brief Sets frame buffers to draw blurred output.
- * @param[in] size Full size of input.
* @param[in] downsampledSize Downsampled size for performance.
*/
- void CreateFrameBuffers(const Vector2 size, const ImageDimensions downsampledSize);
+ void CreateFrameBuffers(const ImageDimensions downsampledSize);
+
+ /**
+ * @brief Removes and destroys local frame buffers.
+ */
+ void DestroyFrameBuffers();
/**
* @brief Sets blur render tasks.
*/
void CreateRenderTasks(Integration::SceneHolder sceneHolder, const Toolkit::Control sourceControl);
+ /**
+ * @brief Removes and destroys local render tasks.
+ */
+ void DestroyRenderTasks();
+
/**
* @brief Apply render tasks source actor, and some other options.
* @param[in] renderTask Target render task to change source actor and exclusiveness
Actor mVerticalBlurActor;
RenderTask mVerticalBlurTask;
- FrameBuffer mSourceFrameBuffer; // Output. Blurred background texture for mOwnerControl and mRenderer.
+ FrameBuffer mBlurredOutputFrameBuffer;
RenderTask mSourceRenderTask;
// Variables
Initialize();
}
+void OffScreenRenderingImpl::SetType(DevelControl::OffScreenRenderingType type)
+{
+ mType = type;
+
+ if(mRenderTask)
+ {
+ if(mType == DevelControl::OffScreenRenderingType::REFRESH_ALWAYS)
+ {
+ mRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
+ }
+ else if(mType == DevelControl::OffScreenRenderingType::REFRESH_ONCE)
+ {
+ mRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
+ }
+ }
+}
+
RenderEffectImplPtr OffScreenRenderingImpl::Clone() const
{
DALI_LOG_ERROR("Cloning offscreen rendering is not allowed.\n");
return;
}
- // Create resources
+ CreateFrameBuffer();
+ CreateRenderTask();
+ SetType(mType);
+
+ Renderer renderer = GetTargetRenderer();
+ SetRendererTexture(renderer, mFrameBuffer);
+
Toolkit::Control control = GetOwnerControl();
- const Size size = GetTargetSize();
+ control.GetImplementation().SetCacheRenderer(renderer);
+ control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::FORWARD);
+}
+
+void OffScreenRenderingImpl::OnDeactivate()
+{
+ Toolkit::Control control = GetOwnerControl();
+ if(DALI_LIKELY(control))
+ {
+ control.GetImplementation().RemoveCacheRenderer();
+ control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::NONE);
+ }
+
+ DestroyFrameBuffer();
+ DestroyRenderTask();
+}
+
+void OffScreenRenderingImpl::OnRefresh()
+{
+ DestroyFrameBuffer();
+
+ CreateFrameBuffer();
+ mRenderTask.SetFrameBuffer(mFrameBuffer);
+}
+
+void OffScreenRenderingImpl::CreateFrameBuffer()
+{
+ const Size size = GetTargetSize();
mFrameBuffer = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, size.width, size.height);
mFrameBuffer.AttachColorTexture(texture);
+}
+
+void OffScreenRenderingImpl::DestroyFrameBuffer()
+{
+ mFrameBuffer.Reset();
+}
+void OffScreenRenderingImpl::CreateRenderTask()
+{
+ Toolkit::Control control = GetOwnerControl();
Integration::SceneHolder sceneHolder = GetSceneHolder();
RenderTaskList taskList = sceneHolder.GetRenderTaskList();
- mRenderTask = taskList.CreateTask();
+
+ mRenderTask = taskList.CreateTask();
mRenderTask.SetSourceActor(control);
mRenderTask.SetCameraActor(GetCameraActor());
mRenderTask.SetExclusive(true);
mRenderTask.SetFrameBuffer(mFrameBuffer);
mRenderTask.SetClearEnabled(true);
mRenderTask.SetClearColor(sceneHolder.GetBackgroundColor());
-
- Renderer renderer = GetTargetRenderer();
- SetRendererTexture(renderer, mFrameBuffer);
-
- control.GetImplementation().SetCacheRenderer(renderer);
- control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::FORWARD);
-
- // Set refresh rate
- if(mType == DevelControl::OffScreenRenderingType::REFRESH_ALWAYS)
- {
- mRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
- }
- else if(mType == DevelControl::OffScreenRenderingType::REFRESH_ONCE)
- {
- mRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
- }
}
-void OffScreenRenderingImpl::OnDeactivate()
+void OffScreenRenderingImpl::DestroyRenderTask()
{
- Toolkit::Control control = GetOwnerControl();
- if(DALI_LIKELY(control))
- {
- control.GetImplementation().RemoveCacheRenderer();
- control.GetImplementation().SetOffScreenRenderableType(OffScreenRenderable::Type::NONE);
- }
-
auto sceneHolder = GetSceneHolder();
if(DALI_LIKELY(sceneHolder))
{
taskList.RemoveTask(mRenderTask);
}
- mFrameBuffer.Reset();
mRenderTask.Reset();
}
{
namespace Internal
{
+/**
+ * @brief This effect renders all children(including self) at off screen framebuffer.
+ * This effect is handleless, so initiate an instance through setting DevelControl::Property::OFFSCREEN_RENDERING
+ * The instance will be saved internally, thus outer modification is impossible.
+ */
class OffScreenRenderingImpl : public RenderEffectImpl
{
public:
+ /**
+ * @brief Constructor
+ * @param[in] type Defines whether effect is enabled or not, and its refresh rate
+ */
OffScreenRenderingImpl(DevelControl::OffScreenRenderingType type);
- RenderEffectImplPtr Clone() const override;
+ /**
+ * @brief Set OffScreenRenderingType explicitly
+ * @param[in] type Defines whether effect is enabled or not, and its refresh rate
+ */
+ void SetType(DevelControl::OffScreenRenderingType type);
+
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::Clone
+ RenderEffectImplPtr Clone() const override;
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::GetOffScreenRenderableType
OffScreenRenderable::Type GetOffScreenRenderableType() override;
- void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override;
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::GetOffScreenRenderTasks
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override;
protected:
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::OnInitialize
void OnInitialize() override;
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::OnActivate
void OnActivate() override;
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::OnDeactivate
void OnDeactivate() override;
+ // @copydoc Dali::Toolkit::Internal::RenderEffectImpl::OnRefresh
+ void OnRefresh() override;
+
+private:
+ /**
+ * @brief Initializes off screen buffer to draw subtree
+ */
+ void CreateFrameBuffer();
+ /**
+ * @brief
+ */
+ void DestroyFrameBuffer();
+
+ /**
+ * @brief Initializes render task for offscreen rendering
+ */
+ void CreateRenderTask();
+ /**
+ * @brief
+ */
+ void DestroyRenderTask();
private:
RenderTask mRenderTask;
void RenderEffectImpl::Initialize()
{
- mCamera = CameraActor::New();
- mCamera.SetInvertYAxis(true);
- mCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
- mCamera.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
- mCamera.SetType(Dali::Camera::FREE_LOOK);
+ if(!mCamera)
+ {
+ mCamera = CameraActor::New();
+ mCamera.SetInvertYAxis(true);
+ mCamera.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ mCamera.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ mCamera.SetType(Dali::Camera::FREE_LOOK);
+ }
+
+ if(!mRenderer)
+ {
+ mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG);
+ mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); // Always use pre-multiply alpha
+
+ Shader shader = mRenderer.GetShader();
+ shader.RegisterProperty("uCornerRadius", Vector4::ZERO);
+ shader.RegisterProperty("uCornerSquareness", Vector4::ZERO);
+ shader.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(1.0f));
+ }
OnInitialize();
}
}
mPlacementSceneHolder = sceneHolder;
- if(!mRenderer)
- {
- mRenderer = CreateRenderer(SHADER_RENDER_EFFECT_VERT, SHADER_RENDER_EFFECT_FRAG);
- mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true); // Always use pre-multiply alpha
-
- Shader shader = mRenderer.GetShader();
- shader.RegisterProperty("uCornerRadius", Vector4::ZERO);
- shader.RegisterProperty("uCornerSquareness", Vector4::ZERO);
- shader.RegisterProperty("uCornerRadiusPolicy", static_cast<float>(1.0f));
- }
-
Vector2 size = GetTargetSize();
if(size != Vector2::ZERO)
{
if(mTargetSize != targetSize && IsActivated())
{
UpdateTargetSize();
- Deactivate();
- Activate();
+ mCamera.SetPerspectiveProjection(GetTargetSize());
+ OnRefresh();
}
}
}
*/
virtual void OnDeactivate() = 0;
+ /**
+ * @brief Redraws effect without deactivation
+ * @note Assumes activation
+ */
+ virtual void OnRefresh() = 0;
+
private:
/**
* @brief Activates effect on ownerControl