Merge "Added FileReader and FileWriter classes to wrap FileCloser" into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / common / adaptor-impl.cpp
index ecaa1e2..7261e4e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@
 #include "adaptor-impl.h"
 
 // EXTERNAL INCLUDES
 #include "adaptor-impl.h"
 
 // EXTERNAL INCLUDES
-#include <boost/thread/tss.hpp>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/core.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/events/touch-event-integ.h>
 
 // INTERNAL INCLUDES
-#include <base/update-render-controller.h>
-#include <base/environment-variables.h>
+#include <base/thread-controller.h>
 #include <base/performance-logging/performance-interface-factory.h>
 #include <base/lifecycle-observer.h>
 
 #include <base/performance-logging/performance-interface-factory.h>
 #include <base/lifecycle-observer.h>
 
+#include <dali/devel-api/text-abstraction/font-client.h>
+
 #include <callback-manager.h>
 #include <callback-manager.h>
-#include <trigger-event.h>
-#include <window-render-surface.h>
-#include <render-surface-impl.h>
+#include <render-surface.h>
 #include <tts-player-impl.h>
 #include <tts-player-impl.h>
-#include <accessibility-manager-impl.h>
-#include <timer-impl.h>
+#include <accessibility-adaptor-impl.h>
 #include <events/gesture-manager.h>
 #include <events/event-handler.h>
 #include <events/gesture-manager.h>
 #include <events/event-handler.h>
-#include <feedback/feedback-controller.h>
-#include <feedback/feedback-plugin-proxy.h>
 #include <gl/gl-proxy-implementation.h>
 #include <gl/gl-implementation.h>
 #include <gl/egl-sync-implementation.h>
 #include <gl/gl-proxy-implementation.h>
 #include <gl/gl-implementation.h>
 #include <gl/egl-sync-implementation.h>
 #include <clipboard-impl.h>
 #include <vsync-monitor.h>
 #include <object-profiler.h>
 #include <clipboard-impl.h>
 #include <vsync-monitor.h>
 #include <object-profiler.h>
+#include <base/display-connection.h>
+#include <window-impl.h>
 
 #include <tizen-logging.h>
 
 #include <tizen-logging.h>
+#include <image-loading.h>
 
 
-
+using Dali::TextAbstraction::FontClient;
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -70,52 +68,13 @@ namespace Adaptor
 
 namespace
 {
 
 namespace
 {
-boost::thread_specific_ptr<Adaptor> gThreadLocalAdaptor;
-
-unsigned int GetIntegerEnvironmentVariable( const char* variable, unsigned int defaultValue )
-{
-  const char* variableParameter = std::getenv(variable);
-
-  // if the parameter exists convert it to an integer, else return the default value
-  unsigned int intValue = variableParameter ? atoi(variableParameter) : defaultValue;
-  return intValue;
-}
-
-bool GetIntegerEnvironmentVariable( const char* variable, int& intValue )
-{
-  const char* variableParameter = std::getenv(variable);
-
-  if( !variableParameter )
-  {
-    return false;
-  }
-  // if the parameter exists convert it to an integer, else return the default value
-  intValue = atoi(variableParameter);
-  return true;
-}
-
-bool GetFloatEnvironmentVariable( const char* variable, float& floatValue )
-{
-  const char* variableParameter = std::getenv(variable);
-
-  if( !variableParameter )
-  {
-    return false;
-  }
-  // if the parameter exists convert it to an integer, else return the default value
-  floatValue = atof(variableParameter);
-  return true;
-}
-
+__thread Adaptor* gThreadLocalAdaptor = NULL; // raw thread specific pointer to allow Adaptor::Get
 } // unnamed namespace
 
 } // unnamed namespace
 
-Dali::Adaptor* Adaptor::New( RenderSurface *surface, const DeviceLayout& baseLayout,
-                             Dali::Configuration::ContextLoss configuration )
+Dali::Adaptor* Adaptor::New( Any nativeWindow, RenderSurface *surface, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
 {
 {
-  DALI_ASSERT_ALWAYS( surface->GetType() != Dali::RenderSurface::NO_SURFACE && "No surface for adaptor" );
-
   Dali::Adaptor* adaptor = new Dali::Adaptor;
   Dali::Adaptor* adaptor = new Dali::Adaptor;
-  Adaptor* impl = new Adaptor( *adaptor, surface, baseLayout );
+  Adaptor* impl = new Adaptor( nativeWindow, *adaptor, surface, environmentOptions );
   adaptor->mImpl = impl;
 
   impl->Initialize(configuration);
   adaptor->mImpl = impl;
 
   impl->Initialize(configuration);
@@ -123,111 +82,22 @@ Dali::Adaptor* Adaptor::New( RenderSurface *surface, const DeviceLayout& baseLay
   return adaptor;
 }
 
   return adaptor;
 }
 
-void Adaptor::ParseEnvironmentOptions()
+Dali::Adaptor* Adaptor::New( Dali::Window window, Dali::Configuration::ContextLoss configuration, EnvironmentOptions* environmentOptions )
 {
 {
-  // get logging options
-  unsigned int logFrameRateFrequency = GetIntegerEnvironmentVariable( DALI_ENV_FPS_TRACKING, 0 );
-  unsigned int logupdateStatusFrequency = GetIntegerEnvironmentVariable( DALI_ENV_UPDATE_STATUS_INTERVAL, 0 );
-  unsigned int logPerformanceStats = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS, 0 );
-  unsigned int logPerformanceStatsFrequency = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PERFORMANCE_STATS_FREQUENCY, 0 );
-  unsigned int performanceTimeStampOutput= GetIntegerEnvironmentVariable( DALI_ENV_PERFORMANCE_TIMESTAMP_OUTPUT, 0 );
-  unsigned int networkControl= GetIntegerEnvironmentVariable( DALI_ENV_NETWORK_CONTROL, 0 );
-
-  unsigned int logPanGesture = GetIntegerEnvironmentVariable( DALI_ENV_LOG_PAN_GESTURE, 0 );
-
-  // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
-  Dali::Integration::Log::LogFunction  logFunction(Dali::TizenPlatform::LogMessage);
-
-  mEnvironmentOptions.SetLogOptions( logFunction, networkControl, logFrameRateFrequency, logupdateStatusFrequency, logPerformanceStats, logPerformanceStatsFrequency, performanceTimeStampOutput, logPanGesture );
+  Any winId = window.GetNativeHandle();
 
 
-  int predictionMode;
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_MODE, predictionMode) )
-  {
-    mEnvironmentOptions.SetPanGesturePredictionMode(predictionMode);
-  }
-  int predictionAmount(-1);
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_AMOUNT, predictionAmount) )
-  {
-    if( predictionAmount < 0 )
-    {
-      // do not support times in the past
-      predictionAmount = 0;
-    }
-    mEnvironmentOptions.SetPanGesturePredictionAmount(predictionAmount);
-  }
-  int minPredictionAmount(-1);
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MIN_PREDICTION_AMOUNT, minPredictionAmount) )
-  {
-    if( minPredictionAmount < 0 )
-    {
-      // do not support times in the past
-      minPredictionAmount = 0;
-    }
-    mEnvironmentOptions.SetPanGestureMinimumPredictionAmount(minPredictionAmount);
-  }
-  int maxPredictionAmount(-1);
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MAX_PREDICTION_AMOUNT, maxPredictionAmount) )
-  {
-    if( minPredictionAmount > -1 && maxPredictionAmount < minPredictionAmount )
-    {
-      // maximum amount should not be smaller than minimum amount
-      maxPredictionAmount = minPredictionAmount;
-    }
-    mEnvironmentOptions.SetPanGestureMaximumPredictionAmount(maxPredictionAmount);
-  }
-  int predictionAmountAdjustment(-1);
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_PREDICTION_AMOUNT_ADJUSTMENT, predictionAmountAdjustment) )
-  {
-    if( predictionAmountAdjustment < 0 )
-    {
-      // negative amount doesn't make sense
-      predictionAmountAdjustment = 0;
-    }
-    mEnvironmentOptions.SetPanGesturePredictionAmountAdjustment(predictionAmountAdjustment);
-  }
-  int smoothingMode;
-  if( GetIntegerEnvironmentVariable(DALI_ENV_PAN_SMOOTHING_MODE, smoothingMode) )
-  {
-    mEnvironmentOptions.SetPanGestureSmoothingMode(smoothingMode);
-  }
-  float smoothingAmount = 1.0f;
-  if( GetFloatEnvironmentVariable(DALI_ENV_PAN_SMOOTHING_AMOUNT, smoothingAmount) )
-  {
-    smoothingAmount = Clamp(smoothingAmount, 0.0f, 1.0f);
-    mEnvironmentOptions.SetPanGestureSmoothingAmount(smoothingAmount);
-  }
-
-  int minimumDistance(-1);
-  if ( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MINIMUM_DISTANCE, minimumDistance ))
-  {
-    mEnvironmentOptions.SetMinimumPanDistance( minimumDistance );
-  }
-
-  int minimumEvents(-1);
-  if ( GetIntegerEnvironmentVariable(DALI_ENV_PAN_MINIMUM_EVENTS, minimumEvents ))
-  {
-    mEnvironmentOptions.SetMinimumPanEvents( minimumEvents );
-  }
-
-  int glesCallTime(0);
-  if ( GetIntegerEnvironmentVariable(DALI_GLES_CALL_TIME, glesCallTime ))
-  {
-    mEnvironmentOptions.SetGlesCallTime( glesCallTime );
-  }
-
-  int windowWidth(0), windowHeight(0);
-  if ( GetIntegerEnvironmentVariable( DALI_WINDOW_WIDTH, windowWidth ) && GetIntegerEnvironmentVariable( DALI_WINDOW_HEIGHT, windowHeight ) )
-  {
-    mEnvironmentOptions.SetWindowWidth( windowWidth );
-    mEnvironmentOptions.SetWindowHeight( windowHeight );
-  }
-
-  mEnvironmentOptions.InstallLogFunction();
+  Window& windowImpl = Dali::GetImplementation(window);
+  Dali::Adaptor* adaptor = New( winId, windowImpl.GetSurface(), configuration, environmentOptions );
+  windowImpl.SetAdaptor(*adaptor);
+  return adaptor;
 }
 
 }
 
-void Adaptor::Initialize(Dali::Configuration::ContextLoss configuration)
+void Adaptor::Initialize( Dali::Configuration::ContextLoss configuration )
 {
 {
-  ParseEnvironmentOptions();
+  // all threads here (event, update, and render) will send their logs to TIZEN Platform's LogMessage handler.
+  Dali::Integration::Log::LogFunction logFunction( Dali::TizenPlatform::LogMessage );
+  mEnvironmentOptions->SetLogFunction( logFunction );
+  mEnvironmentOptions->InstallLogFunction(); // install logging for main thread
 
   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
 
 
   mPlatformAbstraction = new TizenPlatform::TizenPlatformAbstraction;
 
@@ -238,83 +108,87 @@ void Adaptor::Initialize(Dali::Configuration::ContextLoss configuration)
   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
   {
   ResourcePolicy::DataRetention dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
   if( configuration == Dali::Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS )
   {
-    dataRetentionPolicy = ResourcePolicy::DALI_RETAINS_MESH_DATA;
+    dataRetentionPolicy = ResourcePolicy::DALI_DISCARDS_ALL_DATA;
   }
   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
   // files automatically.
 
   }
   // Note, Tizen does not use DALI_RETAINS_ALL_DATA, as it can reload images from
   // files automatically.
 
-  if( mEnvironmentOptions.PerformanceServerRequired() )
+  if( mEnvironmentOptions->PerformanceServerRequired() )
   {
   {
-    mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, mEnvironmentOptions );
+    mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, *mEnvironmentOptions );
   }
 
   mCallbackManager = CallbackManager::New();
 
   PositionSize size = mSurface->GetPositionSize();
 
   }
 
   mCallbackManager = CallbackManager::New();
 
   PositionSize size = mSurface->GetPositionSize();
 
-  mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, mEnvironmentOptions);
+  mGestureManager = new GestureManager(*this, Vector2(size.width, size.height), mCallbackManager, *mEnvironmentOptions);
 
 
-  if( mEnvironmentOptions.GetGlesCallTime() > 0 )
+  if( mEnvironmentOptions->GetGlesCallTime() > 0 )
   {
   {
-    mGLES = new GlProxyImplementation( mEnvironmentOptions );
+    mGLES = new GlProxyImplementation( *mEnvironmentOptions );
   }
   else
   {
     mGLES = new GlImplementation();
   }
 
   }
   else
   {
     mGLES = new GlImplementation();
   }
 
-  mEglFactory = new EglFactory();
+  mEglFactory = new EglFactory( mEnvironmentOptions->GetMultiSamplingLevel() );
 
   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
 
   mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
 
 
   EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
 
   mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
 
-  mObjectProfiler = new ObjectProfiler();
+  const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
+  if( 0u < timeInterval )
+  {
+    mObjectProfiler = new ObjectProfiler( timeInterval );
+  }
 
 
-  mNotificationTrigger = new TriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ) );
+  mNotificationTrigger = mTriggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Adaptor::ProcessCoreEvents ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
 
   mVSyncMonitor = new VSyncMonitor;
 
 
   mVSyncMonitor = new VSyncMonitor;
 
-  mUpdateRenderController = new UpdateRenderController( *this, mEnvironmentOptions );
-
-  mDaliFeedbackPlugin = new FeedbackPluginProxy( FeedbackPluginProxy::DEFAULT_OBJECT_NAME );
+  mThreadController = new ThreadController( *this, *mEnvironmentOptions );
 
   // Should be called after Core creation
 
   // Should be called after Core creation
-  if( mEnvironmentOptions.GetPanGestureLoggingLevel() )
+  if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
   {
     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
   }
   {
     Integration::EnableProfiling( Dali::Integration::PROFILING_TYPE_PAN_GESTURE );
   }
-  if( mEnvironmentOptions.GetPanGesturePredictionMode() >= 0 )
+  if( mEnvironmentOptions->GetPanGesturePredictionMode() >= 0 )
   {
   {
-    Integration::SetPanGesturePredictionMode(mEnvironmentOptions.GetPanGesturePredictionMode());
+    Integration::SetPanGesturePredictionMode(mEnvironmentOptions->GetPanGesturePredictionMode());
   }
   }
-  if( mEnvironmentOptions.GetPanGesturePredictionAmount() >= 0 )
+  if( mEnvironmentOptions->GetPanGesturePredictionAmount() >= 0 )
   {
   {
-    Integration::SetPanGesturePredictionAmount(mEnvironmentOptions.GetPanGesturePredictionAmount());
+    Integration::SetPanGesturePredictionAmount(mEnvironmentOptions->GetPanGesturePredictionAmount());
   }
   }
-  if( mEnvironmentOptions.GetPanGestureMaximumPredictionAmount() >= 0 )
+  if( mEnvironmentOptions->GetPanGestureMaximumPredictionAmount() >= 0 )
   {
   {
-    Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions.GetPanGestureMaximumPredictionAmount());
+    Integration::SetPanGestureMaximumPredictionAmount(mEnvironmentOptions->GetPanGestureMaximumPredictionAmount());
   }
   }
-  if( mEnvironmentOptions.GetPanGestureMinimumPredictionAmount() >= 0 )
+  if( mEnvironmentOptions->GetPanGestureMinimumPredictionAmount() >= 0 )
   {
   {
-    Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions.GetPanGestureMinimumPredictionAmount());
+    Integration::SetPanGestureMinimumPredictionAmount(mEnvironmentOptions->GetPanGestureMinimumPredictionAmount());
   }
   }
-  if( mEnvironmentOptions.GetPanGesturePredictionAmountAdjustment() >= 0 )
+  if( mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment() >= 0 )
   {
   {
-    Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions.GetPanGesturePredictionAmountAdjustment());
+    Integration::SetPanGesturePredictionAmountAdjustment(mEnvironmentOptions->GetPanGesturePredictionAmountAdjustment());
   }
   }
-  if( mEnvironmentOptions.GetPanGestureSmoothingMode() >= 0 )
+  if( mEnvironmentOptions->GetPanGestureSmoothingMode() >= 0 )
   {
   {
-    Integration::SetPanGestureSmoothingMode(mEnvironmentOptions.GetPanGestureSmoothingMode());
+    Integration::SetPanGestureSmoothingMode(mEnvironmentOptions->GetPanGestureSmoothingMode());
   }
   }
-  if( mEnvironmentOptions.GetPanGestureSmoothingAmount() >= 0.0f )
+  if( mEnvironmentOptions->GetPanGestureSmoothingAmount() >= 0.0f )
   {
   {
-    Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions.GetPanGestureSmoothingAmount());
+    Integration::SetPanGestureSmoothingAmount(mEnvironmentOptions->GetPanGestureSmoothingAmount());
   }
   }
-  if( mEnvironmentOptions.GetWindowWidth() && mEnvironmentOptions.GetWindowHeight() )
+
+  // Set max texture size
+  if( mEnvironmentOptions->GetMaxTextureSize() > 0 )
   {
   {
-    SurfaceResized( PositionSize( 0, 0, mEnvironmentOptions.GetWindowWidth(), mEnvironmentOptions.GetWindowHeight() ));
+    Dali::SetMaxTextureSize( mEnvironmentOptions->GetMaxTextureSize() );
   }
 }
 
   }
 }
 
@@ -323,24 +197,21 @@ Adaptor::~Adaptor()
   // Ensure stop status
   Stop();
 
   // Ensure stop status
   Stop();
 
-  // Release first as we do not want any access to Adaptor as it is being destroyed.
-  gThreadLocalAdaptor.release();
+  // set to NULL first as we do not want any access to Adaptor as it is being destroyed.
+  gThreadLocalAdaptor = NULL;
 
   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
   {
     (*iter)->OnDestroy();
   }
 
 
   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
   {
     (*iter)->OnDestroy();
   }
 
-  delete mUpdateRenderController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
+  delete mThreadController; // this will shutdown render thread, which will call Core::ContextDestroyed before exit
   delete mVSyncMonitor;
   delete mEventHandler;
   delete mObjectProfiler;
 
   delete mCore;
   delete mEglFactory;
   delete mVSyncMonitor;
   delete mEventHandler;
   delete mObjectProfiler;
 
   delete mCore;
   delete mEglFactory;
-  // Delete feedback controller before feedback plugin & style monitor dependencies
-  delete mFeedbackController;
-  delete mDaliFeedbackPlugin;
   delete mGLES;
   delete mGestureManager;
   delete mPlatformAbstraction;
   delete mGLES;
   delete mGestureManager;
   delete mPlatformAbstraction;
@@ -349,6 +220,12 @@ Adaptor::~Adaptor()
 
   // uninstall it on this thread (main actor thread)
   Dali::Integration::Log::UninstallLogFunction();
 
   // uninstall it on this thread (main actor thread)
   Dali::Integration::Log::UninstallLogFunction();
+
+  // Delete environment options if we own it
+  if( mEnvironmentOptionsOwned )
+  {
+    delete mEnvironmentOptions;
+  }
 }
 
 void Adaptor::Start()
 }
 
 void Adaptor::Start()
@@ -372,41 +249,28 @@ void Adaptor::Start()
     mDeferredRotationObserver = NULL;
   }
 
     mDeferredRotationObserver = NULL;
   }
 
-  // guarantee map the surface before starting render-thread.
-  mSurface->Map();
+  unsigned int dpiHor, dpiVer;
+  dpiHor = dpiVer = 0;
+  Dali::DisplayConnection::GetDpi(dpiHor, dpiVer);
 
 
-  // use default or command line settings if not run on device
-  if( mHDpi == 0 || mVDpi == 0 )
-  {
-    unsigned int dpiHor, dpiVer;
-    dpiHor = dpiVer = 0;
-    mSurface->GetDpi(dpiHor, dpiVer);
+  // tell core about the DPI value
+  mCore->SetDpi(dpiHor, dpiVer);
 
 
-    // tell core about the value
-    mCore->SetDpi(dpiHor, dpiVer);
-  }
-  else
-  {
-    mCore->SetDpi(mHDpi, mVDpi);
-  }
+  // set the DPI value for font rendering
+  FontClient fontClient = FontClient::Get();
+  fontClient.SetDpi( dpiHor, dpiVer );
 
   // Tell the core the size of the surface just before we start the render-thread
   PositionSize size = mSurface->GetPositionSize();
   mCore->SurfaceResized( size.width, size.height );
 
 
   // Tell the core the size of the surface just before we start the render-thread
   PositionSize size = mSurface->GetPositionSize();
   mCore->SurfaceResized( size.width, size.height );
 
-  // Start the update & render threads
-  mUpdateRenderController->Start();
+  // Initialize the thread controller
+  mThreadController->Initialize();
 
   mState = RUNNING;
 
   ProcessCoreEvents(); // Ensure any startup messages are processed.
 
 
   mState = RUNNING;
 
   ProcessCoreEvents(); // Ensure any startup messages are processed.
 
-  if ( !mFeedbackController )
-  {
-    // Start sound & haptic feedback
-    mFeedbackController = new FeedbackController( *mDaliFeedbackPlugin );
-  }
-
   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
   {
     (*iter)->OnStart();
   for ( ObserverContainer::iterator iter = mObservers.begin(), endIter = mObservers.end(); iter != endIter; ++iter )
   {
     (*iter)->OnStart();
@@ -428,10 +292,10 @@ void Adaptor::Pause()
     // Reset the event handler when adaptor paused
     if( mEventHandler )
     {
     // Reset the event handler when adaptor paused
     if( mEventHandler )
     {
-      mEventHandler->Reset();
+      mEventHandler->Pause();
     }
 
     }
 
-    mUpdateRenderController->Pause();
+    mThreadController->Pause();
     mCore->Suspend();
     mState = PAUSED;
   }
     mCore->Suspend();
     mState = PAUSED;
   }
@@ -443,24 +307,12 @@ void Adaptor::Resume()
   // Only resume the adaptor if we are in the suspended state.
   if( PAUSED == mState )
   {
   // Only resume the adaptor if we are in the suspended state.
   if( PAUSED == mState )
   {
-    // We put ResumeFrameTime first, as this was originally called at the start of mCore->Resume()
-    // If there were events pending, mCore->Resume() will call
-    //   RenderController->RequestUpdate()
-    //     UpdateRenderController->RequestUpdate()
-    //       UpdateRenderSynchronization->RequestUpdate()
-    // and we should have reset the frame timers before allowing Core->Update() to be called.
-    //@todo Should we call UpdateRenderController->Resume before mCore->Resume()?
-
-    mUpdateRenderController->ResumeFrameTime();
-    mCore->Resume();
-    mUpdateRenderController->Resume();
-
     mState = RUNNING;
 
     // Reset the event handler when adaptor resumed
     if( mEventHandler )
     {
     mState = RUNNING;
 
     // Reset the event handler when adaptor resumed
     if( mEventHandler )
     {
-      mEventHandler->Reset();
+      mEventHandler->Resume();
     }
 
     // Inform observers that we have resumed.
     }
 
     // Inform observers that we have resumed.
@@ -469,7 +321,11 @@ void Adaptor::Resume()
       (*iter)->OnResume();
     }
 
       (*iter)->OnResume();
     }
 
-    ProcessCoreEvents(); // Ensure any outstanding messages are processed
+    // Resume core so it processes any requests as well
+    mCore->Resume();
+
+    // Do at end to ensure our first update/render after resumption includes the processed messages as well
+    mThreadController->Resume();
   }
 }
 
   }
 }
 
@@ -484,7 +340,7 @@ void Adaptor::Stop()
       (*iter)->OnStop();
     }
 
       (*iter)->OnStop();
     }
 
-    mUpdateRenderController->Stop();
+    mThreadController->Stop();
     mCore->Suspend();
 
     // Delete the TTS player
     mCore->Suspend();
 
     // Delete the TTS player
@@ -508,87 +364,55 @@ void Adaptor::Stop()
   }
 }
 
   }
 }
 
-void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
+void Adaptor::ContextLost()
 {
 {
-  mEventHandler->FeedTouchPoint( point, timeStamp );
+  mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
 }
 
 }
 
-void Adaptor::FeedWheelEvent( MouseWheelEvent& wheelEvent )
+void Adaptor::ContextRegained()
 {
 {
-  mEventHandler->FeedWheelEvent( wheelEvent );
+  // Inform core, so that texture resources can be reloaded
+  mCore->RecoverFromContextLoss();
+
+  mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
 }
 
 }
 
-void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
+void Adaptor::FeedTouchPoint( TouchPoint& point, int timeStamp )
 {
 {
-  mEventHandler->FeedKeyEvent( keyEvent );
+  mEventHandler->FeedTouchPoint( point, timeStamp );
 }
 
 }
 
-bool Adaptor::MoveResize( const PositionSize& positionSize )
+void Adaptor::FeedWheelEvent( WheelEvent& wheelEvent )
 {
 {
-  PositionSize old = mSurface->GetPositionSize();
-
-  // just resize the surface. The driver should automatically resize the egl Surface (untested)
-  // EGL Spec says : EGL window surfaces need to be resized when their corresponding native window
-  // is resized. Implementations typically use hooks into the OS and native window
-  // system to perform this resizing on demand, transparently to the client.
-  mSurface->MoveResize( positionSize );
-
-  if(old.width != positionSize.width || old.height != positionSize.height)
-  {
-    SurfaceSizeChanged(positionSize);
-  }
-
-  return true;
+  mEventHandler->FeedWheelEvent( wheelEvent );
 }
 
 }
 
-void Adaptor::SurfaceResized( const PositionSize& positionSize )
+void Adaptor::FeedKeyEvent( KeyEvent& keyEvent )
 {
 {
-  PositionSize old = mSurface->GetPositionSize();
-
-  // Called by an application, when it has resized a window outside of Dali.
-  // The EGL driver automatically detects X Window resize calls, and resizes
-  // the EGL surface for us.
-  mSurface->MoveResize( positionSize );
-
-  if(old.width != positionSize.width || old.height != positionSize.height)
-  {
-    SurfaceSizeChanged(positionSize);
-  }
+  mEventHandler->FeedKeyEvent( keyEvent );
 }
 
 }
 
-void Adaptor::ReplaceSurface( Dali::RenderSurface& surface )
+void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface )
 {
 {
-  // adaptor implementation needs the implementation of
-  RenderSurface* internalSurface = dynamic_cast<Internal::Adaptor::RenderSurface*>( &surface );
-  DALI_ASSERT_ALWAYS( internalSurface && "Incorrect surface" );
+  PositionSize positionSize = surface.GetPositionSize();
 
 
-  ECore::WindowRenderSurface* windowSurface = dynamic_cast<Internal::Adaptor::ECore::WindowRenderSurface*>( &surface);
-  if( windowSurface != NULL )
-  {
-    windowSurface->Map();
-    // @todo Restart event handler with new surface
-  }
+  // let the core know the surface size has changed
+  mCore->SurfaceResized( positionSize.width, positionSize.height );
 
 
-  mSurface = internalSurface;
+  mResizedSignal.Emit( mAdaptor );
 
 
-  SurfaceSizeChanged( internalSurface->GetPositionSize() );
+  mNativeWindow = nativeWindow;
+  mSurface = &surface;
 
 
-  // flush the event queue to give update and render threads chance
+  // flush the event queue to give the update-render thread chance
   // to start processing messages for new camera setup etc as soon as possible
   ProcessCoreEvents();
 
   // to start processing messages for new camera setup etc as soon as possible
   ProcessCoreEvents();
 
-  mCore->GetContextNotifier()->NotifyContextLost(); // Inform stage
-
   // this method blocks until the render thread has completed the replace.
   // this method blocks until the render thread has completed the replace.
-  mUpdateRenderController->ReplaceSurface(internalSurface);
-
-  // Inform core, so that texture resources can be reloaded
-  mCore->RecoverFromContextLoss();
-
-  mCore->GetContextNotifier()->NotifyContextRegained(); // Inform stage
+  mThreadController->ReplaceSurface(mSurface);
 }
 
 }
 
-Dali::RenderSurface& Adaptor::GetSurface() const
+RenderSurface& Adaptor::GetSurface() const
 {
   return *mSurface;
 }
 {
   return *mSurface;
 }
@@ -616,34 +440,31 @@ bool Adaptor::AddIdle( CallbackBase* callback )
   // Only add an idle if the Adaptor is actually running
   if( RUNNING == mState )
   {
   // Only add an idle if the Adaptor is actually running
   if( RUNNING == mState )
   {
-    idleAdded = mCallbackManager->AddCallback( callback, CallbackManager::IDLE_PRIORITY );
+    idleAdded = mCallbackManager->AddIdleCallback( callback );
   }
 
   return idleAdded;
 }
 
   }
 
   return idleAdded;
 }
 
-bool Adaptor::CallFromMainLoop( CallbackBase* callback )
+void Adaptor::RemoveIdle( CallbackBase* callback )
 {
 {
-  bool callAdded(false);
-
-  // Only allow the callback if the Adaptor is actually running
-  if ( RUNNING == mState )
-  {
-    callAdded = mCallbackManager->AddCallback( callback, CallbackManager::DEFAULT_PRIORITY );
-  }
-
-  return callAdded;
+  mCallbackManager->RemoveIdleCallback( callback );
 }
 
 Dali::Adaptor& Adaptor::Get()
 {
 }
 
 Dali::Adaptor& Adaptor::Get()
 {
-  DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() != NULL && "Adaptor not instantiated" );
+  DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" );
   return gThreadLocalAdaptor->mAdaptor;
 }
 
 bool Adaptor::IsAvailable()
 {
   return gThreadLocalAdaptor->mAdaptor;
 }
 
 bool Adaptor::IsAvailable()
 {
-  return gThreadLocalAdaptor.get() != NULL;
+  return gThreadLocalAdaptor != NULL;
+}
+
+void Adaptor::SceneCreated()
+{
+  mCore->SceneCreated();
 }
 
 Dali::Integration::Core& Adaptor::GetCore()
 }
 
 Dali::Integration::Core& Adaptor::GetCore()
@@ -653,7 +474,7 @@ Dali::Integration::Core& Adaptor::GetCore()
 
 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
 {
 
 void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
 {
-  mUpdateRenderController->SetRenderRefreshRate( numberOfVSyncsPerRender );
+  mThreadController->SetRenderRefreshRate( numberOfVSyncsPerRender );
 }
 
 void Adaptor::SetUseHardwareVSync( bool useHardware )
 }
 
 void Adaptor::SetUseHardwareVSync( bool useHardware )
@@ -661,12 +482,6 @@ void Adaptor::SetUseHardwareVSync( bool useHardware )
   mVSyncMonitor->SetUseHardwareVSync( useHardware );
 }
 
   mVSyncMonitor->SetUseHardwareVSync( useHardware );
 }
 
-void Adaptor::SetDpi(size_t hDpi, size_t vDpi)
-{
-  mHDpi = hDpi;
-  mVDpi = vDpi;
-}
-
 EglFactory& Adaptor::GetEGLFactory() const
 {
   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
 EglFactory& Adaptor::GetEGLFactory() const
 {
   DALI_ASSERT_DEBUG( mEglFactory && "EGL Factory not created" );
@@ -694,10 +509,11 @@ Dali::Integration::GlAbstraction& Adaptor::GetGlesInterface()
   return *mGLES;
 }
 
   return *mGLES;
 }
 
-TriggerEventInterface& Adaptor::GetTriggerEventInterface()
+TriggerEventInterface& Adaptor::GetProcessCoreEventsTrigger()
 {
   return *mNotificationTrigger;
 }
 {
   return *mNotificationTrigger;
 }
+
 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
 {
   return mTriggerEventFactory;
 TriggerEventFactoryInterface& Adaptor::GetTriggerEventFactoryInterface()
 {
   return mTriggerEventFactory;
@@ -712,16 +528,22 @@ RenderSurface* Adaptor::GetRenderSurfaceInterface()
 {
   return mSurface;
 }
 {
   return mSurface;
 }
+
 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
 {
   return mVSyncMonitor;
 }
 
 VSyncMonitorInterface* Adaptor::GetVSyncMonitorInterface()
 {
   return mVSyncMonitor;
 }
 
-KernelTraceInterface& Adaptor::GetKernelTraceInterface()
+TraceInterface& Adaptor::GetKernelTraceInterface()
 {
   return mKernelTracer;
 }
 
 {
   return mKernelTracer;
 }
 
+TraceInterface& Adaptor::GetSystemTraceInterface()
+{
+  return mSystemTracer;
+}
+
 PerformanceInterface* Adaptor::GetPerformanceInterface()
 {
   return mPerformanceInterface;
 PerformanceInterface* Adaptor::GetPerformanceInterface()
 {
   return mPerformanceInterface;
@@ -772,6 +594,15 @@ void Adaptor::SetMinimumPinchDistance(float distance)
   }
 }
 
   }
 }
 
+Any Adaptor::GetNativeWindowHandle()
+{
+  return mNativeWindow;
+}
+
+void Adaptor::SetUseRemoteSurface(bool useRemoteSurface)
+{
+  mUseRemoteSurface = useRemoteSurface;
+}
 
 void Adaptor::AddObserver( LifeCycleObserver& observer )
 {
 
 void Adaptor::AddObserver( LifeCycleObserver& observer )
 {
@@ -826,7 +657,7 @@ void Adaptor::RequestUpdate()
   if ( PAUSED  == mState ||
        RUNNING == mState )
   {
   if ( PAUSED  == mState ||
        RUNNING == mState )
   {
-    mUpdateRenderController->RequestUpdate();
+    mThreadController->RequestUpdate();
   }
 }
 
   }
 }
 
@@ -872,14 +703,35 @@ void Adaptor::OnDamaged( const DamageArea& area )
   RequestUpdate();
 }
 
   RequestUpdate();
 }
 
-void Adaptor::SurfaceSizeChanged(const PositionSize& positionSize)
+void Adaptor::SurfaceResizePrepare( Dali::Adaptor::SurfaceSize surfaceSize )
 {
   // let the core know the surface size has changed
 {
   // let the core know the surface size has changed
-  mCore->SurfaceResized(positionSize.width, positionSize.height);
+  mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() );
 
   mResizedSignal.Emit( mAdaptor );
 }
 
 
   mResizedSignal.Emit( mAdaptor );
 }
 
+void Adaptor::SurfaceResizeComplete( Dali::Adaptor::SurfaceSize surfaceSize )
+{
+  // flush the event queue to give the update-render thread chance
+  // to start processing messages for new camera setup etc as soon as possible
+  ProcessCoreEvents();
+
+  // this method blocks until the render thread has completed the resizing.
+  mThreadController->ResizeSurface();
+}
+
+void Adaptor::NotifySceneCreated()
+{
+  GetCore().SceneCreated();
+
+  // Start thread controller after the scene has been created
+  mThreadController->Start();
+
+  // process after surface is created (registering to remote surface provider if required)
+  SurfaceInitialized();
+}
+
 void Adaptor::NotifyLanguageChanged()
 {
   mLanguageChangedSignal.Emit( mAdaptor );
 void Adaptor::NotifyLanguageChanged()
 {
   mLanguageChangedSignal.Emit( mAdaptor );
@@ -889,13 +741,19 @@ void Adaptor::RequestUpdateOnce()
 {
   if( PAUSED_WHILE_HIDDEN != mState )
   {
 {
   if( PAUSED_WHILE_HIDDEN != mState )
   {
-    if( mUpdateRenderController )
+    if( mThreadController )
     {
     {
-      mUpdateRenderController->RequestUpdateOnce();
+      mThreadController->RequestUpdateOnce();
     }
   }
 }
 
     }
   }
 }
 
+void Adaptor::IndicatorSizeChanged(int height)
+{
+  // let the core know the indicator height is changed
+  mCore->SetTopMargin(height);
+}
+
 void Adaptor::ProcessCoreEventsFromIdle()
 {
   ProcessCoreEvents();
 void Adaptor::ProcessCoreEventsFromIdle()
 {
   ProcessCoreEvents();
@@ -904,37 +762,43 @@ void Adaptor::ProcessCoreEventsFromIdle()
   mNotificationOnIdleInstalled = false;
 }
 
   mNotificationOnIdleInstalled = false;
 }
 
-Adaptor::Adaptor(Dali::Adaptor& adaptor, RenderSurface* surface, const DeviceLayout& baseLayout)
+Adaptor::Adaptor(Any nativeWindow, Dali::Adaptor& adaptor, RenderSurface* surface, EnvironmentOptions* environmentOptions)
 : mResizedSignal(),
   mLanguageChangedSignal(),
 : mResizedSignal(),
   mLanguageChangedSignal(),
-  mAdaptor(adaptor),
-  mState(READY),
-  mCore(NULL),
-  mUpdateRenderController(NULL),
-  mVSyncMonitor(NULL),
+  mAdaptor( adaptor ),
+  mState( READY ),
+  mCore( NULL ),
+  mThreadController( NULL ),
+  mVSyncMonitor( NULL ),
   mGLES( NULL ),
   mGLES( NULL ),
+  mGlSync( NULL ),
   mEglFactory( NULL ),
   mEglFactory( NULL ),
+  mNativeWindow( nativeWindow ),
   mSurface( surface ),
   mPlatformAbstraction( NULL ),
   mEventHandler( NULL ),
   mCallbackManager( NULL ),
   mNotificationOnIdleInstalled( false ),
   mSurface( surface ),
   mPlatformAbstraction( NULL ),
   mEventHandler( NULL ),
   mCallbackManager( NULL ),
   mNotificationOnIdleInstalled( false ),
-  mNotificationTrigger(NULL),
-  mGestureManager(NULL),
-  mHDpi( 0 ),
-  mVDpi( 0 ),
-  mDaliFeedbackPlugin(NULL),
-  mFeedbackController(NULL),
+  mNotificationTrigger( NULL ),
+  mGestureManager( NULL ),
+  mDaliFeedbackPlugin(),
+  mFeedbackController( NULL ),
+  mTtsPlayers(),
   mObservers(),
   mDragAndDropDetector(),
   mObservers(),
   mDragAndDropDetector(),
-  mDeferredRotationObserver(NULL),
-  mBaseLayout(baseLayout),
-  mEnvironmentOptions(),
-  mPerformanceInterface(NULL),
-  mObjectProfiler(NULL)
-{
-  DALI_ASSERT_ALWAYS( gThreadLocalAdaptor.get() == NULL && "Cannot create more than one Adaptor per thread" );
-  gThreadLocalAdaptor.reset(this);
+  mDeferredRotationObserver( NULL ),
+  mEnvironmentOptions( environmentOptions ? environmentOptions : new EnvironmentOptions /* Create the options if not provided */),
+  mPerformanceInterface( NULL ),
+  mKernelTracer(),
+  mSystemTracer(),
+  mTriggerEventFactory(),
+  mObjectProfiler( NULL ),
+  mSocketFactory(),
+  mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
+  mUseRemoteSurface( false )
+{
+  DALI_ASSERT_ALWAYS( !IsAvailable() && "Cannot create more than one Adaptor per thread" );
+  gThreadLocalAdaptor = this;
 }
 
 // Stereoscopy
 }
 
 // Stereoscopy