Updated demos to use DALi clang-format
[platform/core/uifw/dali-demo.git] / examples / native-image-source / native-image-source-example.cpp
index 873260a..4183352 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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 <dali/dali.h>
+// EXTERNAL INCLUDES
 #include <dali-toolkit/dali-toolkit.h>
+#include <dali/dali.h>
+#include <cstring>
+
+// INTERNAL INCLUDES
+#include "shared/utility.h"
 
 using namespace Dali;
 using namespace Toolkit;
 
 namespace
 {
-  const std::string JPG_FILENAME = DEMO_IMAGE_DIR "gallery-medium-4.jpg";
+const float BUTTON_HEIGHT = 100.0f;
+const float BUTTON_COUNT  = 5.0f;
+
+const std::string JPG_FILENAME     = DEMO_IMAGE_DIR "gallery-medium-4.jpg";
+const std::string CAPTURE_FILENAME = "/tmp/native-image-capture.png";
+
+/**
+ * @brief Creates a shader used to render a native image
+ * @param[in] nativeImage The native image
+ * @return A shader to render the native image
+ */
+Shader CreateShader(NativeImageInterface& nativeImage)
+{
+  static const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
+
+  // clang-format off
+  static const char* VERTEX_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
+      attribute mediump vec2 aPosition;\n
+      attribute mediump vec2 aTexCoord;\n
+      uniform mediump mat4 uMvpMatrix;\n
+      uniform mediump vec3 uSize;\n
+      varying mediump vec2 vTexCoord;\n
+      void main()\n
+      {\n
+        vec4 position = vec4(aPosition,0.0,1.0)*vec4(uSize,1.0);\n
+        gl_Position = uMvpMatrix * position;\n
+        vTexCoord = aTexCoord;\n
+      }\n
+  );
+
+  static const char* FRAGMENT_SHADER_TEXTURE = DALI_COMPOSE_SHADER(
+      uniform lowp vec4 uColor;\n
+      uniform sampler2D sTexture;\n
+      varying mediump vec2 vTexCoord;\n
+
+      void main()\n
+      {\n
+        gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+      }\n
+  );
+  // clang-format on
+
+  std::string fragmentShader;
+
+  //Get custom fragment shader prefix
+  const char* fragmentPrefix = nativeImage.GetCustomFragmentPrefix();
+  if(fragmentPrefix)
+  {
+    fragmentShader = fragmentPrefix;
+    fragmentShader += FRAGMENT_SHADER_TEXTURE;
+  }
+  else
+  {
+    fragmentShader = FRAGMENT_SHADER_TEXTURE;
+  }
+
+  //Get custom sampler type name
+  const char* customSamplerTypename = nativeImage.GetCustomSamplerTypename();
+  if(customSamplerTypename)
+  {
+    fragmentShader.replace(fragmentShader.find(DEFAULT_SAMPLER_TYPENAME), strlen(DEFAULT_SAMPLER_TYPENAME), customSamplerTypename);
+  }
+
+  return Shader::New(VERTEX_SHADER_TEXTURE, fragmentShader);
 }
 
+} // namespace
+
 // This example shows how to create and use a NativeImageSource as the target of the render task.
 //
 class NativeImageSourceController : public ConnectionTracker
 {
 public:
-
-  NativeImageSourceController( Application& application )
-  : mApplication( application )
+  NativeImageSourceController(Application& application)
+  : mApplication(application),
+    mRefreshAlways(true)
   {
     // Connect to the Application's Init signal
-    mApplication.InitSignal().Connect( this, &NativeImageSourceController::Create );
+    mApplication.InitSignal().Connect(this, &NativeImageSourceController::Create);
   }
 
   ~NativeImageSourceController()
@@ -45,123 +115,267 @@ public:
   }
 
   // The Init signal is received once (only) during the Application lifetime
-  void Create( Application& application )
+  void Create(Application& application)
+  {
+    // Get a handle to the window
+    Window window = application.GetWindow();
+    window.SetBackgroundColor(Color::WHITE);
+
+    window.KeyEventSignal().Connect(this, &NativeImageSourceController::OnKeyEvent);
+
+    CreateButtonArea();
+
+    CreateContentAreas();
+  }
+
+  void CreateButtonArea()
   {
-    // Get a handle to the stage
-    Stage stage = Stage::GetCurrent();
-    stage.SetBackgroundColor( Color::WHITE );
-    stage.KeyEventSignal().Connect(this, &NativeImageSourceController::OnKeyEvent);
+    Window  window     = mApplication.GetWindow();
+    Vector2 windowSize = window.GetSize();
+
+    mButtonArea = Layer::New();
+    mButtonArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, BUTTON_HEIGHT));
+    mButtonArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
+    mButtonArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
+    window.Add(mButtonArea);
+
+    mButtonShow = PushButton::New();
+    mButtonShow.SetProperty(Button::Property::TOGGLABLE, true);
+    mButtonShow.SetProperty(Toolkit::Button::Property::LABEL, "SHOW");
+    mButtonShow.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    mButtonShow.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+    mButtonShow.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
+    mButtonShow.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
+    mButtonArea.Add(mButtonShow);
 
     mButtonRefreshAlways = PushButton::New();
-    mButtonRefreshAlways.SetTogglableButton( true );
-    mButtonRefreshAlways.SetSelected( true );
-    mButtonRefreshAlways.SetLabelText( "Refresh ALWAYS" );
-    mButtonRefreshAlways.SetParentOrigin( ParentOrigin::TOP_LEFT );
-    mButtonRefreshAlways.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-    mButtonRefreshAlways.StateChangedSignal().Connect( this, &NativeImageSourceController::OnButtonSelected );
-    stage.Add( mButtonRefreshAlways );
+    mButtonRefreshAlways.SetProperty(Button::Property::TOGGLABLE, true);
+    mButtonRefreshAlways.SetProperty(Toolkit::Button::Property::LABEL, "ALWAYS");
+    mButtonRefreshAlways.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    mButtonRefreshAlways.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+    mButtonRefreshAlways.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
+    mButtonRefreshAlways.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 1.0f, 0.0f));
+    mButtonRefreshAlways.StateChangedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
+    mButtonArea.Add(mButtonRefreshAlways);
 
     mButtonRefreshOnce = PushButton::New();
-    mButtonRefreshOnce.SetLabelText( "Refresh ONCE" );
-    mButtonRefreshOnce.SetParentOrigin( ParentOrigin::TOP_RIGHT );
-    mButtonRefreshOnce.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
-    mButtonRefreshOnce.ClickedSignal().Connect( this, &NativeImageSourceController::OnButtonSelected );
-    stage.Add( mButtonRefreshOnce);
-
-    CreateScene();
+    mButtonRefreshOnce.SetProperty(Toolkit::Button::Property::LABEL, "ONCE");
+    mButtonRefreshOnce.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    mButtonRefreshOnce.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+    mButtonRefreshOnce.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
+    mButtonRefreshOnce.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 2.0f, 0.0f));
+    mButtonRefreshOnce.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
+    mButtonArea.Add(mButtonRefreshOnce);
+
+    mButtonCapture = PushButton::New();
+    mButtonCapture.SetProperty(Toolkit::Button::Property::LABEL, "CAPTURE");
+    mButtonCapture.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    mButtonCapture.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+    mButtonCapture.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
+    mButtonCapture.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 3.0f, 0.0f));
+    mButtonCapture.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
+    mButtonArea.Add(mButtonCapture);
+
+    mButtonReset = PushButton::New();
+    mButtonReset.SetProperty(Toolkit::Button::Property::LABEL, "RESET");
+    mButtonReset.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    mButtonReset.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+    mButtonReset.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x / BUTTON_COUNT, BUTTON_HEIGHT));
+    mButtonReset.SetProperty(Actor::Property::POSITION, Vector2((windowSize.x / BUTTON_COUNT) * 4.0f, 0.0f));
+    mButtonReset.ClickedSignal().Connect(this, &NativeImageSourceController::OnButtonSelected);
+    mButtonArea.Add(mButtonReset);
   }
 
-  bool CreateScene()
+  void CreateContentAreas()
   {
-    Stage stage = Stage::GetCurrent();
-    Vector2 stageSize = stage.GetSize();
+    Window  window     = mApplication.GetWindow();
+    Vector2 windowSize = window.GetSize();
 
-    float buttonHeight = 100.f;
-    mButtonRefreshAlways.SetSize( stageSize.x / 2.f, buttonHeight );
-    mButtonRefreshOnce.SetSize( stageSize.x / 2.f, buttonHeight );
+    float contentHeight((windowSize.y - BUTTON_HEIGHT) / 2.0f);
 
-    Vector2 imageSize( stageSize.x, (stageSize.y-buttonHeight)/2.f );
+    mTopContentArea = Actor::New();
+    mTopContentArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, contentHeight));
+    mTopContentArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
+    mTopContentArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
+    mTopContentArea.SetProperty(Actor::Property::POSITION_Y, BUTTON_HEIGHT);
+    window.Add(mTopContentArea);
 
-    // Create the native image source
-    NativeImageSourcePtr nativeImageSourcePtr = NativeImageSource::New( imageSize.width, imageSize.height, NativeImageSource::COLOR_DEPTH_DEFAULT );
+    mBottomContentArea = Actor::New();
+    mBottomContentArea.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, contentHeight));
+    mBottomContentArea.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
+    mBottomContentArea.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
+    window.Add(mBottomContentArea);
 
-    // Create a image view as source actor to be renderer to the native image source
-    Actor sourceActor = ImageView::New(JPG_FILENAME);
-    sourceActor.SetParentOrigin( ParentOrigin::CENTER);
-    sourceActor.SetAnchorPoint( AnchorPoint::CENTER );
-    sourceActor.SetY( - (imageSize.height-buttonHeight)/2.f );
-    stage.Add( sourceActor );
+    mSourceActor = ImageView::New(JPG_FILENAME);
+    mSourceActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+    mSourceActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+    mTopContentArea.Add(mSourceActor);
 
     Animation animation = Animation::New(2.f);
-    Degree relativeRotationDegrees(90.0f);
-    Radian relativeRotationRadians(relativeRotationDegrees);
-    animation.AnimateTo( Property( sourceActor, Actor::Property::ORIENTATION ), Quaternion( relativeRotationRadians, Vector3::ZAXIS ), AlphaFunction::LINEAR, TimePeriod(0.f, 0.5f));
-    animation.AnimateBy( Property( sourceActor, Actor::Property::ORIENTATION ), Quaternion( relativeRotationRadians, Vector3::ZAXIS ), AlphaFunction::LINEAR, TimePeriod(0.5f, 0.5f));
-    animation.AnimateBy( Property( sourceActor, Actor::Property::ORIENTATION ), Quaternion( relativeRotationRadians, Vector3::ZAXIS ), AlphaFunction::LINEAR, TimePeriod(1.f, 0.5f));
-    animation.AnimateBy( Property( sourceActor, Actor::Property::ORIENTATION ), Quaternion( relativeRotationRadians, Vector3::ZAXIS ), AlphaFunction::LINEAR, TimePeriod(1.5f, 0.5f));
+    Degree    relativeRotationDegrees(90.0f);
+    Radian    relativeRotationRadians(relativeRotationDegrees);
+    animation.AnimateTo(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(0.f, 0.5f));
+    animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(0.5f, 0.5f));
+    animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(1.f, 0.5f));
+    animation.AnimateBy(Property(mSourceActor, Actor::Property::ORIENTATION), Quaternion(relativeRotationRadians, Vector3::ZAXIS), AlphaFunction::LINEAR, TimePeriod(1.5f, 0.5f));
     animation.SetLooping(true);
     animation.Play();
 
-    // create a offscreen renderer task to render content into the native image source
-    FrameBufferImage targetBuffer = FrameBufferImage::New( *nativeImageSourcePtr );
-
-    CameraActor cameraActor = CameraActor::New(imageSize);
-    cameraActor.SetParentOrigin(ParentOrigin::TOP_CENTER);
-    cameraActor.SetParentOrigin( AnchorPoint::TOP_CENTER );
-    cameraActor.SetY( buttonHeight + imageSize.height/2.f );
-    stage.Add(cameraActor);
-
-    RenderTaskList taskList = stage.GetRenderTaskList();
-    mOffscreenRenderTask = taskList.CreateTask();
-    mOffscreenRenderTask.SetSourceActor( sourceActor );
-    mOffscreenRenderTask.SetClearColor( Color::WHITE );
-    mOffscreenRenderTask.SetClearEnabled(true);
-    mOffscreenRenderTask.SetCameraActor(cameraActor);
-    mOffscreenRenderTask.GetCameraActor().SetInvertYAxis(true);
-    mOffscreenRenderTask.SetTargetFrameBuffer( targetBuffer );
-    mOffscreenRenderTask.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
-
-    // Display the native image on the screen
-    NativeImage nativeImage = NativeImage::New( *nativeImageSourcePtr );
-    ImageView nativeImageView = ImageView::New( nativeImage );
-    nativeImageView.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
-    nativeImageView.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-    stage.Add( nativeImageView );
-
-    TextLabel textLabel1 = TextLabel::New( "Resource Image" );
-    textLabel1.SetParentOrigin( ParentOrigin::TOP_CENTER );
-    textLabel1.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-    nativeImageView.Add( textLabel1 );
-
-    TextLabel textLabel2 = TextLabel::New( "Native Image" );
-    textLabel2.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
-    textLabel2.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
-    nativeImageView.Add( textLabel2 );
-
-    return false;
+    TextLabel textLabel1 = TextLabel::New("Image");
+    textLabel1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
+    textLabel1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
+    mTopContentArea.Add(textLabel1);
+
+    // Wait until button press before creating mOffscreenRenderTask
+
+    TextLabel textLabel2 = TextLabel::New("Native Image");
+    textLabel2.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER);
+    textLabel2.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER);
+    mBottomContentArea.Add(textLabel2);
   }
 
-  bool OnButtonSelected( Toolkit::Button button )
+  void SetupNativeImage()
   {
-    Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast( button );
-    if( pushButton == mButtonRefreshAlways )
+    if(!mOffscreenRenderTask)
     {
-      if( mButtonRefreshAlways.IsSelected() )
-      {
-        mOffscreenRenderTask.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
-      }
-      else
+      Window  window     = mApplication.GetWindow();
+      Vector2 windowSize = window.GetSize();
+
+      float   contentHeight((windowSize.y - BUTTON_HEIGHT) / 2.0f);
+      Vector2 imageSize(windowSize.x, contentHeight);
+
+      mNativeImageSourcePtr = NativeImageSource::New(imageSize.width, imageSize.height, NativeImageSource::COLOR_DEPTH_DEFAULT);
+      mNativeTexture        = Texture::New(*mNativeImageSourcePtr);
+
+      mFrameBuffer = FrameBuffer::New(mNativeTexture.GetWidth(), mNativeTexture.GetHeight(), FrameBuffer::Attachment::NONE);
+      mFrameBuffer.AttachColorTexture(mNativeTexture);
+
+      mCameraActor = CameraActor::New(imageSize);
+      mCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+      mCameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
+      mTopContentArea.Add(mCameraActor);
+
+      RenderTaskList taskList = window.GetRenderTaskList();
+      mOffscreenRenderTask    = taskList.CreateTask();
+      mOffscreenRenderTask.SetSourceActor(mSourceActor);
+      mOffscreenRenderTask.SetClearColor(Color::WHITE);
+      mOffscreenRenderTask.SetClearEnabled(true);
+      mOffscreenRenderTask.SetCameraActor(mCameraActor);
+      mOffscreenRenderTask.GetCameraActor().SetInvertYAxis(true);
+      mOffscreenRenderTask.SetFrameBuffer(mFrameBuffer);
+    }
+
+    if(mRefreshAlways)
+    {
+      mOffscreenRenderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
+    }
+    else
+    {
+      mOffscreenRenderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
+    }
+  }
+
+  void SetupDisplayActor(bool show)
+  {
+    if(show)
+    {
+      if(!mDisplayActor)
       {
-        mOffscreenRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
+        // Make sure we have something to display
+        SetupNativeImage();
+
+        mDisplayActor = Actor::New();
+        mDisplayActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+        mDisplayActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+
+        Geometry geometry = DemoHelper::CreateTexturedQuad();
+
+        Shader shader = CreateShader(*mNativeImageSourcePtr);
+
+        Renderer renderer = Renderer::New(geometry, shader);
+
+        TextureSet textureSet = TextureSet::New();
+        textureSet.SetTexture(0u, mNativeTexture);
+        renderer.SetTextures(textureSet);
+
+        mDisplayActor.AddRenderer(renderer);
+        mDisplayActor.SetProperty(Actor::Property::SIZE, Vector2(mNativeTexture.GetWidth(), mNativeTexture.GetHeight()));
+
+        mBottomContentArea.Add(mDisplayActor);
       }
     }
-    else if( pushButton == mButtonRefreshOnce )
+    else
+    {
+      UnparentAndReset(mDisplayActor);
+    }
+  }
+
+  void Capture()
+  {
+    mRefreshAlways = false;
+    SetupNativeImage();
+
+    mOffscreenRenderTask.FinishedSignal().Connect(this, &NativeImageSourceController::DoCapture);
+  }
+
+  void DoCapture(RenderTask& task)
+  {
+    task.FinishedSignal().Disconnect(this, &NativeImageSourceController::DoCapture);
+
+    mNativeImageSourcePtr->EncodeToFile(CAPTURE_FILENAME);
+  }
+
+  void Reset()
+  {
+    SetupDisplayActor(false);
+
+    Window         window   = mApplication.GetWindow();
+    RenderTaskList taskList = window.GetRenderTaskList();
+    taskList.RemoveTask(mOffscreenRenderTask);
+    mOffscreenRenderTask.Reset();
+    mCameraActor.Reset();
+
+    mFrameBuffer.Reset();
+    mNativeTexture.Reset();
+    mNativeImageSourcePtr.Reset();
+  }
+
+  bool OnButtonSelected(Toolkit::Button button)
+  {
+    Toolkit::PushButton pushButton = Toolkit::PushButton::DownCast(button);
+
+    if(pushButton == mButtonShow)
     {
-      if( mButtonRefreshAlways.IsSelected() )
+      bool isSelected = mButtonShow.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
+
+      SetupDisplayActor(isSelected);
+    }
+    else if(pushButton == mButtonRefreshAlways)
+    {
+      bool isSelected = mButtonRefreshAlways.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
+
+      mRefreshAlways = isSelected;
+      SetupNativeImage();
+    }
+    else if(pushButton == mButtonRefreshOnce)
+    {
+      bool isSelected = mButtonRefreshAlways.GetProperty(Toolkit::Button::Property::SELECTED).Get<bool>();
+
+      if(isSelected)
       {
-        mButtonRefreshAlways.SetSelected( false );
+        mButtonRefreshAlways.SetProperty(Button::Property::SELECTED, false);
       }
-      mOffscreenRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
+
+      mRefreshAlways = false;
+      SetupNativeImage();
+    }
+    else if(pushButton == mButtonCapture)
+    {
+      Capture();
+    }
+    else if(pushButton == mButtonReset)
+    {
+      Reset();
     }
 
     return true;
@@ -169,9 +383,9 @@ public:
 
   void OnKeyEvent(const KeyEvent& event)
   {
-    if(event.state == KeyEvent::Down)
+    if(event.GetState() == KeyEvent::DOWN)
     {
-      if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
+      if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
       {
         mApplication.Quit();
       }
@@ -179,27 +393,36 @@ public:
   }
 
 private:
-  Application&  mApplication;
-  RenderTask mOffscreenRenderTask;
+  Application& mApplication;
+
+  Layer mButtonArea;
+  Actor mTopContentArea;
+  Actor mBottomContentArea;
+
+  PushButton mButtonShow;
   PushButton mButtonRefreshAlways;
   PushButton mButtonRefreshOnce;
+  PushButton mButtonCapture;
+  PushButton mButtonReset;
 
-};
+  Actor mSourceActor;
 
-void RunTest( Application& application )
-{
-  NativeImageSourceController test( application );
+  NativeImageSourcePtr mNativeImageSourcePtr;
+  Texture              mNativeTexture;
+  FrameBuffer          mFrameBuffer;
 
-  application.MainLoop();
-}
+  RenderTask  mOffscreenRenderTask;
+  CameraActor mCameraActor;
 
-// Entry point for Linux & Tizen applications
-//
-int DALI_EXPORT_API main( int argc, char **argv )
-{
-  Application application = Application::New( &argc, &argv );
+  Actor mDisplayActor;
 
-  RunTest( application );
+  bool mRefreshAlways;
+};
 
+int DALI_EXPORT_API main(int argc, char** argv)
+{
+  Application                 application = Application::New(&argc, &argv);
+  NativeImageSourceController test(application);
+  application.MainLoop();
   return 0;
 }