X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Feffects-view%2Feffects-view-impl.cpp;h=5f132c7188a93606f79e4edd24e40344e38f03b2;hb=HEAD;hp=e0a5ea517c1970b1560d0ebe15a4e1a3b34b4ab0;hpb=e4e5db1d2d7997e7bf803a531048d8dcb959083b;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp index e0a5ea5..5f132c7 100644 --- a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp +++ b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -19,90 +19,80 @@ #include "effects-view-impl.h" // EXTERNAL INCLUDES +#include #include #include -#include -#include +#include +#include #include +#include #include +#include // INTERNAL INCLUDES -#include "../../filters/blur-two-pass-filter.h" -#include "../../filters/emboss-filter.h" -#include "../../filters/spread-filter.h" +#include +#include +#include +#include +#include +#include +#include +#include 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... @@ -112,18 +102,16 @@ Toolkit::EffectsView EffectsView::New() } 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) { } @@ -132,28 +120,27 @@ EffectsView::~EffectsView() 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: @@ -161,6 +148,8 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type ) break; } } + + mEffectType = type; } } @@ -174,13 +163,15 @@ void EffectsView::Enable() // 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() @@ -188,250 +179,230 @@ 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( mActorPostFilter, Actor::Property::POSITION, EqualToConstraint() ); - positionConstraint.AddSource( Source( self, mEffectOffsetPropertyIndex ) ); - positionConstraint.Apply(); - - Constraint colorConstraint = Constraint::New( mActorPostFilter, Actor::Property::COLOR, EqualToConstraint() ); - colorConstraint.AddSource( Source( self, mEffectColorPropertyIndex ) ); - colorConstraint.Apply(); + self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, 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() ); - 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(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(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(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(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(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; } @@ -441,19 +412,27 @@ void EffectsView::SetupFilters() } } } + 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(); } @@ -461,64 +440,67 @@ void EffectsView::AllocateResources() 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(); } @@ -528,18 +510,13 @@ void EffectsView::RefreshRenderTasks() { 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(); } @@ -547,12 +524,63 @@ void EffectsView::RefreshRenderTasks() 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