/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "effects-view-impl.h"
// EXTERNAL INCLUDES
+#include <dali/devel-api/common/stage.h>
#include <dali/public-api/animation/constraint.h>
#include <dali/public-api/animation/constraints.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/object/property.h>
#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/public-api/rendering/renderer.h>
// INTERNAL INCLUDES
-#include "../../filters/blur-two-pass-filter.h"
-#include "../../filters/emboss-filter.h"
-#include "../../filters/spread-filter.h"
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/control/control-renderers.h>
+#include <dali-toolkit/internal/filters/blur-two-pass-filter.h>
+#include <dali-toolkit/internal/filters/emboss-filter.h>
+#include <dali-toolkit/internal/filters/spread-filter.h>
+#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
namespace Dali
{
-
namespace Toolkit
{
-
namespace Internal
{
-
namespace
{
-
Dali::BaseHandle Create()
{
- return Toolkit::EffectsView::New();
+ return EffectsView::New();
}
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::EffectsView, Toolkit::Control, Create )
+DALI_TYPE_REGISTRATION_BEGIN(Toolkit::EffectsView, Toolkit::Control, Create)
+DALI_PROPERTY_REGISTRATION(Toolkit, EffectsView, "effectSize", INTEGER, EFFECT_SIZE)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, EffectsView, "effectOffset", VECTOR3, EFFECT_OFFSET)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, EffectsView, "effectColor", Color::WHITE, EFFECT_COLOR)
DALI_TYPE_REGISTRATION_END()
const Pixel::Format EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT = Pixel::RGBA8888;
-const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
-const Vector4 EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR( 1.0f, 1.0f, 1.0f, 0.0 );
+const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
+const Vector4 EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR(0.0f, 0.0f, 0.0f, 0.0);
const bool EFFECTS_VIEW_REFRESH_ON_DEMAND(false);
-// Custom properties
-const char* const EFFECT_SIZE_PROPERTY_NAME = "EffectSize";
-const char* const EFFECT_STRENGTH_PROPERTY_NAME = "EffectStrength";
-const char* const EFFECT_OFFSET_PROPERTY_NAME = "EffectOffset";
-const char* const EFFECT_COLOR_PROPERTY_NAME = "EffectColor";
-
-const float EFFECT_SIZE_DEFAULT( 1.0f );
-const float EFFECT_STRENGTH_DEFAULT( 0.5f );
-const Vector3 EFFECT_OFFSET_DEFAULT( 0.0f, 0.0f, 0.0f );
-const Vector4 EFFECT_COLOR_DEFAULT( Color::WHITE );
-
-const char* const EFFECTS_VIEW_FRAGMENT_SOURCE =
- "void main()\n"
- "{\n"
- " gl_FragColor = uColor;\n"
- " gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n"
- "}\n";
-
-const float BLUR_KERNEL0[] = { 12.0f/16.0f,
- 2.0f/16.0f, 2.0f/16.0f };
-
-const float BLUR_KERNEL1[] = { 8.0f/16.0f,
- 4.0f/16.0f, 4.0f/16.0f };
-
-const float BLUR_KERNEL2[] = { 6.0f/16.0f,
- 2.5f/16.0f, 2.5f/16.0f,
- 1.5f/16.0f, 1.5f/16.0f,
- 1.0f/16.0f, 1.0f/16.0f };
-
-const float BLUR_KERNEL3[] = { 4.0f/16.0f,
- 3.0f/16.0f, 2.0f/16.0f,
- 2.0f/16.0f, 2.0f/16.0f,
- 1.0f/16.0f, 1.0f/16.0f };
-
-const float BLUR_KERNEL4[] = { 3.0f/16.0f,
- 2.5f/16.0f, 2.5f/16.0f,
- 1.75f/16.0f, 1.75f/16.0f,
- 1.25f/16.0f, 1.25f/16.0f,
- 1.0f/16.0f, 1.0f/16.0f };
-
+// clang-format off
+const float BLUR_KERNEL0[] = {12.0f/16.0f,
+ 2.0f/16.0f, 2.0f/16.0f};
+
+const float BLUR_KERNEL1[] = {8.0f/16.0f,
+ 4.0f/16.0f, 4.0f/16.0f };
+
+const float BLUR_KERNEL2[] = {6.0f/16.0f,
+ 2.5f/16.0f, 2.5f/16.0f,
+ 1.5f/16.0f, 1.5f/16.0f,
+ 1.0f/16.0f, 1.0f/16.0f};
+
+const float BLUR_KERNEL3[] = {4.0f/16.0f,
+ 3.0f/16.0f, 2.0f/16.0f,
+ 2.0f/16.0f, 2.0f/16.0f,
+ 1.0f/16.0f, 1.0f/16.0f};
+
+const float BLUR_KERNEL4[] = {3.0f/16.0f,
+ 2.5f/16.0f, 2.5f/16.0f,
+ 1.75f/16.0f, 1.75f/16.0f,
+ 1.25f/16.0f, 1.25f/16.0f,
+ 1.0f/16.0f, 1.0f/16.0f};
+// clang-format on
} // namespace
Toolkit::EffectsView EffectsView::New()
{
EffectsView* effectsView = new EffectsView;
- Toolkit::EffectsView handle = Toolkit::EffectsView( *effectsView );
+ Toolkit::EffectsView handle = Toolkit::EffectsView(*effectsView);
// Second-phase init of the implementation
// This can only be done after the CustomActor connection has been made...
}
EffectsView::EffectsView()
-: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
- mEffectType( Toolkit::EffectsView::INVALID_TYPE ),
- mPixelFormat( EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT ),
- mSpread(0.0f),
- mBackgroundColor( EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR ),
- mTargetSize( Vector2::ZERO ),
- mLastSize( Vector2::ZERO ),
- mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND),
- mEffectSizePropertyIndex(Property::INVALID_INDEX),
- mEffectStrengthPropertyIndex(Property::INVALID_INDEX),
- mEffectOffsetPropertyIndex(Property::INVALID_INDEX),
- mEffectColorPropertyIndex(Property::INVALID_INDEX)
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+ mChildrenRoot(Actor::New()),
+ mBackgroundColor(EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR),
+ mTargetSize(Vector2::ZERO),
+ mLastSize(Vector2::ZERO),
+ mEffectSize(0),
+ mEffectType(Toolkit::EffectsView::INVALID_TYPE),
+ mPixelFormat(EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT),
+ mEnabled(false),
+ mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND)
{
}
RemoveFilters();
}
-void EffectsView::SetType( Toolkit::EffectsView::EffectType type )
+void EffectsView::SetType(Toolkit::EffectsView::EffectType type)
{
- if( mEffectType != type )
+ if(mEffectType != type)
{
- mEffectType = type;
-
RemoveFilters();
- switch( mEffectType )
+ Actor self = Self();
+
+ switch(type)
{
case Toolkit::EffectsView::DROP_SHADOW:
{
- mFilters.push_back( new SpreadFilter );
- mFilters.push_back( new BlurTwoPassFilter );
+ mFilters.PushBack(new SpreadFilter);
+ mFilters.PushBack(new BlurTwoPassFilter);
break;
}
case Toolkit::EffectsView::EMBOSS:
{
- mFilters.push_back( new SpreadFilter );
- mFilters.push_back( new EmbossFilter );
- mFilters.push_back( new BlurTwoPassFilter );
- mActorPostFilter.RemoveShaderEffect();
+ mFilters.PushBack(new SpreadFilter);
+ mFilters.PushBack(new EmbossFilter);
+ mFilters.PushBack(new BlurTwoPassFilter);
break;
}
default:
break;
}
}
+
+ mEffectType = type;
}
}
// make sure resources are allocated and start the render tasks processing
AllocateResources();
CreateRenderTasks();
+ mEnabled = true;
}
void EffectsView::Disable()
{
// stop render tasks processing
- // Note: render target resources are automatically freed since we set the Image::Unused flag
RemoveRenderTasks();
+ mLastSize = Vector2::ZERO; // Ensure resources are reallocated on subsequent enable
+ mEnabled = false;
}
void EffectsView::Refresh()
RefreshRenderTasks();
}
-void EffectsView::SetRefreshOnDemand( bool onDemand )
+void EffectsView::SetRefreshOnDemand(bool onDemand)
{
mRefreshOnDemand = onDemand;
RefreshRenderTasks();
}
-void EffectsView::SetPixelFormat( Pixel::Format pixelFormat )
+void EffectsView::SetPixelFormat(Pixel::Format pixelFormat)
{
mPixelFormat = pixelFormat;
}
-void EffectsView::SetOutputImage( FrameBufferImage image )
+void EffectsView::SetBackgroundColor(const Vector4& color)
{
- CustomActor self = Self();
-
- if( mImageForResult != image )
- {
- if( !image )
- {
- if( mImageForResult )
- {
- self.Remove( mActorForResult );
- mActorForResult.Reset();
-
- self.Add( mActorPostFilter );
- self.Add( mActorForChildren );
- }
- }
- else
- {
- if( mImageForResult )
- {
- self.Remove( mActorForResult );
- }
- mActorForResult = Actor::New();
- mActorForResult.SetParentOrigin( ParentOrigin::CENTER );
- mActorForResult.SetSize( mTargetSize );
- mActorForResult.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
- Self().Add( mActorForResult );
- mActorForResult.Add( mActorPostFilter );
- mActorForResult.Add( mActorForChildren );
- }
- mImageForResult = image;
- }
+ mBackgroundColor = color;
}
-FrameBufferImage EffectsView::GetOutputImage()
+Vector4 EffectsView::GetBackgroundColor() const
{
- return mImageForResult;
+ return mBackgroundColor;
}
-Property::Index EffectsView::GetEffectSizePropertyIndex() const
+void EffectsView::SetEffectSize(int effectSize)
{
- return mEffectSizePropertyIndex;
-}
+ mEffectSize = effectSize;
-Property::Index EffectsView::GetEffectStrengthPropertyIndex() const
-{
- return mEffectStrengthPropertyIndex;
-}
+ if(mEnabled)
+ {
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
+ {
+ mFilters[i]->Disable();
+ }
-Property::Index EffectsView::GetEffectOffsetPropertyIndex() const
-{
- return mEffectOffsetPropertyIndex;
+ SetupFilters();
+
+ for(size_t i = 0; i < numFilters; ++i)
+ {
+ mFilters[i]->Enable();
+ }
+ }
}
-Property::Index EffectsView::GetEffectColorPropertyIndex() const
+int EffectsView::GetEffectSize()
{
- return mEffectColorPropertyIndex;
+ return mEffectSize;
}
-void EffectsView::SetupProperties()
+// From Control
+void EffectsView::OnInitialize()
{
CustomActor self = Self();
+ mChildrenRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ self.Add(mChildrenRoot);
- // Register a property that the user can control the drop shadow offset
- mEffectSizePropertyIndex = self.RegisterProperty(EFFECT_SIZE_PROPERTY_NAME, EFFECT_SIZE_DEFAULT, Property::READ_WRITE);
- mEffectStrengthPropertyIndex = self.RegisterProperty(EFFECT_STRENGTH_PROPERTY_NAME, EFFECT_STRENGTH_DEFAULT, Property::READ_WRITE);
- mEffectOffsetPropertyIndex = self.RegisterProperty(EFFECT_OFFSET_PROPERTY_NAME, EFFECT_OFFSET_DEFAULT);
- mEffectColorPropertyIndex = self.RegisterProperty(EFFECT_COLOR_PROPERTY_NAME, EFFECT_COLOR_DEFAULT);
-
- Constraint positionConstraint = Constraint::New<Vector3>( mActorPostFilter, Actor::Property::POSITION, EqualToConstraint() );
- positionConstraint.AddSource( Source( self, mEffectOffsetPropertyIndex ) );
- positionConstraint.Apply();
-
- Constraint colorConstraint = Constraint::New<Vector4>( mActorPostFilter, Actor::Property::COLOR, EqualToConstraint() );
- colorConstraint.AddSource( Source( self, mEffectColorPropertyIndex ) );
- colorConstraint.Apply();
+ DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
+ return std::unique_ptr<Dali::Accessibility::Accessible>(
+ new DevelControl::AccessibleImpl(actor, Dali::Accessibility::Role::FILLER));
+ });
}
-void EffectsView::SetBackgroundColor( const Vector4& color )
+void EffectsView::OnSizeSet(const Vector3& targetSize)
{
- mBackgroundColor = color;
-}
+ mTargetSize = Vector2(targetSize);
-Vector4 EffectsView::GetBackgroundColor() const
-{
- return mBackgroundColor;
+ // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
+ if(mEnabled)
+ {
+ if(mLastSize != Vector2::ZERO)
+ {
+ Disable();
+ }
+ Enable();
+ }
+
+ mChildrenRoot.SetProperty(Actor::Property::SIZE, targetSize);
+
+ Control::OnSizeSet(targetSize);
}
-// From Control
-void EffectsView::OnInitialize()
+void EffectsView::OnSceneConnection(int depth)
{
- //////////////////////////////////////////////////////
- // Create cameras
- mCameraForChildren = CameraActor::New();
- mCameraForChildren.SetParentOrigin(ParentOrigin::CENTER);
+ Actor self(Self());
- mActorForChildren = ImageActor::New();
- mActorForChildren.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
- mActorForChildren.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
+ // Create renderers
+ mRendererPostFilter = CreateRenderer(SHADER_EFFECTS_VIEW_VERT,
+ SHADER_EFFECTS_VIEW_FRAG);
+ mRendererPostFilter.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT);
+ self.AddRenderer(mRendererPostFilter);
- mActorPostFilter = ImageActor::New();
- mActorPostFilter.SetParentOrigin( ParentOrigin::CENTER );
- mActorPostFilter.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
- mActorPostFilter.SetShaderEffect( ShaderEffect::New( "", EFFECTS_VIEW_FRAGMENT_SOURCE ) );
+ mRendererForChildren = CreateRenderer(BASIC_VERTEX_SOURCE, BASIC_FRAGMENT_SOURCE);
+ mRendererForChildren.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, DepthIndex::CONTENT + 1);
+ self.AddRenderer(mRendererForChildren);
- // Connect to actor tree
- Self().Add( mActorPostFilter );
- Self().Add( mActorForChildren );
- Self().Add( mCameraForChildren );
+ Enable();
- SetupProperties();
+ Control::OnSceneConnection(depth);
}
-void EffectsView::OnControlSizeSet(const Vector3& targetSize)
+void EffectsView::OnSceneDisconnection()
{
- mTargetSize = Vector2(targetSize);
+ Actor self(Self());
- // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
- if(Self().OnStage())
- {
- AllocateResources();
- }
+ Disable();
- if( mActorForResult )
- {
- mActorForResult.SetSize( targetSize );
- }
- if( mActorForChildren )
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
{
- mActorForChildren.SetSize( targetSize );
- }
- if( mActorPostFilter )
- {
- mActorPostFilter.SetSize( targetSize );
+ mFilters[i]->Disable();
}
- // Children render camera must move when EffectsView object is resized.
- // This is since we cannot change render target size - so we need to remap the child actors' rendering
- // accordingly so they still exactly fill the render target.
- // Note that this means the effective resolution of the child render changes as the EffectsView object
- // changes size, this is the trade off for not being able to modify render target size
- // Change camera z position based on EffectsView actor height
- if( mCameraForChildren )
- {
- const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) );
- mCameraForChildren.SetZ( targetSize.height * cameraPosScale );
- }
+ // Remove renderers
+ self.RemoveRenderer(mRendererForChildren);
+ mRendererForChildren.Reset();
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
- {
- mFilters[i]->SetSize( mTargetSize );
- }
+ self.RemoveRenderer(mRendererPostFilter);
+ mRendererPostFilter.Reset();
+ Control::OnSceneDisconnection();
}
-void EffectsView::OnStageDisconnection()
+void EffectsView::OnChildAdd(Actor& child)
{
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
+ if(child != mChildrenRoot && child != mCameraForChildren)
{
- mFilters[i]->Disable();
+ mChildrenRoot.Add(child);
}
+
+ Control::OnChildAdd(child);
+}
+
+void EffectsView::OnChildRemove(Actor& child)
+{
+ mChildrenRoot.Remove(child);
+
+ Control::OnChildRemove(child);
}
void EffectsView::SetupFilters()
{
- int effectSize = static_cast< int >( Self().GetProperty( mEffectSizePropertyIndex ).Get<float>() );
- switch( mEffectType )
+ switch(mEffectType)
{
case Toolkit::EffectsView::DROP_SHADOW:
{
- SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] );
- spreadFilter->SetInputImage( mImageForChildren );
- spreadFilter->SetOutputImage( mImagePostFilter );
- spreadFilter->SetRootActor( Self() );
- spreadFilter->SetBackgroundColor( mBackgroundColor );
- spreadFilter->SetPixelFormat( mPixelFormat );
- spreadFilter->SetSize( mTargetSize );
- spreadFilter->SetSpread( effectSize );
-
- BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[1] );
- blurFilter->SetInputImage( mImagePostFilter );
- blurFilter->SetOutputImage( mImagePostFilter );
- blurFilter->SetRootActor( Self() );
- blurFilter->SetBackgroundColor( mBackgroundColor );
- blurFilter->SetPixelFormat( mPixelFormat );
- blurFilter->SetSize( mTargetSize );
+ SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
+ spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
+ spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
+ spreadFilter->SetRootActor(mChildrenRoot);
+ spreadFilter->SetBackgroundColor(mBackgroundColor);
+ spreadFilter->SetPixelFormat(mPixelFormat);
+ spreadFilter->SetSize(mTargetSize);
+ spreadFilter->SetSpread(mEffectSize);
+
+ BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[1]);
+ blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
+ blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
+ blurFilter->SetRootActor(mChildrenRoot);
+ blurFilter->SetBackgroundColor(mBackgroundColor);
+ blurFilter->SetPixelFormat(mPixelFormat);
+ blurFilter->SetSize(mTargetSize);
const float* kernel(NULL);
- size_t kernelSize(0);
- switch( effectSize )
+ size_t kernelSize(0);
+ switch(mEffectSize)
{
- case 4: { kernel = BLUR_KERNEL4; kernelSize = sizeof(BLUR_KERNEL4)/sizeof(BLUR_KERNEL4[0]); break; }
- case 3: { kernel = BLUR_KERNEL3; kernelSize = sizeof(BLUR_KERNEL3)/sizeof(BLUR_KERNEL3[0]); break; }
- case 2: { kernel = BLUR_KERNEL2; kernelSize = sizeof(BLUR_KERNEL2)/sizeof(BLUR_KERNEL2[0]); break; }
- case 1: { kernel = BLUR_KERNEL1; kernelSize = sizeof(BLUR_KERNEL1)/sizeof(BLUR_KERNEL1[0]); break; }
+ case 4:
+ {
+ kernel = BLUR_KERNEL4;
+ kernelSize = sizeof(BLUR_KERNEL4) / sizeof(BLUR_KERNEL4[0]);
+ break;
+ }
+ case 3:
+ {
+ kernel = BLUR_KERNEL3;
+ kernelSize = sizeof(BLUR_KERNEL3) / sizeof(BLUR_KERNEL3[0]);
+ break;
+ }
+ case 2:
+ {
+ kernel = BLUR_KERNEL2;
+ kernelSize = sizeof(BLUR_KERNEL2) / sizeof(BLUR_KERNEL2[0]);
+ break;
+ }
+ case 1:
+ {
+ kernel = BLUR_KERNEL1;
+ kernelSize = sizeof(BLUR_KERNEL1) / sizeof(BLUR_KERNEL1[0]);
+ break;
+ }
case 0:
- default: { kernel = BLUR_KERNEL0; kernelSize = sizeof(BLUR_KERNEL0)/sizeof(BLUR_KERNEL0[0]); break; }
+ default:
+ {
+ kernel = BLUR_KERNEL0;
+ kernelSize = sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]);
+ break;
+ }
}
- blurFilter->CreateKernel( kernel, kernelSize );
+ blurFilter->CreateKernel(kernel, kernelSize);
break;
}
case Toolkit::EffectsView::EMBOSS:
{
- SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] );
- spreadFilter->SetInputImage( mImageForChildren );
- spreadFilter->SetOutputImage( mImagePostFilter );
- spreadFilter->SetRootActor( Self() );
- spreadFilter->SetBackgroundColor( mBackgroundColor );
- spreadFilter->SetPixelFormat( Pixel::RGBA8888 );
- spreadFilter->SetSize( mTargetSize );
- spreadFilter->SetSpread( effectSize );
-
- EmbossFilter* embossFilter = static_cast< EmbossFilter* >( mFilters[1] );
- embossFilter->SetInputImage( mImagePostFilter );
- embossFilter->SetOutputImage( mImagePostFilter );
- embossFilter->SetRootActor( Self() );
- embossFilter->SetBackgroundColor( mBackgroundColor );
- embossFilter->SetPixelFormat( Pixel::RGBA8888 );
- embossFilter->SetSize( mTargetSize );
-
- BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[2] );
- blurFilter->SetInputImage( mImagePostFilter );
- blurFilter->SetOutputImage( mImagePostFilter );
- blurFilter->SetRootActor( Self() );
- blurFilter->SetBackgroundColor( Vector4( 0.5f, 0.5f, 0.5f, 0.0 ) );
- blurFilter->SetPixelFormat( Pixel::RGBA8888 );
- blurFilter->SetSize( mTargetSize );
- blurFilter->CreateKernel( BLUR_KERNEL0, sizeof(BLUR_KERNEL0)/sizeof(BLUR_KERNEL0[0]) );
+ SpreadFilter* spreadFilter = static_cast<SpreadFilter*>(mFilters[0]);
+ spreadFilter->SetInputTexture(mFrameBufferForChildren.GetColorTexture());
+ spreadFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
+ spreadFilter->SetRootActor(mChildrenRoot);
+ spreadFilter->SetBackgroundColor(mBackgroundColor);
+ spreadFilter->SetPixelFormat(Pixel::RGBA8888);
+ spreadFilter->SetSize(mTargetSize);
+ spreadFilter->SetSpread(mEffectSize);
+
+ EmbossFilter* embossFilter = static_cast<EmbossFilter*>(mFilters[1]);
+ embossFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
+ embossFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
+ embossFilter->SetRootActor(mChildrenRoot);
+ embossFilter->SetBackgroundColor(mBackgroundColor);
+ embossFilter->SetPixelFormat(Pixel::RGBA8888);
+ embossFilter->SetSize(mTargetSize);
+
+ BlurTwoPassFilter* blurFilter = static_cast<BlurTwoPassFilter*>(mFilters[2]);
+ blurFilter->SetInputTexture(mFrameBufferPostFilter.GetColorTexture());
+ blurFilter->SetOutputFrameBuffer(mFrameBufferPostFilter);
+ blurFilter->SetRootActor(mChildrenRoot);
+ blurFilter->SetBackgroundColor(Vector4(0.5f, 0.5f, 0.5f, 0.0));
+ blurFilter->SetPixelFormat(Pixel::RGBA8888);
+ blurFilter->SetSize(mTargetSize);
+ blurFilter->CreateKernel(BLUR_KERNEL0, sizeof(BLUR_KERNEL0) / sizeof(BLUR_KERNEL0[0]));
break;
}
}
}
}
+
void EffectsView::AllocateResources()
{
if(mTargetSize != mLastSize)
{
mLastSize = mTargetSize;
-
SetupCameras();
- mImageForChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED );
- mActorForChildren.SetImage(mImageForChildren);
+ Actor self(Self());
+
+ mFrameBufferForChildren = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
+ Texture textureForChildren = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
+ mFrameBufferForChildren.AttachColorTexture(textureForChildren);
+
+ SetRendererTexture(mRendererForChildren, textureForChildren);
+
+ mFrameBufferPostFilter = FrameBuffer::New(mTargetSize.width, mTargetSize.height, FrameBuffer::Attachment::NONE);
+ Texture texturePostFilter = Texture::New(TextureType::TEXTURE_2D, mPixelFormat, unsigned(mTargetSize.width), unsigned(mTargetSize.height));
+ mFrameBufferPostFilter.AttachColorTexture(texturePostFilter);
- mImagePostFilter = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED );
- mActorPostFilter.SetImage(mImagePostFilter);
+ SetRendererTexture(mRendererPostFilter, texturePostFilter);
SetupFilters();
}
void EffectsView::SetupCameras()
{
- const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) );
-
- // Create and place a camera for the children render, corresponding to its render target size
- mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
- // TODO: how do we pick a reasonable value for near clip? Needs to relate to normal camera the user renders with, but we don't have a handle on it
- mCameraForChildren.SetNearClippingPlane(1.0f);
- mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
- mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
- mCameraForChildren.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosScale);
- mCameraForChildren.SetZ( mTargetSize.height * cameraPosScale );
+ if(!mCameraForChildren)
+ {
+ // Create a camera for the children render, corresponding to its render target size
+ mCameraForChildren = CameraActor::New(mTargetSize);
+ mCameraForChildren.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ mCameraForChildren.SetInvertYAxis(true);
+ Self().Add(mCameraForChildren);
+ }
+ else
+ {
+ // place the camera for the children render, corresponding to its render target size
+ const float cameraPosScale(0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f));
+ mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
+ mCameraForChildren.SetNearClippingPlane(1.0f);
+ mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
+ mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
+ mCameraForChildren.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, mTargetSize.height * cameraPosScale));
+ mCameraForChildren.SetProperty(Actor::Property::POSITION_Z, mTargetSize.height * cameraPosScale);
+ }
}
void EffectsView::CreateRenderTasks()
{
+ if(mTargetSize == Vector2::ZERO)
+ {
+ return;
+ }
RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
// create render task to render our child actors to offscreen buffer
mRenderTaskForChildren = taskList.CreateTask();
- mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
- mRenderTaskForChildren.SetSourceActor( Self() );
+ mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
+ mRenderTaskForChildren.SetSourceActor(mChildrenRoot);
mRenderTaskForChildren.SetExclusive(true);
- mRenderTaskForChildren.SetInputEnabled( false );
- mRenderTaskForChildren.SetClearColor( mBackgroundColor );
- mRenderTaskForChildren.SetClearEnabled( true );
- mRenderTaskForChildren.SetTargetFrameBuffer( mImageForChildren );
+ mRenderTaskForChildren.SetInputEnabled(false);
+ mRenderTaskForChildren.SetClearColor(mBackgroundColor);
+ mRenderTaskForChildren.SetClearEnabled(true);
+ mRenderTaskForChildren.SetFrameBuffer(mFrameBufferForChildren);
mRenderTaskForChildren.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
// Enable image filters
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
{
mFilters[i]->Enable();
}
-
- // create render task to render result of the image filters to the final offscreen
- if( mImageForResult )
- {
- mRenderTaskForResult = taskList.CreateTask();
- mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
- mRenderTaskForResult.SetSourceActor( mActorForResult );
- mRenderTaskForResult.SetExclusive(true);
- mRenderTaskForResult.SetInputEnabled( false );
- mRenderTaskForResult.SetClearColor( mBackgroundColor );
- mRenderTaskForResult.SetClearEnabled( true );
- mRenderTaskForResult.SetTargetFrameBuffer( mImageForResult );
- mRenderTaskForResult.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
- }
}
void EffectsView::RemoveRenderTasks()
{
+ if(mTargetSize == Vector2::ZERO)
+ {
+ return;
+ }
+
RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
taskList.RemoveTask(mRenderTaskForChildren);
- taskList.RemoveTask(mRenderTaskForResult);
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
{
mFilters[i]->Disable();
}
{
RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
- if( mRenderTaskForChildren )
- {
- mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
- }
-
- if( mRenderTaskForResult )
+ if(mRenderTaskForChildren)
{
- mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
+ mRenderTaskForChildren.SetRefreshRate(mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS);
}
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
{
mFilters[i]->Refresh();
}
void EffectsView::RemoveFilters()
{
- const size_t numFilters( mFilters.size() );
- for( size_t i = 0; i < numFilters; ++i )
+ const size_t numFilters(mFilters.Size());
+ for(size_t i = 0; i < numFilters; ++i)
{
delete mFilters[i];
}
- mFilters.clear();
+ mFilters.Release();
+}
+
+void EffectsView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
+{
+ Toolkit::EffectsView effectsView = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
+
+ if(effectsView)
+ {
+ switch(index)
+ {
+ case Toolkit::EffectsView::Property::EFFECT_SIZE:
+ {
+ int effectSize;
+ if(value.Get(effectSize))
+ {
+ GetImpl(effectsView).SetEffectSize(effectSize);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+}
+
+Property::Value EffectsView::GetProperty(BaseObject* object, Property::Index propertyIndex)
+{
+ Property::Value value;
+
+ Toolkit::EffectsView imageview = Toolkit::EffectsView::DownCast(Dali::BaseHandle(object));
+
+ if(imageview)
+ {
+ EffectsView& impl = GetImpl(imageview);
+ switch(propertyIndex)
+ {
+ case Toolkit::EffectsView::Property::EFFECT_SIZE:
+ {
+ value = impl.GetEffectSize();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return value;
}
} // namespace Internal