mPanMinimumEvents(-1),
mGlesCallTime(0),
mWindowWidth( 0 ),
- mWindowHeight( 0 )
+ mWindowHeight( 0 ),
+ mThreadingMode( ThreadingMode::SEPARATE_UPDATE_RENDER )
{
ParseEnvironmentOptions();
}
return mWindowClassName;
}
+ThreadingMode::Type EnvironmentOptions::GetThreadingMode() const
+{
+ return mThreadingMode;
+}
+
bool EnvironmentOptions::PerformanceServerRequired() const
{
return ( ( GetPerformanceStatsLoggingOptions() > 0) ||
{
mWindowClassName = windowClassName;
}
+
+ int threadingMode(0);
+ if ( GetIntegerEnvironmentVariable( DALI_THREADING_MODE, threadingMode ) )
+ {
+ switch( threadingMode )
+ {
+ case ThreadingMode::SEPARATE_UPDATE_RENDER:
+ case ThreadingMode::COMBINED_UPDATE_RENDER:
+ case ThreadingMode::SINGLE_THREADED:
+ {
+ mThreadingMode = static_cast< ThreadingMode::Type >( threadingMode );
+ break;
+ }
+ }
+ }
}
} // Adaptor
// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
+// INTERNAL INCLUDES
+#include <base/threading-mode.h>
+
namespace Dali
{
namespace Internal
*/
const std::string& GetWindowClassName() const;
+ /**
+ * @return The thread mode that DALi should use.
+ */
+ ThreadingMode::Type GetThreadingMode() const;
+
private: // Internal
/**
int mGlesCallTime; ///< time in seconds between status updates
unsigned int mWindowWidth; ///< width of the window
unsigned int mWindowHeight; ///< height of the window
+ ThreadingMode::Type mThreadingMode; ///< threading mode
Dali::Integration::Log::LogFunction mLogFunction;
#define DALI_WINDOW_CLASS_NAME "DALI_WINDOW_CLASS_NAME"
+#define DALI_THREADING_MODE "DALI_THREADING_MODE"
+
} // namespace Adaptor
} // namespace Internal
$(base_adaptor_src_dir)/display-connection.cpp \
$(base_adaptor_src_dir)/environment-options.cpp \
$(base_adaptor_src_dir)/fps-tracker.cpp \
- $(base_adaptor_src_dir)/frame-time.cpp \
$(base_adaptor_src_dir)/render-helper.cpp \
- $(base_adaptor_src_dir)/render-request.cpp \
- $(base_adaptor_src_dir)/render-thread.cpp \
$(base_adaptor_src_dir)/thread-controller.cpp \
- $(base_adaptor_src_dir)/thread-synchronization.cpp \
$(base_adaptor_src_dir)/update-status-logger.cpp \
- $(base_adaptor_src_dir)/update-thread.cpp \
- $(base_adaptor_src_dir)/vsync-notifier.cpp \
$(base_adaptor_src_dir)/performance-logging/frame-time-stamp.cpp \
$(base_adaptor_src_dir)/performance-logging/frame-time-stats.cpp \
$(base_adaptor_src_dir)/performance-logging/performance-marker.cpp \
$(base_adaptor_src_dir)/performance-logging/statistics/stat-context.cpp \
- $(base_adaptor_src_dir)/performance-logging/statistics/stat-context-manager.cpp
+ $(base_adaptor_src_dir)/performance-logging/statistics/stat-context-manager.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/frame-time.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/separate-update-render-controller.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/render-request.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/render-thread.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/thread-synchronization.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/update-thread.cpp \
+ $(base_adaptor_src_dir)/separate-update-render/vsync-notifier.cpp
base_adaptor_networking_src_files = \
$(base_adaptor_src_dir)/performance-logging/networking/network-performance-protocol.cpp \
// INTERNAL INCLUDES
#include <base/interfaces/adaptor-internal-services.h>
-#include <base/thread-synchronization.h>
+#include <base/separate-update-render/thread-synchronization.h>
#include <base/environment-options.h>
namespace Dali
// INTERNAL INCLUDES
#include <base/render-helper.h>
-#include <base/render-request.h>
+#include <base/separate-update-render/render-request.h>
#include <egl-interface.h>
#include <render-surface.h> // needed for Dali::RenderSurface
--- /dev/null
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// CLASS HEADER
+#include "separate-update-render-controller.h"
+
+// INTERNAL INCLUDES
+#include <base/separate-update-render/update-thread.h>
+#include <base/separate-update-render/render-thread.h>
+#include <base/separate-update-render/thread-synchronization.h>
+#include <base/separate-update-render/vsync-notifier.h>
+#include <base/interfaces/adaptor-internal-services.h>
+#include <base/environment-options.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+SeparateUpdateRenderController::SeparateUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions )
+: ThreadControllerInterface(),
+ mAdaptorInterfaces( adaptorInterfaces ),
+ mUpdateThread( NULL ),
+ mRenderThread( NULL ),
+ mVSyncNotifier( NULL ),
+ mThreadSync( NULL ),
+ mNumberOfVSyncsPerRender( 1 )
+{
+ mThreadSync = new ThreadSynchronization( adaptorInterfaces, mNumberOfVSyncsPerRender );
+
+ mUpdateThread = new UpdateThread( *mThreadSync, adaptorInterfaces, environmentOptions );
+
+ mRenderThread = new RenderThread( *mThreadSync, adaptorInterfaces, environmentOptions );
+
+ mVSyncNotifier = new VSyncNotifier( *mThreadSync, adaptorInterfaces, environmentOptions );
+
+ // Set the thread-synchronization interface on the render-surface
+ RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
+ if( currentSurface )
+ {
+ currentSurface->SetThreadSynchronization( *mThreadSync );
+ }
+}
+
+SeparateUpdateRenderController::~SeparateUpdateRenderController()
+{
+ delete mVSyncNotifier;
+ delete mRenderThread;
+ delete mUpdateThread;
+ delete mThreadSync;
+}
+
+void SeparateUpdateRenderController::Initialize()
+{
+ // Notify the synchronization object before starting the threads
+ mThreadSync->Initialise();
+
+ // We want to the threads to be set up before they start
+ mUpdateThread->Start();
+ mRenderThread->Start();
+ mVSyncNotifier->Start();
+}
+
+void SeparateUpdateRenderController::Start()
+{
+ mThreadSync->Start();
+}
+
+void SeparateUpdateRenderController::Pause()
+{
+ mThreadSync->Pause();
+}
+
+void SeparateUpdateRenderController::Resume()
+{
+ mThreadSync->Resume();
+}
+
+void SeparateUpdateRenderController::Stop()
+{
+ // Notify the synchronization object before stopping the threads
+ mThreadSync->Stop();
+
+ mVSyncNotifier->Stop();
+ mUpdateThread->Stop();
+ mRenderThread->Stop();
+}
+
+void SeparateUpdateRenderController::RequestUpdate()
+{
+ mThreadSync->UpdateRequest();
+}
+
+void SeparateUpdateRenderController::RequestUpdateOnce()
+{
+ // if we are paused, need to allow one update
+ mThreadSync->UpdateOnce();
+}
+
+void SeparateUpdateRenderController::ReplaceSurface( RenderSurface* newSurface )
+{
+ // Set the thread-syncronization on the new surface
+ newSurface->SetThreadSynchronization( *mThreadSync );
+
+ // tell render thread to start the replace. This call will block until the replace
+ // has completed.
+ RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
+
+ // Ensure the current surface releases any locks to prevent deadlock.
+ currentSurface->StopRender();
+
+ mThreadSync->ReplaceSurface( newSurface );
+}
+
+void SeparateUpdateRenderController::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender )
+{
+ mNumberOfVSyncsPerRender = numberOfVSyncsPerRender;
+ mThreadSync->SetRenderRefreshRate(numberOfVSyncsPerRender);
+}
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_INTERNAL_MULTI_THREAD_CONTROLLER_H__
+#define __DALI_INTERNAL_MULTI_THREAD_CONTROLLER_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <base/thread-controller-interface.h>
+
+namespace Dali
+{
+
+class RenderSurface;
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+class UpdateThread;
+class RenderThread;
+class VSyncNotifier;
+class ThreadSynchronization;
+class AdaptorInternalServices;
+class EnvironmentOptions;
+
+/**
+ * Class to control multiple threads:
+ * - Main Event Thread
+ * - VSync Thread
+ * - Update Thread
+ * - Render Thread
+ */
+class SeparateUpdateRenderController : public ThreadControllerInterface
+{
+public:
+
+ /**
+ * Constructor
+ */
+ SeparateUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions );
+
+ /**
+ * Non virtual destructor. Not intended as base class.
+ */
+ ~SeparateUpdateRenderController();
+
+ /**
+ * @copydoc ThreadControllerInterface::Initialize()
+ */
+ void Initialize();
+
+ /**
+ * @copydoc ThreadControllerInterface::Start()
+ */
+ void Start();
+
+ /**
+ * @copydoc ThreadControllerInterface::Pause()
+ */
+ void Pause();
+
+ /**
+ * @copydoc ThreadControllerInterface::Resume()
+ */
+ void Resume();
+
+ /**
+ * @copydoc ThreadControllerInterface::Stop()
+ */
+ void Stop();
+
+ /**
+ * @copydoc ThreadControllerInterface::RequestUpdate()
+ */
+ void RequestUpdate();
+
+ /**
+ * @copydoc ThreadControllerInterface::RequestUpdateOnce()
+ */
+ void RequestUpdateOnce();
+
+ /**
+ * @copydoc ThreadControllerInterface::ReplaceSurface()
+ */
+ void ReplaceSurface( RenderSurface* surface );
+
+ /**
+ * @copydoc ThreadControllerInterface::SetRenderRefreshRate()
+ */
+ void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
+
+private:
+
+ // Undefined copy constructor.
+ SeparateUpdateRenderController( const SeparateUpdateRenderController& );
+
+ // Undefined assignment operator.
+ SeparateUpdateRenderController& operator=( const SeparateUpdateRenderController& );
+
+ AdaptorInternalServices& mAdaptorInterfaces;
+
+ UpdateThread* mUpdateThread; ///< The update-thread owned by SeparateUpdateRenderController
+ RenderThread* mRenderThread; ///< The render-thread owned by SeparateUpdateRenderController
+ VSyncNotifier* mVSyncNotifier; ///< The vsync-thread owned by SeparateUpdateRenderController
+ ThreadSynchronization* mThreadSync; ///< Used to synchronize all the threads; owned by SeparateUpdateRenderController
+ unsigned int mNumberOfVSyncsPerRender; ///< Frame skipping count
+};
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_MULTI_THREAD_CONTROLLER_H__
// INTERNAL INCLUDES
#include <base/interfaces/adaptor-internal-services.h>
-#include <base/thread-synchronization-debug.h>
+#include <base/separate-update-render/thread-synchronization-debug.h>
namespace Dali
{
#include <integration-api/thread-synchronization-interface.h>
#include <base/interfaces/performance-interface.h>
#include <trigger-event-interface.h>
-#include <base/frame-time.h>
-#include <base/render-request.h>
+#include <base/separate-update-render/frame-time.h>
+#include <base/separate-update-render/render-request.h>
namespace Dali
{
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
#include <base/interfaces/adaptor-internal-services.h>
-#include <base/thread-synchronization.h>
+#include <base/separate-update-render/thread-synchronization.h>
#include <base/environment-options.h>
namespace Dali
// INTERNAL INCLUDES
#include <base/interfaces/adaptor-internal-services.h>
-#include <base/thread-synchronization.h>
+#include <base/separate-update-render/thread-synchronization.h>
#include <base/environment-options.h>
namespace Dali
--- /dev/null
+#ifndef __DALI_INTERNAL_THREAD_CONTROLLER_INTERFACE_H__
+#define __DALI_INTERNAL_THREAD_CONTROLLER_INTERFACE_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+namespace Dali
+{
+
+class RenderSurface;
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * Interface Class for all controlling threads.
+ */
+class ThreadControllerInterface
+{
+public:
+
+ /**
+ * Virtual destructor. Not intended as base class.
+ */
+ virtual ~ThreadControllerInterface() { }
+
+ /**
+ * Initializes the thread controller
+ */
+ virtual void Initialize() = 0;
+
+ /**
+ * @copydoc Dali::Adaptor::Start()
+ */
+ virtual void Start() = 0;
+
+ /**
+ * @copydoc Dali::Adaptor::Pause()
+ */
+ virtual void Pause() = 0;
+
+ /**
+ * @copydoc Dali::Adaptor::Resume()
+ */
+ virtual void Resume() = 0;
+
+ /**
+ * @copydoc Dali::Adaptor::Stop()
+ */
+ virtual void Stop() = 0;
+
+ /**
+ * Called by the adaptor when core requires another update
+ */
+ virtual void RequestUpdate() = 0;
+
+ /**
+ * Called by the adaptor when core requires one update
+ * If Adaptor is paused, we do one update and return to pause
+ */
+ virtual void RequestUpdateOnce() = 0;
+
+ /**
+ * Replaces the surface.
+ * @param surface new surface
+ */
+ virtual void ReplaceSurface( RenderSurface* surface ) = 0;
+
+ /**
+ * @copydoc Dali::Adaptor::SetRenderRefreshRate()
+ */
+ virtual void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender ) = 0;
+
+protected:
+
+ /**
+ * Constructor
+ */
+ ThreadControllerInterface() { }
+
+private:
+
+ // Undefined copy constructor.
+ ThreadControllerInterface( const ThreadControllerInterface& );
+
+ // Undefined assignment operator.
+ ThreadControllerInterface& operator=( const ThreadControllerInterface& );
+};
+
+} // namespace Adaptor
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_THREAD_CONTROLLER_INTERFACE_H__
#include "thread-controller.h"
// INTERNAL INCLUDES
-#include <base/update-thread.h>
-#include <base/render-thread.h>
-#include <base/thread-synchronization.h>
-#include <base/vsync-notifier.h>
-#include <base/interfaces/adaptor-internal-services.h>
#include <base/environment-options.h>
+#include <base/thread-controller-interface.h>
+#include <base/separate-update-render/separate-update-render-controller.h>
namespace Dali
{
{
ThreadController::ThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions )
-: mAdaptorInterfaces( adaptorInterfaces ),
- mUpdateThread( NULL ),
- mRenderThread( NULL ),
- mVSyncNotifier( NULL ),
- mThreadSync( NULL ),
- mNumberOfVSyncsPerRender( 1 )
+: mThreadControllerInterface( NULL )
{
- mThreadSync = new ThreadSynchronization( adaptorInterfaces, mNumberOfVSyncsPerRender );
-
- mUpdateThread = new UpdateThread( *mThreadSync, adaptorInterfaces, environmentOptions );
-
- mRenderThread = new RenderThread( *mThreadSync, adaptorInterfaces, environmentOptions );
-
- mVSyncNotifier = new VSyncNotifier( *mThreadSync, adaptorInterfaces, environmentOptions );
-
- // Set the thread-synchronization interface on the render-surface
- RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
- if( currentSurface )
+ switch( environmentOptions.GetThreadingMode() )
{
- currentSurface->SetThreadSynchronization( *mThreadSync );
+ case ThreadingMode::SEPARATE_UPDATE_RENDER:
+ case ThreadingMode::COMBINED_UPDATE_RENDER:
+ case ThreadingMode::SINGLE_THREADED:
+ {
+ mThreadControllerInterface = new SeparateUpdateRenderController( adaptorInterfaces, environmentOptions );
+ }
}
}
ThreadController::~ThreadController()
{
- delete mVSyncNotifier;
- delete mRenderThread;
- delete mUpdateThread;
- delete mThreadSync;
+ delete mThreadControllerInterface;
}
void ThreadController::Initialize()
{
- // Notify the synchronization object before starting the threads
- mThreadSync->Initialise();
-
- // We want to the threads to be set up before they start
- mUpdateThread->Start();
- mRenderThread->Start();
- mVSyncNotifier->Start();
+ mThreadControllerInterface->Initialize();
}
void ThreadController::Start()
{
- mThreadSync->Start();
+ mThreadControllerInterface->Start();
}
void ThreadController::Pause()
{
- mThreadSync->Pause();
+ mThreadControllerInterface->Pause();
}
void ThreadController::Resume()
{
- mThreadSync->Resume();
+ mThreadControllerInterface->Resume();
}
void ThreadController::Stop()
{
- // Notify the synchronization object before stopping the threads
- mThreadSync->Stop();
-
- mVSyncNotifier->Stop();
- mUpdateThread->Stop();
- mRenderThread->Stop();
+ mThreadControllerInterface->Stop();
}
void ThreadController::RequestUpdate()
{
- mThreadSync->UpdateRequest();
+ mThreadControllerInterface->RequestUpdate();
}
void ThreadController::RequestUpdateOnce()
{
- // if we are paused, need to allow one update
- mThreadSync->UpdateOnce();
+ mThreadControllerInterface->RequestUpdateOnce();
}
void ThreadController::ReplaceSurface( RenderSurface* newSurface )
{
- // Set the thread-syncronization on the new surface
- newSurface->SetThreadSynchronization( *mThreadSync );
-
- // tell render thread to start the replace. This call will block until the replace
- // has completed.
- RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
-
- // Ensure the current surface releases any locks to prevent deadlock.
- currentSurface->StopRender();
-
- mThreadSync->ReplaceSurface( newSurface );
+ mThreadControllerInterface->ReplaceSurface( newSurface );
}
void ThreadController::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender )
{
- mNumberOfVSyncsPerRender = numberOfVSyncsPerRender;
- mThreadSync->SetRenderRefreshRate(numberOfVSyncsPerRender);
+ mThreadControllerInterface->SetRenderRefreshRate( numberOfVSyncsPerRender );
}
} // namespace Adaptor
-#ifndef __DALI_INTERNAL_UPDATE_RENDER_CONTROLLER_H__
-#define __DALI_INTERNAL_UPDATE_RENDER_CONTROLLER_H__
+#ifndef __DALI_INTERNAL_THREAD_CONTROLLER_H__
+#define __DALI_INTERNAL_THREAD_CONTROLLER_H__
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
namespace Adaptor
{
-class UpdateThread;
-class RenderThread;
-class VSyncNotifier;
-class ThreadSynchronization;
class AdaptorInternalServices;
class EnvironmentOptions;
+class ThreadControllerInterface;
/**
* Class to control all the threads.
// Undefined assignment operator.
ThreadController& operator=( const ThreadController& );
- AdaptorInternalServices& mAdaptorInterfaces;
+private:
- UpdateThread* mUpdateThread; ///< The update-thread owned by ThreadController
- RenderThread* mRenderThread; ///< The render-thread owned by ThreadController
- VSyncNotifier* mVSyncNotifier; ///< The vsync-thread owned by ThreadController
- ThreadSynchronization* mThreadSync; ///< Used to synchronize all the threads; owned by ThreadController
- unsigned int mNumberOfVSyncsPerRender; ///< Frame skipping count
+ ThreadControllerInterface* mThreadControllerInterface;
};
} // namespace Adaptor
} // namespace Dali
-#endif // __DALI_INTERNAL_UPDATE_RENDER_CONTROLLER_H__
+#endif // __DALI_INTERNAL_THREAD_CONTROLLER_H__
--- /dev/null
+#ifndef __DALI_INTERNAL_ADAPTOR_THREADING_MODE_H__
+#define __DALI_INTERNAL_ADAPTOR_THREADING_MODE_H__
+
+/*
+ * Copyright (c) 2015 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.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+struct ThreadingMode
+{
+ enum Type
+ {
+ SEPARATE_UPDATE_RENDER = 0, ///< Event, V-Sync, Update & Render on Separate threads.
+ COMBINED_UPDATE_RENDER, ///< Three threads: Event, V-Sync & a Joint Update/Render thread.
+ SINGLE_THREADED, ///< ALL functionality on the SAME thread.
+ };
+};
+
+} // Adaptor
+
+} // Internal
+
+} // Dali
+
+#endif // __DALI_INTERNAL_ADAPTOR_THREADING_MODE_H__