my $opt_help;
my $opt_quiet;
my $opt_verbose;
+my $opt_variable;
my %options = (
"output:s" => { "optvar"=>\$opt_output, "desc"=>"output"},
+ "variable=s" => { "optvar"=>\$opt_variable, "desc"=>"variable"},
"help" => { "optvar"=>\$opt_help, "desc"=>""},
"quiet" => { "optvar"=>\$opt_quiet, "desc"=>""},
"verbose" => { "optvar"=>\$opt_verbose, "desc"=>"" });
GetOptions( %longOptions ) or pod2usage(2);
pod2usage(1) if $opt_help;
-if( $opt_output )
+my $var;
+if($opt_variable)
{
+ $var = "--vn $opt_variable";
}
my $tempFile="/tmp/shader.spv$$";
# Create a binary file from the main argument
-print `glslangValidator -V1.0 $ARGV[0] -vn -o $tempFile`;
+print " Executing: glslangValidator -V1.0 $ARGV[0] $var -o $tempFile\n";
+print `glslangValidator -V1.0 $ARGV[0] $var -o $tempFile`;
open PIPE, "uuencode -m $tempFile $tempFile | " || die "Can't execute pipe: $!\n";
my @lines;
#include <dali-toolkit/dali-toolkit.h>
using namespace Dali;
-using Dali::Toolkit::TextLabel;
+using namespace Dali::Toolkit;
+#include <dali-toolkit/devel-api/controls/gaussian-blur-view/gaussian-blur-view.h>
-// This example shows how to create and display Hello World! using a simple TextActor
-//
-class HelloWorldController : public ConnectionTracker
+const char* URL="https://upload.wikimedia.org/wikipedia/commons/2/2c/NZ_Landscape_from_the_van.jpg";
+
+/**
+ * This example shows how to use GaussianBlur UI control.
+ */
+class ImageBlurExample : public ConnectionTracker
{
public:
- HelloWorldController( Application& application )
+ // Initialize variables and connect signal
+ ImageBlurExample( Application& application )
: mApplication( application )
{
// Connect to the Application's Init signal
- mApplication.InitSignal().Connect( this, &HelloWorldController::Create );
+ mApplication.InitSignal().Connect( this, &ImageBlurExample::Create );
}
- ~HelloWorldController()
+ ~ImageBlurExample()
{
// Nothing to do here;
}
void Create( Application& application )
{
// Get a handle to the stage
- Stage stage = Stage::GetCurrent();
- stage.SetBackgroundColor( Color::WHITE );
+ mStage = Stage::GetCurrent();
+ // Set stage background color
+ mStage.SetBackgroundColor( Color::BLACK );
+ mStage.KeyEventSignal().Connect(this, &ImageBlurExample::OnKeyEvent);
- TextLabel textLabel = TextLabel::New( "Hello World" );
- textLabel.SetAnchorPoint( AnchorPoint::TOP_LEFT );
- textLabel.SetName( "helloWorldLabel" );
- stage.Add( textLabel );
+ mImageView = ImageView::New();
+ mImageView.SetProperty(ImageView::Property::IMAGE, Property::Map()
+ .Add(ImageVisual::Property::URL, URL)
+ .Add(ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE ) );
- // Respond to a click anywhere on the stage
- stage.GetRootLayer().TouchSignal().Connect( this, &HelloWorldController::OnTouch );
+ mImageView.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ mImageView.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- // Respond to key events
- stage.KeyEventSignal().Connect( this, &HelloWorldController::OnKeyEvent );
+ auto sceneText = TextLabel::New( "Landscape photo");
+ sceneText.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+ sceneText.SetProperty( TextLabel::Property::POINT_SIZE, 40 );
+ sceneText.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
+ sceneText.SetProperty( TextLabel::Property::OUTLINE, Property::Map().Add("color",Color::WHITE).Add("width", 2) );
+ sceneText.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ sceneText.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ sceneText.SetName("SceneText");
+ mImageView.Add(sceneText);
+
+ CreateBlurView( mImageView );
+ mStage.KeepRendering( 1000000.0f );
}
- bool OnTouch( Actor actor, const TouchData& touch )
+ void CreateBlurView( Actor scene )
{
- // quit the application
- mApplication.Quit();
- return true;
+ mGaussianBlurView = GaussianBlurView::New(5, 1.5f, 0.5f, 0.5f);
+ mGaussianBlurView.SetSize(mStage.GetSize()*0.8f);
+ mGaussianBlurView.SetAnchorPoint( AnchorPoint::CENTER );
+ mGaussianBlurView.SetParentOrigin( ParentOrigin::CENTER );
+ mGaussianBlurView.SetVisible( true );
+ mGaussianBlurView.Add( scene );
+ mGaussianBlurView.SetBackgroundColor( Color::MAGENTA ); // All render tasks should use this color...
+
+ mStage.Add(mGaussianBlurView);
+ mGaussianBlurView.Activate();
}
- void OnKeyEvent( const KeyEvent& event )
+
+ void OnKeyEvent(const KeyEvent& event)
{
- if( event.state == KeyEvent::Down )
+ if(event.state == KeyEvent::Down)
{
- if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
+ if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
{
mApplication.Quit();
}
+ if( event.keyCode == 10 )
+ {
+ if( mGaussianBlurView )
+ {
+ mGaussianBlurView.Deactivate();
+ printf("Deactivated\n");
+ }
+ }
+ else if( event.keyCode == 11 )
+ {
+ if( mGaussianBlurView )
+ {
+ mGaussianBlurView.Activate();
+ printf("Activated\n");
+ }
+ }
+ else if( event.keyCode == 12 )
+ {
+ UnparentAndReset( mGaussianBlurView );
+ printf("Destroyed\n");
+ }
+ else if( event.keyCode == 13 )
+ {
+ CreateBlurView( mImageView );
+ printf("Re-created\n");
+ }
}
}
private:
Application& mApplication;
+ Stage mStage;
+ GaussianBlurView mGaussianBlurView;
+ ImageView mImageView;
+
};
-int DALI_EXPORT_API main( int argc, char **argv )
+// Entry point for Linux & Tizen applications
+int main(int argc, char **argv)
{
- Application application = Application::New( &argc, &argv );
- HelloWorldController test( application );
- application.MainLoop();
+ // Create application instance
+ Application app = Application::New(&argc, &argv);
+ ImageBlurExample test(app);
+
+ // Start application.
+ app.MainLoop();
+
return 0;
}
--- /dev/null
+std::vector<uint32_t> GAUSSIAN_BLUR_FRAG_SHADER = {
+ 0x07230203,0x00010000,0x00080001,0x00000044,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000011,0x00000042,0x00030010,
+ 0x00000004,0x00000007,0x00030003,0x00000002,0x000001ae,0x00040005,0x00000004,0x6e69616d,
+ 0x00000000,0x00030005,0x00000009,0x006c6f63,0x00050005,0x0000000d,0x78655473,0x65727574,
+ 0x00000000,0x00050005,0x00000011,0x78655476,0x726f6f43,0x00000064,0x00050005,0x00000017,
+ 0x67617246,0x61746144,0x00000000,0x00050006,0x00000017,0x00000000,0x6c6f4375,0x0000726f,
+ 0x00070006,0x00000017,0x00000001,0x6d615375,0x4f656c70,0x65736666,0x00007374,0x00070006,
+ 0x00000017,0x00000002,0x6d615375,0x57656c70,0x68676965,0x00007374,0x00030005,0x00000019,
+ 0x00000000,0x00030005,0x00000028,0x00000069,0x00050005,0x00000042,0x67617266,0x6f6c6f43,
+ 0x00000072,0x00030047,0x00000009,0x00000000,0x00040047,0x0000000d,0x00000022,0x00000000,
+ 0x00040047,0x0000000d,0x00000021,0x00000002,0x00030047,0x00000011,0x00000000,0x00040047,
+ 0x00000011,0x0000001e,0x00000000,0x00030047,0x00000012,0x00000000,0x00040047,0x00000015,
+ 0x00000006,0x00000010,0x00040047,0x00000016,0x00000006,0x00000010,0x00040048,0x00000017,
+ 0x00000000,0x00000000,0x00050048,0x00000017,0x00000000,0x00000023,0x00000000,0x00040048,
+ 0x00000017,0x00000001,0x00000000,0x00050048,0x00000017,0x00000001,0x00000023,0x00000010,
+ 0x00040048,0x00000017,0x00000002,0x00000000,0x00050048,0x00000017,0x00000002,0x00000023,
+ 0x00000060,0x00030047,0x00000017,0x00000002,0x00040047,0x00000019,0x00000022,0x00000000,
+ 0x00040047,0x00000019,0x00000021,0x00000001,0x00030047,0x0000001f,0x00000000,0x00030047,
+ 0x00000020,0x00000000,0x00030047,0x00000025,0x00000000,0x00030047,0x00000033,0x00000000,
+ 0x00030047,0x00000036,0x00000000,0x00030047,0x00000037,0x00000000,0x00030047,0x0000003b,
+ 0x00000000,0x00030047,0x0000003d,0x00000000,0x00040047,0x00000042,0x0000001e,0x00000000,
+ 0x00030047,0x00000043,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,
+ 0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,
+ 0x00000008,0x00000007,0x00000007,0x00090019,0x0000000a,0x00000006,0x00000001,0x00000000,
+ 0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b,0x0000000b,0x0000000a,0x00040020,
+ 0x0000000c,0x00000000,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000000,0x00040017,
+ 0x0000000f,0x00000006,0x00000002,0x00040020,0x00000010,0x00000001,0x0000000f,0x0004003b,
+ 0x00000010,0x00000011,0x00000001,0x00040015,0x00000013,0x00000020,0x00000000,0x0004002b,
+ 0x00000013,0x00000014,0x00000005,0x0004001c,0x00000015,0x0000000f,0x00000014,0x0004001c,
+ 0x00000016,0x00000006,0x00000014,0x0005001e,0x00000017,0x00000007,0x00000015,0x00000016,
+ 0x00040020,0x00000018,0x00000002,0x00000017,0x0004003b,0x00000018,0x00000019,0x00000002,
+ 0x00040015,0x0000001a,0x00000020,0x00000001,0x0004002b,0x0000001a,0x0000001b,0x00000001,
+ 0x0004002b,0x0000001a,0x0000001c,0x00000000,0x00040020,0x0000001d,0x00000002,0x0000000f,
+ 0x0004002b,0x0000001a,0x00000022,0x00000002,0x00040020,0x00000023,0x00000002,0x00000006,
+ 0x00040020,0x00000027,0x00000007,0x0000001a,0x0004002b,0x0000001a,0x0000002f,0x00000005,
+ 0x00020014,0x00000030,0x00040020,0x00000041,0x00000003,0x00000007,0x0004003b,0x00000041,
+ 0x00000042,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,
+ 0x00000005,0x0004003b,0x00000008,0x00000009,0x00000007,0x0004003b,0x00000027,0x00000028,
+ 0x00000007,0x0004003d,0x0000000b,0x0000000e,0x0000000d,0x0004003d,0x0000000f,0x00000012,
+ 0x00000011,0x00060041,0x0000001d,0x0000001e,0x00000019,0x0000001b,0x0000001c,0x0004003d,
+ 0x0000000f,0x0000001f,0x0000001e,0x00050081,0x0000000f,0x00000020,0x00000012,0x0000001f,
+ 0x00050057,0x00000007,0x00000021,0x0000000e,0x00000020,0x00060041,0x00000023,0x00000024,
+ 0x00000019,0x00000022,0x0000001c,0x0004003d,0x00000006,0x00000025,0x00000024,0x0005008e,
+ 0x00000007,0x00000026,0x00000021,0x00000025,0x0003003e,0x00000009,0x00000026,0x0003003e,
+ 0x00000028,0x0000001b,0x000200f9,0x00000029,0x000200f8,0x00000029,0x000400f6,0x0000002b,
+ 0x0000002c,0x00000000,0x000200f9,0x0000002d,0x000200f8,0x0000002d,0x0004003d,0x0000001a,
+ 0x0000002e,0x00000028,0x000500b1,0x00000030,0x00000031,0x0000002e,0x0000002f,0x000400fa,
+ 0x00000031,0x0000002a,0x0000002b,0x000200f8,0x0000002a,0x0004003d,0x0000000b,0x00000032,
+ 0x0000000d,0x0004003d,0x0000000f,0x00000033,0x00000011,0x0004003d,0x0000001a,0x00000034,
+ 0x00000028,0x00060041,0x0000001d,0x00000035,0x00000019,0x0000001b,0x00000034,0x0004003d,
+ 0x0000000f,0x00000036,0x00000035,0x00050081,0x0000000f,0x00000037,0x00000033,0x00000036,
+ 0x00050057,0x00000007,0x00000038,0x00000032,0x00000037,0x0004003d,0x0000001a,0x00000039,
+ 0x00000028,0x00060041,0x00000023,0x0000003a,0x00000019,0x00000022,0x00000039,0x0004003d,
+ 0x00000006,0x0000003b,0x0000003a,0x0005008e,0x00000007,0x0000003c,0x00000038,0x0000003b,
+ 0x0004003d,0x00000007,0x0000003d,0x00000009,0x00050081,0x00000007,0x0000003e,0x0000003d,
+ 0x0000003c,0x0003003e,0x00000009,0x0000003e,0x000200f9,0x0000002c,0x000200f8,0x0000002c,
+ 0x0004003d,0x0000001a,0x0000003f,0x00000028,0x00050080,0x0000001a,0x00000040,0x0000003f,
+ 0x0000001b,0x0003003e,0x00000028,0x00000040,0x000200f9,0x00000029,0x000200f8,0x0000002b,
+ 0x0004003d,0x00000007,0x00000043,0x00000009,0x0003003e,0x00000042,0x00000043,0x000100fd,
+ 0x00010038
+};
*/
#include <dali-toolkit/dali-toolkit.h>
-#include <dali-toolkit/devel-api/controls/gaussian-blur-view/gaussian-blur-view.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include "gaussian-blur-frag-shader.h"
+#include "utils.h"
using namespace Dali;
using namespace Dali::Toolkit;
+namespace
+{
+const Vector2 TARGET_SIZE(960.f, 480.f);
+const char* URL="https://upload.wikimedia.org/wikipedia/commons/2/2c/NZ_Landscape_from_the_van.jpg";
+}
+
class ImageViewBlurExample : public ConnectionTracker
{
public:
{
auto stage = Stage::GetCurrent();
stage.KeyEventSignal().Connect(this, &ImageViewBlurExample::OnKeyEvent);
+ stage.SetBackgroundColor( Vector4( 0.2f, 0.1f, 0.2f, 1.0f ) );
+
+ mSceneActor = CreateScene( TARGET_SIZE );
- CreateBlurView1();
+ // Don't add to stage until it's ready.... Must use immediate only.
+ // If image view's aren't added with loading policy = Immediate, then the render task cannot use REFRESH_ONCE,
+ // and must run until de-activated
+
+ // Build render tasks in ready callback.
+ Stage::GetCurrent().Add( mSceneActor ); // Will make all text labels ready
+ mSceneActor.SetVisible(false);
}
- void CreateBlurView1()
+
+ Actor CreateScene( Vector2 targetSize )
{
- auto stage = Stage::GetCurrent();
- auto size = stage.GetSize();
- auto image1 = ImageView::New( DEMO_IMAGE_DIR "background-1.jpg" );
- image1.SetSize( size * 0.5f );
-
- blurView1 = GaussianBlurView::New();
- blurView1.SetSize( size * 0.5f );
- blurView1.SetParentOrigin( ParentOrigin::CENTER );// Vector3(0.0f, -0.25f, 0.0f) );
- blurView1.SetAnchorPoint( AnchorPoint::CENTER );
- blurView1.Add( image1 );
- //blurView1.SetBackgroundColor( Color::RED );
-
- image1.SetParentOrigin( ParentOrigin::CENTER );
- image1.SetAnchorPoint( AnchorPoint::CENTER );
- blurView1.Activate();
-
- blurView1.SetProperty(blurView1.GetBlurStrengthPropertyIndex(), 1.0f);
- auto blurAnim = Animation::New(0.5f);
- blurAnim.AnimateTo( Property( blurView1, blurView1.GetBlurStrengthPropertyIndex() ), 1.0f);
- blurAnim.FinishedSignal().Connect( this, &ImageViewBlurExample::OnBlurAnimFinished );
- blurAnim.Play();
- stage.Add(blurView1);
+ auto sceneActor = Actor::New();
+ sceneActor.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ sceneActor.SetParentOrigin( ParentOrigin::CENTER );
+ auto sceneImage = ImageView::New();
+ sceneImage.SetProperty(ImageView::Property::IMAGE, Property::Map()
+ .Add( ImageVisual::Property::URL, URL )
+ .Add( ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE ) );
+
+ sceneImage.ResourceReadySignal().Connect( this, &ImageViewBlurExample::OnImageReady );
+
+ sceneImage.SetSize( targetSize );
+ sceneImage.SetParentOrigin( ParentOrigin::CENTER );
+ sceneImage.SetAnchorPoint( AnchorPoint::CENTER );
+ sceneImage.SetName("SceneImage");
+ sceneActor.Add(sceneImage);
+
+ auto sceneText = TextLabel::New( "Landscape photo");
+ sceneText.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+ sceneText.SetProperty( TextLabel::Property::POINT_SIZE, 40 );
+ sceneText.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
+ sceneText.SetProperty( TextLabel::Property::OUTLINE, Property::Map().Add("color",Color::WHITE).Add("width", 2) );
+ sceneText.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ sceneText.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ sceneText.SetName("SceneText");
+ sceneImage.Add(sceneText);
+ return sceneActor;
}
- void OnBlurAnimFinished(Animation& anim)
+ void OnImageReady( Control control )
{
- blurView1.Deactivate();
+ mSceneActor.SetVisible(true);
+ CreateBlurView( mSceneActor, TARGET_SIZE ); // Renders the scene in an exclusive render task
+ }
+
+ /**
+ * Create a scene render + 2 stage filter, reusing Framebuffers
+ */
+ void CreateBlurView( Actor sceneActor, Vector2 targetSize )
+ {
+ auto stage = Stage::GetCurrent();
+
+ // Step 1 captures the scene into a framebuffer without any effects
+ auto step1Output = Texture::New( TextureType::TEXTURE_2D,
+ Pixel::RGBA8888,
+ unsigned(targetSize.width),
+ unsigned(targetSize.height) );
+
+ // Should be final size
+ auto fb1 = FrameBuffer::New(targetSize.width, targetSize.height, Pixel::RGBA8888);
+ fb1.AttachColorTexture( step1Output );
+
+ Utils::CreateRenderTask( sceneActor, targetSize, fb1 ); // Renders scene exclusively - it shouldn't be drawn to main fb
+ auto step1Url = TextureManager::AddTexture( step1Output );
+
+ mPreview1 = Utils::CreatePreview( step1Url, targetSize, ParentOrigin::TOP_LEFT, ParentOrigin::BOTTOM_LEFT,"Step 1", true );
+ stage.Add( mPreview1 );
+
+ // Step2 executes the first pass of the effect shader
+ // Can be reduced size:
+ Vector2 downscaledSize = targetSize * 0.5f;
+
+ auto step2Url = Utils::CreateEffectPassTexture( step1Url, GAUSSIAN_BLUR_FRAG_SHADER, downscaledSize,
+ Utils::Direction::HORIZONTAL );
+
+ mPreview2 = Utils::CreatePreview( step2Url, targetSize, ParentOrigin::BOTTOM_LEFT, ParentOrigin::TOP_LEFT,
+ "Step 2", true );
+ stage.Add( mPreview2 );
+
+ // Step 3 renders the second pass of the effect shader
+ auto step3Url = Utils::CreateEffectPassTexture( step2Url, GAUSSIAN_BLUR_FRAG_SHADER, downscaledSize,
+ Utils::Direction::VERTICAL );
+
+ // Don't bother with preview 3, we're going to draw it at larger scale back to original fbo
+ std::vector<uint32_t> empty;
+ Utils::CreateEffectPassTexture( step3Url, empty, targetSize, Utils::Direction::HORIZONTAL, fb1 );
+
+ // Render step 4 output (same as step 1 output) to center:
+ mFinalImage = ImageView::New( step1Url );
+ mFinalImage.SetSize( targetSize );
+ mFinalImage.SetParentOrigin( ParentOrigin::CENTER );
+ mFinalImage.SetAnchorPoint( AnchorPoint::CENTER );
+ stage.Add( mFinalImage );
}
- void OnBlurFinished(GaussianBlurView source)
+ void Deactivate()
{
- printf("Blur finished\n");
+ Stage stage = Stage::GetCurrent();
+ auto taskList = stage.GetRenderTaskList();
+ for( unsigned int i=taskList.GetTaskCount()-1; i>0; --i )
+ {
+ auto task = taskList.GetTask(i);
+ Actor cameraActor = task.GetCameraActor();
+ Actor sourceActor = task.GetSourceActor();
+ stage.Remove( cameraActor );
+ stage.Remove( sourceActor );
+ task.SetCameraActor( CameraActor() );
+ task.SetSourceActor( Actor() );
+ taskList.RemoveTask(taskList.GetTask(i));
+ }
+ UnparentAndReset(mPreview1);
+ UnparentAndReset(mPreview2);
+ mFinalImage.SetSize( TARGET_SIZE * 1.8f );
}
void OnKeyEvent(const KeyEvent& event)
{
mApp.Quit();
}
+ if( event.keyCode == 10 )
+ {
+ Deactivate();
+ }
}
}
private:
Application& mApp;
- GaussianBlurView blurView1;
- GaussianBlurView blurView2;
+ Actor mSceneActor;
+ ImageView mFinalImage;
+ Actor mPreview1;
+ Actor mPreview2;
};
int main( int argc, char** argv )
--- /dev/null
+#include "utils.h"
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
+#include <iostream>
+
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+namespace Utils
+{
+
+std::string CreateEffectPassTexture( std::string inputUrl, std::vector<uint32_t>& fragShader, Vector2 targetSize, Direction direction )
+{
+ auto outputTexture = Texture::New( TextureType::TEXTURE_2D,
+ Pixel::RGBA8888,
+ unsigned(targetSize.width),
+ unsigned(targetSize.height) );
+
+ auto framebuffer = FrameBuffer::New(targetSize.width, targetSize.height, Pixel::RGB888);
+ framebuffer.AttachColorTexture( outputTexture );
+
+ Actor image = CreateEffectPassTexture( inputUrl, fragShader, targetSize, direction, framebuffer );
+
+ auto url = Dali::Toolkit::TextureManager::AddTexture( outputTexture );
+ return url;
+}
+
+
+Actor CreateEffectPassTexture( std::string inputUrl, std::vector<uint32_t>& fragShader, Vector2 targetSize, Direction direction, FrameBuffer fb )
+{
+ auto image = ImageView::New( inputUrl );
+
+ if( fragShader.size() > 0 )
+ {
+ Property::Map visualMap;
+ Property::Map customShader;
+ Property::Value value;
+ Toolkit::EncodeBase64PropertyData( value, fragShader );
+ customShader[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = value;
+ visualMap[Toolkit::Visual::Property::SHADER] = customShader;
+ image.SetProperty(Toolkit::ImageView::Property::IMAGE, visualMap);
+ SetShaderConstants( image, direction, 5, targetSize.x, targetSize.y );
+ }
+
+ image.SetParentOrigin( ParentOrigin::CENTER );
+ image.SetSize( targetSize );
+
+ Stage::GetCurrent().Add(image);
+
+ Utils::CreateRenderTask( image, targetSize, fb );
+ return image;
+}
+
+Actor CreatePreview( const std::string& url,
+ Vector2 targetSize,
+ Vector3 parentOrigin, Vector3 labelOrigin,
+ const std::string& label, bool copy )
+{
+ Actor previewActor;
+ if( copy )
+ {
+ previewActor = CreatePreviewRenderTask( url, targetSize );
+ }
+ else
+ {
+ previewActor = ImageView::New( url );
+ }
+
+ previewActor.SetParentOrigin( parentOrigin );
+ previewActor.SetAnchorPoint( parentOrigin );
+ previewActor.SetSize( targetSize * 0.8f );
+
+ auto labelActor = TextLabel::New(label);
+ labelActor.SetResizePolicy(ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS);
+ labelActor.SetParentOrigin( labelOrigin );
+ labelActor.SetAnchorPoint( parentOrigin );
+ labelActor.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE);
+ previewActor.Add( labelActor );
+
+ return previewActor;
+}
+
+/**
+ * @param[in] url The url of the texture to copy
+ * @return An image view containing a copy of the texture
+ */
+Actor CreatePreviewRenderTask( std::string url, Vector2 targetSize )
+{
+ // Image for re-rendering to a second FB
+ auto image = ImageView::New( url );
+ image.SetSize( targetSize );
+ image.SetParentOrigin( ParentOrigin::CENTER );
+ image.SetAnchorPoint( AnchorPoint::CENTER );
+ Stage::GetCurrent().Add( image );
+
+ Texture previewOutput = Utils::CreateRenderTask( image, targetSize ); // Exclusive
+ auto previewUrl = Dali::Toolkit::TextureManager::AddTexture( previewOutput );
+
+ auto previewImage = ImageView::New( previewUrl );
+ previewImage.SetSize( targetSize * 0.4f );
+ return previewImage;
+}
+
+Texture CreateRenderTask(Actor inputActor, Vector2 targetSize)
+{
+ auto outputTexture = Texture::New( TextureType::TEXTURE_2D,
+ Pixel::RGBA8888,
+ unsigned(targetSize.width),
+ unsigned(targetSize.height) );
+
+ auto framebuffer = FrameBuffer::New(targetSize.width, targetSize.height, Pixel::RGBA8888);
+ framebuffer.AttachColorTexture( outputTexture );
+
+ Utils::CreateRenderTask( inputActor, targetSize, framebuffer );
+
+ return outputTexture;
+}
+
+void CreateRenderTask(Actor inputActor, Vector2 targetSize, FrameBuffer fbo )
+{
+ auto rootActor = Stage::GetCurrent().GetRootLayer();
+
+ auto cameraActor = CameraActor::New(targetSize);
+ float fov = Math::PI * 0.25f;
+ cameraActor.SetFieldOfView( fov );
+ cameraActor.SetNearClippingPlane( 1.0f );
+ cameraActor.SetAspectRatio( targetSize.width / targetSize.height );
+ cameraActor.SetType( Dali::Camera::FREE_LOOK );
+ cameraActor.SetPosition( 0.0f, 0.0f, ((targetSize.height * 0.5f) / tanf( fov * 0.5f ) ) );
+ cameraActor.SetParentOrigin(ParentOrigin::CENTER);
+ rootActor.Add(cameraActor);
+
+ RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+
+ auto renderTask = taskList.CreateTask();
+ renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
+ renderTask.SetSourceActor(inputActor);
+ renderTask.SetExclusive(true);
+
+ renderTask.SetInputEnabled(false);
+ renderTask.SetClearColor(Vector4(1.,0.,0.,1.));
+ renderTask.SetClearEnabled(true);
+ renderTask.SetCameraActor(cameraActor);
+
+ renderTask.SetFrameBuffer( fbo );
+}
+
+
+float CalcGaussianWeight(float x)
+{
+ const float BELL_CURVE_WIDTH( 1.5f );
+
+ return (1.0f / sqrt(2.0f * Math::PI * BELL_CURVE_WIDTH)) * exp(-(x * x) / (2.0f * BELL_CURVE_WIDTH * BELL_CURVE_WIDTH));
+}
+
+std::string GetSampleOffsetsPropertyName( unsigned int index )
+{
+ std::ostringstream oss;
+ oss << "uSampleOffsets[" << index << "]";
+ return oss.str();
+}
+
+std::string GetSampleWeightsPropertyName( unsigned int index )
+{
+ std::ostringstream oss;
+ oss << "uSampleWeights[" << index << "]";
+ return oss.str();
+}
+
+
+void SetShaderConstants(Actor actor, Direction direction, uint32_t numSamples, float downsampledWidth, float downsampledHeight)
+{
+ Vector2 *uvOffsets;
+ float ofs;
+ float *weights;
+ float w, totalWeights;
+ unsigned int i;
+
+ uvOffsets = new Vector2[numSamples + 1];
+ weights = new float[numSamples + 1];
+
+ totalWeights = weights[0] = CalcGaussianWeight(0);
+ uvOffsets[0].x = 0.0f;
+ uvOffsets[0].y = 0.0f;
+
+ for(i=0; i<numSamples >> 1; i++)
+ {
+ w = CalcGaussianWeight((float)(i + 1));
+ weights[(i << 1) + 1] = w;
+ weights[(i << 1) + 2] = w;
+ totalWeights += w * 2.0f;
+
+ // offset texture lookup to between texels, that way the bilinear filter in the texture hardware will average two samples with one lookup
+ ofs = ((float)(i << 1)) + 1.5f;
+
+ // get offsets from units of pixels into uv coordinates in [0..1]
+ float ofsX = ofs / downsampledWidth;
+ float ofsY = ofs / downsampledHeight;
+ uvOffsets[(i << 1) + 1].x = ofsX;
+ uvOffsets[(i << 1) + 1].y = ofsY;
+
+ uvOffsets[(i << 1) + 2].x = -ofsX;
+ uvOffsets[(i << 1) + 2].y = -ofsY;
+ }
+
+ for(i=0; i<numSamples; i++)
+ {
+ weights[i] /= totalWeights;
+ }
+
+ // set shader constants
+ Vector2 xAxis(1.0f, 0.0f);
+ Vector2 yAxis(0.0f, 1.0f);
+ for (i = 0; i < numSamples; ++i )
+ {
+ switch( direction )
+ {
+ case Direction::HORIZONTAL:
+ {
+ actor.RegisterProperty( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * xAxis );
+ actor.RegisterProperty( GetSampleWeightsPropertyName( i ), weights[ i ] );
+ break;
+ }
+ case Direction::VERTICAL:
+ {
+ actor.RegisterProperty( GetSampleOffsetsPropertyName( i ), uvOffsets[ i ] * yAxis );
+ actor.RegisterProperty( GetSampleWeightsPropertyName( i ), weights[ i ] );
+ break;
+ }
+ }
+ }
+
+ delete[] uvOffsets;
+ delete[] weights;
+}
+
+} // namespace Util
--- /dev/null
+#ifndef UTILS_H
+#define UTILS_H
+
+/*
+ * Copyright (c) 2018 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <string>
+#include <vector>
+
+namespace Utils
+{
+
+enum class Direction
+{
+ HORIZONTAL,
+ VERTICAL
+};
+
+std::string CreateEffectPassTexture( std::string inputUrl, std::vector<uint32_t>& fragShader,
+ Dali::Vector2 targetSize, Direction direction );
+Dali::Actor CreateEffectPassTexture( std::string inputUrl, std::vector<uint32_t>& fragShader,
+ Dali::Vector2 targetSize, Direction direction, Dali::FrameBuffer fb );
+Dali::Actor CreatePreview( const std::string& url, Dali::Vector2 targetSize, Dali::Vector3 parentOrigin,
+ Dali::Vector3 labelOrigin, const std::string& label, bool copy );
+Dali::Actor CreatePreviewRenderTask( std::string url, Dali::Vector2 targetSize );
+Dali::Texture CreateRenderTask(Dali::Actor inputActor, Dali::Vector2 targetSize);
+void CreateRenderTask(Dali::Actor inputActor, Dali::Vector2 targetSize, Dali::FrameBuffer fbo);
+
+void SetShaderConstants(Dali::Actor actor, Direction direction, uint32_t numSamples,
+ float downsampledWidth, float downsampledHeight);
+
+
+}
+
+#endif // UTILS_H