From 237387295f08c601ddd1b0f44ea5d31bf327b2bf Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 18 Jul 2017 18:45:45 +0900 Subject: [PATCH] Removed separate-update-render and single-threaded modes Change-Id: I6c6a5754b82ecfe3c4c73d86bd77eaccbb0bcb43 --- adaptors/base/environment-options.cpp | 2 - adaptors/base/file.list | 10 +- .../base/separate-update-render/frame-time.cpp | 233 ------ adaptors/base/separate-update-render/frame-time.h | 138 ---- .../base/separate-update-render/render-request.cpp | 79 -- .../base/separate-update-render/render-request.h | 102 --- .../base/separate-update-render/render-thread.cpp | 186 ----- .../base/separate-update-render/render-thread.h | 131 --- .../separate-update-render-controller.cpp | 143 ---- .../separate-update-render-controller.h | 131 --- .../thread-synchronization-debug.h | 183 ----- .../thread-synchronization.cpp | 884 --------------------- .../thread-synchronization.h | 436 ---------- .../base/separate-update-render/update-thread.cpp | 143 ---- .../base/separate-update-render/update-thread.h | 116 --- .../base/separate-update-render/vsync-notifier.cpp | 189 ----- .../base/separate-update-render/vsync-notifier.h | 115 --- .../single-threaded/single-thread-controller.cpp | 351 -------- .../single-threaded/single-thread-controller.h | 200 ----- adaptors/base/thread-controller.cpp | 14 - adaptors/base/threading-mode.h | 4 +- .../wayland/render-surface/render-surface-wl.cpp | 1 - 22 files changed, 2 insertions(+), 3789 deletions(-) delete mode 100644 adaptors/base/separate-update-render/frame-time.cpp delete mode 100644 adaptors/base/separate-update-render/frame-time.h delete mode 100644 adaptors/base/separate-update-render/render-request.cpp delete mode 100644 adaptors/base/separate-update-render/render-request.h delete mode 100644 adaptors/base/separate-update-render/render-thread.cpp delete mode 100644 adaptors/base/separate-update-render/render-thread.h delete mode 100644 adaptors/base/separate-update-render/separate-update-render-controller.cpp delete mode 100644 adaptors/base/separate-update-render/separate-update-render-controller.h delete mode 100644 adaptors/base/separate-update-render/thread-synchronization-debug.h delete mode 100644 adaptors/base/separate-update-render/thread-synchronization.cpp delete mode 100644 adaptors/base/separate-update-render/thread-synchronization.h delete mode 100644 adaptors/base/separate-update-render/update-thread.cpp delete mode 100644 adaptors/base/separate-update-render/update-thread.h delete mode 100644 adaptors/base/separate-update-render/vsync-notifier.cpp delete mode 100644 adaptors/base/separate-update-render/vsync-notifier.h delete mode 100644 adaptors/base/single-threaded/single-thread-controller.cpp delete mode 100644 adaptors/base/single-threaded/single-thread-controller.h diff --git a/adaptors/base/environment-options.cpp b/adaptors/base/environment-options.cpp index 806c428..fef700d 100644 --- a/adaptors/base/environment-options.cpp +++ b/adaptors/base/environment-options.cpp @@ -389,9 +389,7 @@ void EnvironmentOptions::ParseEnvironmentOptions() { switch( threadingMode ) { - case ThreadingMode::SEPARATE_UPDATE_RENDER: case ThreadingMode::COMBINED_UPDATE_RENDER: - case ThreadingMode::SINGLE_THREADED: { mThreadingMode = static_cast< ThreadingMode::Type >( threadingMode ); break; diff --git a/adaptors/base/file.list b/adaptors/base/file.list index 022f01f..130284d 100644 --- a/adaptors/base/file.list +++ b/adaptors/base/file.list @@ -15,15 +15,7 @@ base_adaptor_src_files = \ $(base_adaptor_src_dir)/performance-logging/performance-interface-factory.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)/combined-update-render/combined-update-render-controller.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_src_dir)/single-threaded/single-thread-controller.cpp + $(base_adaptor_src_dir)/combined-update-render/combined-update-render-controller.cpp base_adaptor_networking_src_files = \ $(base_adaptor_src_dir)/performance-logging/networking/network-performance-protocol.cpp \ diff --git a/adaptors/base/separate-update-render/frame-time.cpp b/adaptors/base/separate-update-render/frame-time.cpp deleted file mode 100644 index 489e024..0000000 --- a/adaptors/base/separate-update-render/frame-time.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - * 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. - * 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 "frame-time.h" - -// EXTERNAL INCLUDES -#include -#include - -// INTERNAL INCLUDES -#include - -namespace Dali -{ - -using Integration::PlatformAbstraction; - -namespace Internal -{ -namespace Adaptor -{ - -namespace -{ -#if defined(DEBUG_ENABLED) -Integration::Log::Filter* gLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_FRAME_TIME"); -#endif - -const unsigned int DEFAULT_MINIMUM_FRAME_TIME_INTERVAL( 16667u ); - -const unsigned int MICROSECONDS_PER_MILLISECOND( 1000u ); -const unsigned int NANOSECONDS_PER_MICROSECOND( 1000u); - -const float MICROSECONDS_TO_SECONDS( 0.000001f ); - -const unsigned int HISTORY_SIZE(3); - -// constants to keep code readability with unsigned int has to be used as boolean (due to multithreading) -const unsigned int TRUE = 1u; -const unsigned int FALSE = 0u; -} // unnamed namespace - - -FrameTime::FrameTime() -: mMinimumFrameTimeInterval( DEFAULT_MINIMUM_FRAME_TIME_INTERVAL ), - mLastSyncTime( 0u ), - mLastSyncTimeAtUpdate( 0u ), - mLastSyncFrameNumber( 0u ), - mLastUpdateFrameNumber( 0u ), - mRunning( TRUE ), - mFirstFrame( TRUE ), - writePos( 0u ), - mExtraUpdatesSinceSync( 0u ) -{ - // Clear buffer - for ( unsigned int i = 0; i < HISTORY_SIZE; ++i ) - { - mPreviousUpdateFrames[i] = 0; - } - - SetLastSyncTime(); - mLastSyncTimeAtUpdate = mLastSyncTime; - - DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime Initialized\n" ); -} - -FrameTime::~FrameTime() -{ -} - -void FrameTime::SetMinimumFrameTimeInterval( unsigned int interval ) -{ - mMinimumFrameTimeInterval = interval; -} - -void FrameTime::SetSyncTime( unsigned int frameNumber ) -{ - // Only set the render time if we are running - if ( mRunning ) - { - SetLastSyncTime(); - - mLastSyncFrameNumber = frameNumber; - - DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: SetSyncTime(): Frame: %u: Time: %u\n", mLastSyncFrameNumber, static_cast( mLastSyncTime / MICROSECONDS_PER_MILLISECOND ) ); - } -} - -void FrameTime::Suspend() -{ - mRunning = FALSE; - - // Reset members - mLastSyncFrameNumber = 0; - mLastUpdateFrameNumber = 0; - writePos = 0; - mExtraUpdatesSinceSync = 0; - - // Clear buffer - for ( unsigned int i = 0; i < HISTORY_SIZE; ++i ) - { - mPreviousUpdateFrames[i] = 0; - } - - DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Suspended\n" ); -} - -void FrameTime::Resume() -{ - DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Resuming\n" ); - - SetLastSyncTime(); // Should only update the last Sync time so the elapsed time during suspension is taken into consideration when we next update. - mFirstFrame = TRUE; - - mRunning = TRUE; -} - -void FrameTime::Sleep() -{ - DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Sleeping\n" ); - - // Mimic Suspend behaviour - Suspend(); -} - -void FrameTime::WakeUp() -{ - DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Waking Up\n" ); - - SetLastSyncTime(); - mLastSyncTimeAtUpdate = mLastSyncTime; // We do not want any animations to progress as we have just been woken up. - mFirstFrame = TRUE; - mRunning = TRUE; -} - -void FrameTime::PredictNextSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastSyncTimeMilliseconds, unsigned int& nextSyncTimeMilliseconds ) -{ - if ( mRunning ) - { - const unsigned int minimumFrameTimeInterval( mMinimumFrameTimeInterval ); - const uint64_t lastSyncTime( mLastSyncTime ); - const unsigned int lastSyncFrameNumber( mLastSyncFrameNumber ); - - float lastFrameDelta( 0.0f ); // Assume the last update frame delta is 0. - unsigned int framesTillNextSync( 1 ); // Assume next render will be in one Sync frame time. - - unsigned int framesInLastUpdate( lastSyncFrameNumber - mLastUpdateFrameNumber ); - lastFrameDelta = lastSyncTime - mLastSyncTimeAtUpdate; - - // We should only evaluate the previous frame values if this is not the first frame. - if ( !mFirstFrame ) - { - // Check whether we have had any Syncs since we last did an Update. - if ( framesInLastUpdate == 0 ) - { - // We have had another update before a Sync, increment counter. - ++mExtraUpdatesSinceSync; - - // This update frame will be rendered mUpdatesSinceSync later. - framesTillNextSync += mExtraUpdatesSinceSync; - DALI_LOG_INFO(gLogFilter, Debug::Concise, "PredictNextSyncTime UpdateBeforeSync\n"); - } - else - { - mExtraUpdatesSinceSync = 0; - } - - // If more than one frame elapsed since last Update, then check if this is a recurring theme so we can accurately predict when this Update is rendered. - if ( framesInLastUpdate > 1 ) - { - DALI_LOG_INFO(gLogFilter, Debug::Concise, "PredictNextSyncTime framesInLastUpdate:%u\n", framesInLastUpdate); - unsigned int average(0); - for ( unsigned int i = 0; i < HISTORY_SIZE; ++i ) - { - average += mPreviousUpdateFrames[i]; - } - average /= HISTORY_SIZE; - - if ( average > 1 ) - { - // Our average shows a recurring theme, we are missing frames when rendering so calculate number of frames this will take. - framesTillNextSync = average; - } - } - - // Write the number of frames the last update took to the array. - mPreviousUpdateFrames[writePos] = framesInLastUpdate; - writePos = ( writePos + 1 ) % HISTORY_SIZE; - } - - mLastUpdateFrameNumber = lastSyncFrameNumber; - mLastSyncTimeAtUpdate = lastSyncTime; - mFirstFrame = FALSE; - - // Calculate the time till the next render - unsigned int timeTillNextRender( minimumFrameTimeInterval * framesTillNextSync ); - - // Set the input variables - lastFrameDeltaSeconds = lastFrameDelta * MICROSECONDS_TO_SECONDS; - lastSyncTimeMilliseconds = lastSyncTime / MICROSECONDS_PER_MILLISECOND; - nextSyncTimeMilliseconds = ( lastSyncTime + timeTillNextRender ) / MICROSECONDS_PER_MILLISECOND; - - DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: Frame: %u, Time: %u, NextTime: %u, LastDelta: %f\n", mLastUpdateFrameNumber, lastSyncTimeMilliseconds, nextSyncTimeMilliseconds, lastFrameDeltaSeconds ); - DALI_LOG_INFO( gLogFilter, Debug::Verbose, " FramesInLastUpdate: %u, FramesTillNextSync: %u\n", framesInLastUpdate, framesTillNextSync ); - } -} - -inline void FrameTime::SetLastSyncTime() -{ - uint64_t nanoseconds( 0u ); - TimeService::GetNanoseconds( nanoseconds ); - - mLastSyncTime = nanoseconds / NANOSECONDS_PER_MICROSECOND; -} - -} // namespace Adaptor -} // namespace Internal -} // namespace Dali diff --git a/adaptors/base/separate-update-render/frame-time.h b/adaptors/base/separate-update-render/frame-time.h deleted file mode 100644 index ec43971..0000000 --- a/adaptors/base/separate-update-render/frame-time.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef __DALI_INTERNAL_ADAPTOR_FRAME_TIME_H__ -#define __DALI_INTERNAL_ADAPTOR_FRAME_TIME_H__ - -/* - * Copyright (c) 2014 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. - * - */ - -// EXTERNAL INCLUDES -#include - -namespace Dali -{ - -namespace Integration -{ -class PlatformAbstraction; -} - -namespace Internal -{ -namespace Adaptor -{ - -/** - * FrameTime stores the time of the last VSync. It can then be used by the update thread to predict - * the current update will be rendered. - */ -class FrameTime -{ -public: - - // Called from Event thread - - /** - * Constructor - */ - FrameTime(); - - /** - * Destructor, non virtual - */ - ~FrameTime(); - - /** - * Sets the expected minimum frame time interval. - * @param[in] interval The interval in microseconds. - */ - void SetMinimumFrameTimeInterval( unsigned int interval ); - - /** - * Suspends the FrameTime object when the application state changes - */ - void Suspend(); - - /** - * Resumes the FrameTime object when the application state changes - */ - void Resume(); - - // Called from Update thread - - /** - * Sets the FrameTime object to sleep, i.e. when there are no more updates required. - */ - void Sleep(); - - /** - * Wakes the FrameTime object from a sleep state. - */ - void WakeUp(); - - /** - * Predicts when the next render time will occur. - * - * @param[out] lastFrameDeltaSeconds The delta, in seconds (with float precision), between the last two renders. - * @param[out] lastSyncTimeMilliseconds The time, in milliseconds, of the last Sync. - * @param[out] nextSyncTimeMilliseconds The estimated time, in milliseconds, at the next Sync. - * - * @note Should only be called once per tick, from the update thread. - */ - void PredictNextSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastVSyncTimeMilliseconds, unsigned int& nextVSyncTimeMilliseconds ); - - // Called from VSync thread - - /** - * Tells the FrameTime object that a Sync has occurred. - * - * @param[in] frameNumber The frame number of the current Sync. - * - * @note Should only be called from the VSync thread. - */ - void SetSyncTime( unsigned int frameNumber ); - -private: - - /** - * Sets the current time to be the last Vsync time. - */ - inline void SetLastSyncTime(); - -private: - - unsigned int mMinimumFrameTimeInterval; ///< The minimum frame time interval, set by Adaptor. - - uint64_t mLastSyncTime; ///< The last Sync time (in microseconds). - uint64_t mLastSyncTimeAtUpdate; ///< The last Sync time at Update (in microseconds). - - unsigned int mLastSyncFrameNumber; ///< The last Sync frame number - unsigned int mLastUpdateFrameNumber; ///< The last Sync frame number handled in Update. - - // NOTE cannot use bitfields or booleans as these are used from multiple threads, must use variable with machine word size for atomic read/write - unsigned int mRunning; ///< The state of the FrameTime object. - unsigned int mFirstFrame; ///< Whether the current update is the first frame (after initialisation, resume or wake up). - - unsigned int mPreviousUpdateFrames[3]; ///< Array holding the number of frames Update took in the last three iterations. - unsigned int writePos; ///< The current write position in the array. - - unsigned int mExtraUpdatesSinceSync; ///< The number of extra updates since the last Sync. -}; - -} // namespace Adaptor -} // namespace Internal -} // namespace Dali - -#endif // __DALI_INTERNAL_ADAPTOR_FRAME_TIME_H__ diff --git a/adaptors/base/separate-update-render/render-request.cpp b/adaptors/base/separate-update-render/render-request.cpp deleted file mode 100644 index 0d1e710..0000000 --- a/adaptors/base/separate-update-render/render-request.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 "render-request.h" - -// EXTERNAL INCLUDES - -// INTERNAL INCLUDES - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -} - -RenderRequest::RenderRequest( RenderRequest::Request type ) -: mRequestType( type ) -{ -} - -RenderRequest::Request RenderRequest::GetType() -{ - return mRequestType; -} - -ReplaceSurfaceRequest::ReplaceSurfaceRequest() -: RenderRequest( RenderRequest::REPLACE_SURFACE ), - mNewSurface( NULL ), - mReplaceCompleted( false ) -{ -} - -void ReplaceSurfaceRequest::SetSurface( RenderSurface* newSurface ) -{ - mNewSurface = newSurface; -} - -RenderSurface* ReplaceSurfaceRequest::GetSurface() -{ - return mNewSurface; -} - -void ReplaceSurfaceRequest::ReplaceCompleted() -{ - mReplaceCompleted = true; -} - -bool ReplaceSurfaceRequest::GetReplaceCompleted() -{ - return mReplaceCompleted != 0u; -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/separate-update-render/render-request.h b/adaptors/base/separate-update-render/render-request.h deleted file mode 100644 index 608679c..0000000 --- a/adaptors/base/separate-update-render/render-request.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __DALI_INTERNAL_RENDER_REQUEST_H__ -#define __DALI_INTERNAL_RENDER_REQUEST_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. - * - */ - -// EXTERNAL INCLUDES - -// INTERNAL INCLUDES -#include -#include // needed for Dali::RenderSurface - -namespace Dali -{ - -class RenderSurface; -class DisplayConnection; - -namespace Internal -{ -namespace Adaptor -{ - -class RenderRequest -{ -public: - enum Request - { - REPLACE_SURFACE, // Request to replace surface - }; - - /** - * Constructor. - * @param[in] type The type of the request - */ - RenderRequest( Request type ); - - /** - * @return the type of the request - */ - Request GetType(); - -private: - Request mRequestType; -}; - -class ReplaceSurfaceRequest : public RenderRequest -{ -public: - - /** - * Constructor - */ - ReplaceSurfaceRequest(); - - /** - * Set the new surface - * @param[in] newSurface The new surface to use - */ - void SetSurface(RenderSurface* newSurface); - - /** - * @return the new surface - */ - RenderSurface* GetSurface(); - - /** - * Called when the request has been completed to set the result. - */ - void ReplaceCompleted(); - - /** - * @return true if the replace has completed. - */ - bool GetReplaceCompleted(); - -private: - RenderSurface* mNewSurface; ///< The new surface to use. - unsigned int mReplaceCompleted; ///< Set to true when the replace has completed. -}; - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_RENDER_REQUEST_H__ diff --git a/adaptors/base/separate-update-render/render-thread.cpp b/adaptors/base/separate-update-render/render-thread.cpp deleted file mode 100644 index 5d57c9e..0000000 --- a/adaptors/base/separate-update-render/render-thread.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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 "render-thread.h" - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -#if defined(DEBUG_ENABLED) -Integration::Log::Filter* gRenderLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_RENDER_THREAD"); -#endif -} - -RenderThread::RenderThread( ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions ) -: mThreadSynchronization( sync ), - mCore( adaptorInterfaces.GetCore() ), - mThread( NULL ), - mEnvironmentOptions( environmentOptions ), - mRenderHelper( adaptorInterfaces ) -{ -} - -RenderThread::~RenderThread() -{ -} - -void RenderThread::Start() -{ - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Start()\n"); - - // create the render thread, initially we are rendering - mThread = new pthread_t(); - int error = pthread_create( mThread, NULL, InternalThreadEntryFunc, this ); - DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() in RenderThread" ); - - mRenderHelper.Start(); -} - -void RenderThread::Stop() -{ - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Stop()\n"); - - mRenderHelper.Stop(); - - // shutdown the render thread and destroy the opengl context - if( mThread ) - { - // wait for the thread to finish - pthread_join(*mThread, NULL); - - delete mThread; - mThread = NULL; - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// The following methods are all executed inside render thread !!! -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool RenderThread::Run() -{ - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run\n"); - - // Install a function for logging - mEnvironmentOptions.InstallLogFunction(); - - mRenderHelper.InitializeEgl(); - - // tell core it has a context - mCore.ContextCreated(); - - Dali::Integration::RenderStatus renderStatus; - RenderRequest* request = NULL; - - // Render loop, we stay inside here when rendering - while( mThreadSynchronization.RenderReady( request ) ) - { - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 1 - RenderReady\n"); - - // Consume any pending events to avoid memory leaks - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 2 - ConsumeEvents\n"); - mRenderHelper.ConsumeEvents(); - - // Check if we've got a request from the main thread (e.g. replace surface) - if( request ) - { - // Process the request, we should NOT render when we have a request - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Process requests\n"); - ProcessRequest( request ); - } - else - { - // No request to process so we render - if( mRenderHelper.PreRender() ) // Returns false if no surface onto which to render - { - // Render - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Core.Render()\n"); - - mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::RENDER_START ); - mCore.Render( renderStatus ); - mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::RENDER_END ); - - // Decrement the count of how far update is ahead of render - mThreadSynchronization.RenderFinished(); - - // Perform any post-render operations - if( renderStatus.NeedsPostRender() ) - { - DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 4 - PostRender()\n"); - mRenderHelper.PostRender(); - } - } - } - - request = NULL; // Clear the request if it was set, no need to release memory - } - - // Inform core of context destruction & shutdown EGL - mCore.ContextDestroyed(); - mRenderHelper.ShutdownEgl(); - - // Uninstall the logging function - mEnvironmentOptions.UnInstallLogFunction(); - - return true; -} - -void RenderThread::ProcessRequest( RenderRequest* request ) -{ - if( request != NULL ) - { - switch(request->GetType()) - { - case RenderRequest::REPLACE_SURFACE: - { - // change the surface - ReplaceSurfaceRequest* replaceSurfaceRequest = static_cast(request); - mRenderHelper.ReplaceSurface( replaceSurfaceRequest->GetSurface() ); - replaceSurfaceRequest->ReplaceCompleted(); - mThreadSynchronization.RenderInformSurfaceReplaced(); - break; - } - } - } -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/separate-update-render/render-thread.h b/adaptors/base/separate-update-render/render-thread.h deleted file mode 100644 index ad0a97e..0000000 --- a/adaptors/base/separate-update-render/render-thread.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef __DALI_INTERNAL_RENDER_THREAD_H__ -#define __DALI_INTERNAL_RENDER_THREAD_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. - * - */ - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include // needed for Dali::RenderSurface - -namespace Dali -{ - -class RenderSurface; - -namespace Integration -{ -class Core; -} - -namespace Internal -{ -namespace Adaptor -{ - -class AdaptorInternalServices; -class ThreadSynchronization; -class EnvironmentOptions; - -/** - * The render-thread is responsible for calling Core::Render() after each update. - */ -class RenderThread -{ -public: - - /** - * Create the render-thread; this will not do anything until Start() is called. - * @param[in] sync thread synchronization object - * @param[in] adaptorInterfaces base adaptor interface - * @param[in] environmentOptions environment options - */ - RenderThread( ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions ); - - /** - * Destructor - */ - ~RenderThread(); - -public: - - /** - * Starts the render-thread - */ - void Start(); - - /** - * Stops the render-thread - */ - void Stop(); - -private: // Render thread side helpers - - /** - * This method is used by the Render thread for rendering the Core to the screen. - * Called from render thread - * @return true, if the thread finishes properly. - */ - bool Run(); - - /** - * Check if main thread made any requests, e.g. ReplaceSurface - * Called from render thread - */ - void ProcessRequest( RenderRequest* request ); - - /** - * Helper for the thread calling the entry function. - * @param[in] This A pointer to the current RenderThread object - */ - static inline void* InternalThreadEntryFunc( void* This ) - { - ( static_cast( This ) )->Run(); - return NULL; - } - -private: - - // Undefined - RenderThread( const RenderThread& renderThread ); - - // Undefined - RenderThread& operator=( const RenderThread& renderThread ); - -private: // Data - - ThreadSynchronization& mThreadSynchronization; ///< Used to synchronize the all threads - Dali::Integration::Core& mCore; ///< Dali core reference - pthread_t* mThread; ///< render thread - const EnvironmentOptions& mEnvironmentOptions; ///< Environment options - RenderHelper mRenderHelper; ///< Helper class for EGL, pre & post rendering -}; - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_RENDER_THREAD_H__ diff --git a/adaptors/base/separate-update-render/separate-update-render-controller.cpp b/adaptors/base/separate-update-render/separate-update-render-controller.cpp deleted file mode 100644 index 0e99f81..0000000 --- a/adaptors/base/separate-update-render/separate-update-render-controller.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -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( environmentOptions.GetRenderRefreshRate() ) -{ - 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 diff --git a/adaptors/base/separate-update-render/separate-update-render-controller.h b/adaptors/base/separate-update-render/separate-update-render-controller.h deleted file mode 100644 index 19d3b3c..0000000 --- a/adaptors/base/separate-update-render/separate-update-render-controller.h +++ /dev/null @@ -1,131 +0,0 @@ -#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 - -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__ diff --git a/adaptors/base/separate-update-render/thread-synchronization-debug.h b/adaptors/base/separate-update-render/thread-synchronization-debug.h deleted file mode 100644 index 8edf4b3..0000000 --- a/adaptors/base/separate-update-render/thread-synchronization-debug.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef __DALI_INTERNAL_THREAD_SYNCHRONIZATION_DEBUG_H__ -#define __DALI_INTERNAL_THREAD_SYNCHRONIZATION_DEBUG_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. - * - */ - -// EXTERNAL INCLUDES -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -// Uncomment next line for FULL logging of the ThreadSynchronization class in release mode -//#define RELEASE_BUILD_LOGGING - -#ifdef DEBUG_ENABLED - -#define ENABLE_LOG_IN_COLOR -#define ENABLE_VSYNC_COUNTER_LOGGING -#define ENABLE_UPDATE_COUNTER_LOGGING -#define ENABLE_VSYNC_THREAD_LOGGING -#define ENABLE_UPDATE_THREAD_LOGGING -#define ENABLE_RENDER_THREAD_LOGGING -#define ENABLE_EVENT_LOGGING - -#define DEBUG_LEVEL_COUNTER Debug::Verbose -#define DEBUG_LEVEL_VSYNC Debug::General -#define DEBUG_LEVEL_UPDATE Debug::General -#define DEBUG_LEVEL_RENDER Debug::General -#define DEBUG_LEVEL_EVENT Debug::Concise - -Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_THREAD_SYNC" ); - -#define LOG_THREAD_SYNC(level, color, format, args...) \ - DALI_LOG_INFO( gLogFilter, level, "%s" format "%s\n", color, ## args, COLOR_CLEAR ) - -#define LOG_THREAD_SYNC_TRACE(color) \ - Dali::Integration::Log::TraceObj debugTraceObj( gLogFilter, "%s%s%s", color, __FUNCTION__, COLOR_CLEAR ); \ - if( ! gLogFilter->IsTraceEnabled() ) { LOG_THREAD_SYNC( Debug::Concise, color, "%s", __FUNCTION__ ); } - -#define LOG_THREAD_SYNC_TRACE_FMT(color, format, args...) \ - Dali::Integration::Log::TraceObj debugTraceObj( gLogFilter, "%s%s: " format "%s", color, __FUNCTION__, ## args, COLOR_CLEAR ); \ - if( ! gLogFilter->IsTraceEnabled() ) { LOG_THREAD_SYNC( Debug::Concise, color, "%s: " format, __FUNCTION__, ## args ); } - -#elif defined( RELEASE_BUILD_LOGGING ) - -#define ENABLE_LOG_IN_COLOR -#define ENABLE_VSYNC_COUNTER_LOGGING -#define ENABLE_UPDATE_COUNTER_LOGGING -#define ENABLE_VSYNC_THREAD_LOGGING -#define ENABLE_UPDATE_THREAD_LOGGING -#define ENABLE_RENDER_THREAD_LOGGING -#define ENABLE_EVENT_LOGGING - -#define DEBUG_LEVEL_COUNTER 0 -#define DEBUG_LEVEL_VSYNC 0 -#define DEBUG_LEVEL_UPDATE 0 -#define DEBUG_LEVEL_RENDER 0 -#define DEBUG_LEVEL_EVENT 0 - -#define LOG_THREAD_SYNC(level, color, format, args...) \ - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s" format "%s\n", color, ## args, COLOR_CLEAR ) - -#define LOG_THREAD_SYNC_TRACE(color) \ - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s%s%s\n", color, __FUNCTION__, COLOR_CLEAR ) - -#define LOG_THREAD_SYNC_TRACE_FMT(color, format, args...) \ - Dali::Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, "%s%s: " format "%s\n", color, __FUNCTION__, ## args, COLOR_CLEAR ) - -#else - -#define LOG_THREAD_SYNC(level, color, format, args...) -#define LOG_THREAD_SYNC_TRACE(color) -#define LOG_THREAD_SYNC_TRACE_FMT(color, format, args...) - -#endif // DEBUG_ENABLED - -#ifdef ENABLE_LOG_IN_COLOR -#define COLOR_RED "\033[31m" -#define COLOR_YELLOW "\033[33m" -#define COLOR_BLUE "\033[34m" -#define COLOR_LIGHT_RED "\033[91m" -#define COLOR_LIGHT_YELLOW "\033[93m" -#define COLOR_LIGHT_BLUE "\033[94m" -#define COLOR_WHITE "\033[97m" -#define COLOR_CLEAR "\033[0m" -#else -#define COLOR_RED -#define COLOR_YELLOW -#define COLOR_BLUE -#define COLOR_LIGHT_RED -#define COLOR_LIGHT_YELLOW -#define COLOR_LIGHT_BLUE -#define COLOR_WHITE -#define COLOR_CLEAR -#endif - -#ifdef ENABLE_VSYNC_COUNTER_LOGGING -#define LOG_VSYNC_COUNTER_VSYNC(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_COUNTER, COLOR_LIGHT_RED, "%s: " format, __FUNCTION__, ## args) -#define LOG_VSYNC_COUNTER_UPDATE(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_COUNTER, COLOR_LIGHT_YELLOW, "%s: " format, __FUNCTION__, ## args) -#else -#define LOG_VSYNC_COUNTER_VSYNC(format, args...) -#define LOG_VSYNC_COUNTER_UPDATE(format, args...) -#endif - -#ifdef ENABLE_UPDATE_COUNTER_LOGGING -#define LOG_UPDATE_COUNTER_UPDATE(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_COUNTER, COLOR_YELLOW, "%s: " format, __FUNCTION__, ## args) -#define LOG_UPDATE_COUNTER_RENDER(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_COUNTER, COLOR_LIGHT_BLUE, "%s: " format, __FUNCTION__, ## args) -#else -#define LOG_UPDATE_COUNTER_UPDATE(format, args...) -#define LOG_UPDATE_COUNTER_RENDER(format, args...) -#endif - -#ifdef ENABLE_VSYNC_THREAD_LOGGING -#define LOG_VSYNC(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_VSYNC, COLOR_RED, "%s: " format, __FUNCTION__, ## args) -#define LOG_VSYNC_TRACE LOG_THREAD_SYNC_TRACE(COLOR_RED) -#define LOG_VSYNC_TRACE_FMT(format, args...) LOG_THREAD_SYNC_TRACE_FMT(COLOR_RED, format, ## args) -#else -#define LOG_VSYNC(format, args...) -#define LOG_VSYNC_TRACE -#define LOG_VSYNC_TRACE_FMT(format, args...) -#endif - -#ifdef ENABLE_UPDATE_THREAD_LOGGING -#define LOG_UPDATE(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_UPDATE, COLOR_YELLOW, "%s: " format, __FUNCTION__, ## args) -#define LOG_UPDATE_TRACE LOG_THREAD_SYNC_TRACE(COLOR_YELLOW) -#define LOG_UPDATE_TRACE_FMT(format, args...) LOG_THREAD_SYNC_TRACE_FMT(COLOR_YELLOW, format, ## args) -#else -#define LOG_UPDATE(format, args...) -#define LOG_UPDATE_TRACE -#define LOG_UPDATE_TRACE_FMT(format, args...) -#endif - -#ifdef ENABLE_RENDER_THREAD_LOGGING -#define LOG_RENDER(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_RENDER, COLOR_BLUE, "%s: " format, __FUNCTION__, ## args) -#define LOG_RENDER_TRACE LOG_THREAD_SYNC_TRACE(COLOR_BLUE) -#define LOG_RENDER_TRACE_FMT(format, args...) LOG_THREAD_SYNC_TRACE_FMT(COLOR_BLUE, format, ## args) -#else -#define LOG_RENDER(format, args...) -#define LOG_RENDER_TRACE -#define LOG_RENDER_TRACE_FMT(format, args...) -#endif - -#ifdef ENABLE_EVENT_LOGGING -#define LOG_EVENT(format, args...) LOG_THREAD_SYNC(DEBUG_LEVEL_EVENT, COLOR_WHITE, "%s: " format, __FUNCTION__, ## args) -#define LOG_EVENT_TRACE LOG_THREAD_SYNC_TRACE(COLOR_WHITE) -#define LOG_EVENT_TRACE_FMT(format, args...) LOG_THREAD_SYNC_TRACE_FMT(COLOR_WHITE, format, ## args) -#else -#define LOG_EVENT(format, args...) -#define LOG_EVENT_TRACE -#define LOG_EVENT_TRACE_FMT(format, args...) -#endif -} // unnamed namespace - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_THREAD_SYNCHRONIZATION_DEBUG_H__ diff --git a/adaptors/base/separate-update-render/thread-synchronization.cpp b/adaptors/base/separate-update-render/thread-synchronization.cpp deleted file mode 100644 index 407c018..0000000 --- a/adaptors/base/separate-update-render/thread-synchronization.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* - * 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 "thread-synchronization.h" - -// INTERNAL INCLUDES -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -const unsigned int TIME_PER_FRAME_IN_MICROSECONDS = 16667; -const int TOTAL_THREAD_COUNT = 3; -const unsigned int TRUE = 1u; -const unsigned int FALSE = 0u; -} // unnamed namespace - -ThreadSynchronization::ThreadSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender) -: mFrameTime(), - mNotificationTrigger( adaptorInterfaces.GetProcessCoreEventsTrigger() ), - mPerformanceInterface( adaptorInterfaces.GetPerformanceInterface() ), - mReplaceSurfaceRequest(), - mUpdateThreadWaitCondition(), - mRenderThreadWaitCondition(), - mVSyncThreadWaitCondition(), - mEventThreadWaitCondition(), - mMaximumUpdateCount( adaptorInterfaces.GetCore().GetMaximumUpdateCount()), - mNumberOfVSyncsPerRender( numberOfVSyncsPerRender ), - mTryToSleepCount( 0u ), - mState( State::STOPPED ), - mVSyncAheadOfUpdate( 0u ), - mUpdateAheadOfRender( 0u ), - mNumberOfThreadsStarted( 0u ), - mUpdateThreadResuming( FALSE ), - mVSyncThreadRunning( FALSE ), - mVSyncThreadStop( FALSE ), - mRenderThreadStop( FALSE ), - mRenderThreadReplacingSurface( FALSE ), - mRenderThreadPostRendering( FALSE ), - mEventThreadSurfaceReplaced( FALSE ), - mVSyncThreadInitialised( FALSE ), - mRenderThreadInitialised( FALSE ), - mRenderThreadSurfaceReplaced( FALSE ) -{ -} - -ThreadSynchronization::~ThreadSynchronization() -{ -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// EVENT THREAD -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::Initialise() -{ - LOG_EVENT_TRACE; - - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState == State::STOPPED ) - { - LOG_EVENT( "INITIALISING" ); - mState = State::INITIALISING; - } -} - -void ThreadSynchronization::Start() -{ - LOG_EVENT_TRACE; - - bool start = false; - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState == State::INITIALISING ) - { - start = true; - } - } - - // Not atomic, but does not matter here as we just want to ensure we only start from State::INITIALISING - if( start ) - { - LOG_EVENT( "STARTING" ); - mFrameTime.SetMinimumFrameTimeInterval( mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS ); - - { - ConditionalWait::ScopedLock lock( mEventThreadWaitCondition ); - while( mNumberOfThreadsStarted < TOTAL_THREAD_COUNT ) - { - mEventThreadWaitCondition.Wait( lock ); - } - } - - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - mState = State::RUNNING; - } - mUpdateThreadWaitCondition.Notify(); - } -} - -void ThreadSynchronization::Stop() -{ - LOG_EVENT_TRACE; - - bool stop = false; - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState != State::STOPPED ) - { - stop = true; - mState = State::STOPPED; - } - } - - // Not atomic, but does not matter here as we just want to ensure we do not stop more than once - if( stop ) - { - LOG_EVENT( "STOPPING" ); - - // Notify update-thread so that it continues and sets up the other threads to stop as well - mUpdateThreadWaitCondition.Notify(); - - mFrameTime.Suspend(); - } -} - -void ThreadSynchronization::Pause() -{ - LOG_EVENT_TRACE; - - bool addPerformanceMarker = false; - { - // Only pause if we're RUNNING or SLEEPING - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( ( mState == State::RUNNING ) || - ( mState == State::SLEEPING ) ) - { - LOG_EVENT( "PAUSING" ); - - mState = State::PAUSED; - - mUpdateThreadResuming = FALSE; - - mFrameTime.Suspend(); - - addPerformanceMarker = true; - } - } - - if( addPerformanceMarker ) - { - // Can lock so we do not want to have a lock when calling this to avoid deadlocks - AddPerformanceMarker( PerformanceInterface::PAUSED ); - } -} - -void ThreadSynchronization::Resume() -{ - LOG_EVENT_TRACE; - - // Only resume if we're PAUSED - bool resume = false; - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState == State::PAUSED ) - { - resume = true; - mState = State::RUNNING; - mUpdateThreadResuming = TRUE; - } - } - - // Not atomic, but does not matter here as we just want to ensure we only resume if we're paused - if( resume ) - { - LOG_EVENT( "RESUMING" ); - - mFrameTime.Resume(); - - // Start up Update thread again - mUpdateThreadWaitCondition.Notify(); - - // Can lock so we do not want to have a lock when calling this to avoid deadlocks - AddPerformanceMarker( PerformanceInterface::RESUME); - } -} - -void ThreadSynchronization::UpdateRequest() -{ - LOG_EVENT_TRACE; - - bool update = false; - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState == State::SLEEPING ) - { - mState = State::RUNNING; - update = true; - } - mTryToSleepCount = 0; - } - - if( update ) - { - LOG_EVENT( "UPDATE REQUEST" ); - mUpdateThreadWaitCondition.Notify(); - } -} - -void ThreadSynchronization::UpdateOnce() -{ - LOG_EVENT_TRACE; - LOG_EVENT( "UPDATE ONCE" ); - - // If we're sleeping then change state to running as this will also wake up the v-sync-thread - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - if( mState == State::SLEEPING ) - { - mState = State::RUNNING; - } - } - - mUpdateThreadWaitCondition.Notify(); -} - -void ThreadSynchronization::ReplaceSurface( RenderSurface* newSurface ) -{ - LOG_EVENT_TRACE; - - State::Type previousState( State::STOPPED ); - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - previousState = mState; - mState = State::REPLACING_SURFACE; - } - - { - ConditionalWait::ScopedLock lock( mEventThreadWaitCondition ); - mEventThreadSurfaceReplaced = FALSE; - } - - { - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - mReplaceSurfaceRequest.SetSurface( newSurface ); - mRenderThreadReplacingSurface = TRUE; - } - - // Notify the RenderThread in case it's waiting - mRenderThreadWaitCondition.Notify(); - - { - ConditionalWait::ScopedLock lock( mEventThreadWaitCondition ); - - // Wait for RenderThread to replace the surface - while( ! mEventThreadSurfaceReplaced ) - { - LOG_EVENT( "Waiting for Surface to be Replaced" ); - - mEventThreadWaitCondition.Wait( lock ); - } - } - - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - mState = previousState; - } - mUpdateThreadWaitCondition.Notify(); -} - -void ThreadSynchronization::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender ) -{ - LOG_EVENT_TRACE; - LOG_EVENT( "SET RENDER REFRESH RATE" ); - - mNumberOfVSyncsPerRender = numberOfVSyncsPerRender; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// UPDATE THREAD -/////////////////////////////////////////////////////////////////////////////////////////////////// - -bool ThreadSynchronization::UpdateReady( bool notifyEvent, bool runUpdate, float& lastFrameDeltaSeconds, unsigned int& lastSyncTimeMilliseconds, unsigned int& nextSyncTimeMilliseconds ) -{ - LOG_UPDATE_TRACE; - - State::Type state = State::STOPPED; - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - state = mState; - } - - switch( state ) - { - case State::STOPPED: - { - StopAllThreads(); - return false; // Stop update-thread - } - - case State::INITIALISING: - { - UpdateInitialising(); - break; - } - - case State::PAUSED: - { - LOG_UPDATE_TRACE_FMT( "PAUSED" ); - - // Just pause the VSyncThread, locks so we shouldn't have a scoped-lock when calling this - PauseVSyncThread(); - } - // No break, fall through - - case State::RUNNING: - { - LOG_UPDATE_TRACE_FMT( "RUNNING" ); - - if( IsUpdateThreadResuming() ) - { - LOG_UPDATE( "Restarting VSyncThread" ); - - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - mUpdateThreadResuming = FALSE; - } - - // Restart the VSyncThread, locks so we shouldn't have a scoped-lock when calling this - RunVSyncThread(); - } - - if( notifyEvent ) - { - LOG_UPDATE( "Notify Event Thread" ); - - // Do the notifications first so the event thread can start processing them - // Tell the event-thread to wake up (if asleep) and send a notification event to Core - mNotificationTrigger.Trigger(); - } - - // Inform render thread - { - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - ++mUpdateAheadOfRender; - DALI_ASSERT_ALWAYS( mUpdateAheadOfRender >= 0 ); - DALI_ASSERT_ALWAYS( mUpdateAheadOfRender <= mMaximumUpdateCount ); - LOG_UPDATE_COUNTER_UPDATE( "updateAheadOfRender(%d)", mUpdateAheadOfRender ); - } - mRenderThreadWaitCondition.Notify(); - - // Wait if we've reached the maximum-ahead-of-render count. - while( MaximumUpdateAheadOfRenderReached() ) - { - LOG_UPDATE( "Maximum Update Ahead of Render: WAIT" ); - - mRenderThreadWaitCondition.Notify(); // Notify the render thread in case it was waiting - - { - // Ensure we did not stop while we were waiting previously. - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - if( mState == State::STOPPED ) - { - break; // Break out of while loop - } - mUpdateThreadWaitCondition.Wait( updateLock ); - } - } - - // Ensure we have had at least 1 V-Sync before we continue - // Ensure we didn't stop while we were previously waiting - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - if( ( mState != State::STOPPED ) && - ( mVSyncAheadOfUpdate == 0 ) && - ( !mUpdateThreadResuming ) ) // Ensure we don't wait if the update-thread is JUST resuming - { - LOG_VSYNC_COUNTER_UPDATE( " vSyncAheadOfUpdate(%d) WAIT", mVSyncAheadOfUpdate ); - mUpdateThreadWaitCondition.Wait( updateLock ); - } - else - { - LOG_VSYNC_COUNTER_UPDATE( " vSyncAheadOfUpdate(%d)", mVSyncAheadOfUpdate ); - } - mVSyncAheadOfUpdate = 0; - } - - // Try to sleep if we do not require any more updates - UpdateTryToSleep( runUpdate ); - - break; - } - - case State::SLEEPING: - case State::REPLACING_SURFACE: - { - break; - } - } - - // Ensure we didn't stop while we were waiting - if( IsUpdateThreadStopping() ) - { - // Locks so we shouldn't have a scoped-lock when calling this - StopAllThreads(); - return false; // Stop update-thread - } - - // Just wait if we're replacing the surface as the render-thread is busy - UpdateWaitIfReplacingSurface(); - - mFrameTime.PredictNextSyncTime( lastFrameDeltaSeconds, lastSyncTimeMilliseconds, nextSyncTimeMilliseconds ); - - return true; // Keep update-thread running -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// RENDER THREAD -/////////////////////////////////////////////////////////////////////////////////////////////////// - -bool ThreadSynchronization::RenderReady( RenderRequest*& requestPtr ) -{ - LOG_RENDER_TRACE; - - if( ! IsRenderThreadReplacingSurface() ) // Call to this function locks so should not be called if we have a scoped-lock - { - if( ! mRenderThreadInitialised ) - { - LOG_RENDER( "Initialised" ); - - mRenderThreadInitialised = TRUE; - - // Notify event thread that this thread is up and running, this locks so we should have a scoped-lock - NotifyThreadInitialised(); - } - else - { - if( mRenderThreadSurfaceReplaced ) - { - mRenderThreadSurfaceReplaced = FALSE; - } - } - - // Check if we've had an update, if we haven't then we just wait - // Ensure we do not wait if we're supposed to stop - { - ConditionalWait::ScopedLock renderLock( mRenderThreadWaitCondition ); - if( mUpdateAheadOfRender <= 0 && ! mRenderThreadStop ) - { - do - { - LOG_UPDATE_COUNTER_RENDER( "updateAheadOfRender(%d) WAIT", mUpdateAheadOfRender ); - mRenderThreadWaitCondition.Wait( renderLock ); - } while( mUpdateAheadOfRender <= 0 && ! mRenderThreadStop && ! mRenderThreadReplacingSurface ); - } - else - { - LOG_UPDATE_COUNTER_RENDER( "updateAheadOfRender(%d)", mUpdateAheadOfRender ); - } - } - } - - // We may have been asked to replace the surface while we were waiting so check again here - if( IsRenderThreadReplacingSurface() ) - { - // Replacing surface - LOG_RENDER( "REPLACE SURFACE" ); - - ConditionalWait::ScopedLock renderLock( mRenderThreadWaitCondition ); - requestPtr = &mReplaceSurfaceRequest; - mRenderThreadReplacingSurface = FALSE; - mRenderThreadSurfaceReplaced = FALSE; - } - - return IsRenderThreadRunning(); // Call to this function locks so should not be called if we have a scoped-lock -} - -void ThreadSynchronization::RenderFinished() -{ - // A frame has been rendered; decrement counter - ConditionalWait::ScopedLock renderLock( mRenderThreadWaitCondition ); - --mUpdateAheadOfRender; - - LOG_RENDER( "mUpdateAheadOfRender %d\n", mUpdateAheadOfRender ); - DALI_ASSERT_ALWAYS( mUpdateAheadOfRender < mMaximumUpdateCount ); - DALI_ASSERT_ALWAYS( mUpdateAheadOfRender >= 0 ); -} - -void ThreadSynchronization::RenderInformSurfaceReplaced() -{ - LOG_RENDER_TRACE; - - mRenderThreadSurfaceReplaced = TRUE; - { - ConditionalWait::ScopedLock lock( mEventThreadWaitCondition ); - mEventThreadSurfaceReplaced = TRUE; - } - mEventThreadWaitCondition.Notify(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// V-SYNC THREAD -/////////////////////////////////////////////////////////////////////////////////////////////////// - -bool ThreadSynchronization::VSyncReady( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender ) -{ - LOG_VSYNC_TRACE; - - // Ensure we do not process an invalid v-sync - if( validSync ) - { - bool minimumFrameTimeIntervalChanged = false; - { - ConditionalWait::ScopedLock vSyncLock( mVSyncThreadWaitCondition ); - if( numberOfVSyncsPerRender != mNumberOfVSyncsPerRender ) - { - numberOfVSyncsPerRender = mNumberOfVSyncsPerRender; // save it back - minimumFrameTimeIntervalChanged = true; - } - } - - if( minimumFrameTimeIntervalChanged ) - { - mFrameTime.SetMinimumFrameTimeInterval( mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS ); - } - - mFrameTime.SetSyncTime( frameNumber ); - - if( ! mVSyncThreadInitialised ) - { - LOG_VSYNC( "Initialised" ); - - mVSyncThreadInitialised = TRUE; - - // Notify event thread that this thread is up and running, this locks so we should have a scoped-lock - NotifyThreadInitialised(); - } - else - { - // Increment v-sync-ahead-of-update count and inform update-thread - { - ConditionalWait::ScopedLock lock( mUpdateThreadWaitCondition ); - ++mVSyncAheadOfUpdate; - LOG_VSYNC_COUNTER_VSYNC( " vSyncAheadOfUpdate(%d)", mVSyncAheadOfUpdate ); - } - mUpdateThreadWaitCondition.Notify(); - } - - // Ensure update-thread has set us to run before continuing - // Ensure we do not wait if we're supposed to stop - { - ConditionalWait::ScopedLock vSyncLock( mVSyncThreadWaitCondition ); - while( ! mVSyncThreadRunning && ! mVSyncThreadStop ) - { - LOG_VSYNC( "WAIT" ); - mVSyncThreadWaitCondition.Wait( vSyncLock ); - } - } - } - else - { - LOG_VSYNC( "INVALID SYNC" ); - - // Later we still check if the v-sync thread is supposed to keep running so we can still stop the thread if we are supposed to - } - - return IsVSyncThreadRunning(); // Call to this function locks so should not be called if we have a scoped-lock -} - -///////////////////////////////////////////////////////////////////////////////////////////////// -// POST RENDERING: EVENT THREAD -///////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::PostRenderComplete() -{ - LOG_EVENT_TRACE; - - { - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - mRenderThreadPostRendering = FALSE; - } - mRenderThreadWaitCondition.Notify(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// POST RENDERING: RENDER THREAD -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::PostRenderStarted() -{ - LOG_RENDER_TRACE; - - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - mRenderThreadPostRendering = TRUE; -} - -void ThreadSynchronization::PostRenderWaitForCompletion() -{ - LOG_RENDER_TRACE; - - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - while( mRenderThreadPostRendering && - ! mRenderThreadReplacingSurface ) // We should NOT wait if we're replacing the surface - { - LOG_RENDER( "WAIT" ); - mRenderThreadWaitCondition.Wait( lock ); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// ALL THREADS: Performance Marker -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::AddPerformanceMarker( PerformanceInterface::MarkerType type ) -{ - if( mPerformanceInterface ) - { - mPerformanceInterface->AddMarker( type ); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// PRIVATE METHODS -// -/////////////////////////////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Called by ALL Threads -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::NotifyThreadInitialised() -{ - { - ConditionalWait::ScopedLock lock( mEventThreadWaitCondition ); - ++mNumberOfThreadsStarted; - } - mEventThreadWaitCondition.Notify(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Called by Update Thread -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void ThreadSynchronization::UpdateInitialising() -{ - LOG_UPDATE_TRACE; - - // Notify event thread that this thread is up and running, locks so we shouldn't have a scoped-lock when calling this - NotifyThreadInitialised(); - - // Wait for first thread-sync point - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - - while( mState == State::INITIALISING ) - { - mUpdateThreadWaitCondition.Wait( updateLock ); - } - } - - // Locks so we shouldn't have a scoped-lock when calling this - RunVSyncThread(); -} - -void ThreadSynchronization::UpdateTryToSleep( bool runUpdate ) -{ - LOG_UPDATE_TRACE; - - if( ! runUpdate && - ! IsUpdateThreadResuming() ) // Locks so we shouldn't have a lock, we shouldn't try to sleep if we're JUST resuming - { - LOG_UPDATE( "TryToSleep" ); - - if( ++mTryToSleepCount >= 3 ) - { - LOG_UPDATE( "Going to sleep" ); - - // Locks so we shouldn't have a scoped-lock when calling this - PauseVSyncThread(); - - // Render thread will automatically wait as it relies on update-ahead-of-render count - - // Change the state - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - - // Ensure we weren't stopped while we have been processing - if( mState != State::STOPPED ) - { - mState = State::SLEEPING; - } - } - - // Inform FrameTime that we're going to sleep - mFrameTime.Sleep(); - - // Wait while we're SLEEPING - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - while( mState == State::SLEEPING ) - { - mUpdateThreadWaitCondition.Wait( updateLock ); - } - } - - //////////////////////// - // WAKE UP - //////////////////////// - - LOG_UPDATE( "Waking Up" ); - - // Clear V-Sync-ahead-of-update-count - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - mVSyncAheadOfUpdate = 0; - } - - // Restart the v-sync-thread, locks so we shouldn't have a scoped-lock - RunVSyncThread(); - - // Reset try-to-sleep count - mTryToSleepCount = 0; - - // Inform frame timer that we've woken up - mFrameTime.WakeUp(); - } - } - else - { - mTryToSleepCount = 0; - } -} - -void ThreadSynchronization::UpdateWaitIfReplacingSurface() -{ - bool replacingSurface = false; - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - replacingSurface = ( mState == State::REPLACING_SURFACE ); - } - while( replacingSurface ) - { - LOG_UPDATE_TRACE_FMT( "REPLACING SURFACE" ); - - // Locks so should not be called while we have a scoped-lock - PauseVSyncThread(); - - // One last check before we actually wait in case the state has changed since we checked earlier - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - replacingSurface = ( mState == State::REPLACING_SURFACE ); - if( replacingSurface ) - { - mUpdateThreadWaitCondition.Wait( updateLock ); - } - } - - { - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - mVSyncAheadOfUpdate = 0; - } - - // Locks so should not be called while we have a scoped-lock - RunVSyncThread(); - } -} - -bool ThreadSynchronization::IsUpdateThreadResuming() -{ - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - return mUpdateThreadResuming; -} - -bool ThreadSynchronization::IsUpdateThreadStopping() -{ - ConditionalWait::ScopedLock updateLock( mUpdateThreadWaitCondition ); - return ( mState == State::STOPPED ); -} - -bool ThreadSynchronization::MaximumUpdateAheadOfRenderReached() -{ - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - return mUpdateAheadOfRender >= mMaximumUpdateCount; -} - -void ThreadSynchronization::StopAllThreads() -{ - LOG_UPDATE_TRACE; - - // Lock so we shouldn't have a scoped-lock when calling these methods - StopVSyncThread(); - StopRenderThread(); -} - -void ThreadSynchronization::RunVSyncThread() -{ - { - ConditionalWait::ScopedLock lock( mVSyncThreadWaitCondition ); - mVSyncThreadRunning = TRUE; - } - mVSyncThreadWaitCondition.Notify(); -} - -void ThreadSynchronization::PauseVSyncThread() -{ - ConditionalWait::ScopedLock lock( mVSyncThreadWaitCondition ); - mVSyncThreadRunning = FALSE; -} - -void ThreadSynchronization::StopVSyncThread() -{ - { - ConditionalWait::ScopedLock lock( mVSyncThreadWaitCondition ); - mVSyncThreadStop = TRUE; - } - mVSyncThreadWaitCondition.Notify(); -} - -void ThreadSynchronization::StopRenderThread() -{ - { - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - mRenderThreadStop = TRUE; - } - mRenderThreadWaitCondition.Notify(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Called by V-Sync Thread -/////////////////////////////////////////////////////////////////////////////////////////////////// - -bool ThreadSynchronization::IsVSyncThreadRunning() -{ - ConditionalWait::ScopedLock lock( mVSyncThreadWaitCondition ); - return ! mVSyncThreadStop; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Called by Render Thread -/////////////////////////////////////////////////////////////////////////////////////////////////// - -bool ThreadSynchronization::IsRenderThreadRunning() -{ - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - return ! mRenderThreadStop; -} - -bool ThreadSynchronization::IsRenderThreadReplacingSurface() -{ - ConditionalWait::ScopedLock lock( mRenderThreadWaitCondition ); - return mRenderThreadReplacingSurface; -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/separate-update-render/thread-synchronization.h b/adaptors/base/separate-update-render/thread-synchronization.h deleted file mode 100644 index e5068fd..0000000 --- a/adaptors/base/separate-update-render/thread-synchronization.h +++ /dev/null @@ -1,436 +0,0 @@ -#ifndef __DALI_INTERNAL_THREAD_SYNCHRONIZATION_H__ -#define __DALI_INTERNAL_THREAD_SYNCHRONIZATION_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. - * - */ - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include -#include - -namespace Dali -{ - -class RenderSurface; - -namespace Internal -{ - -namespace Adaptor -{ - -class AdaptorInternalServices; - -/** - * This object is used to synchronize the update, render and vsync threads. - * The Core::GetMaximumUpdateCount() method determines how many frames may be prepared, ahead of the rendering. - * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed whilst frame N is being rendered. - * However the Core::Update() for frame N+2 may not be called, until the Core::Render() method for frame N has returned. - * - */ -class ThreadSynchronization : public Dali::ThreadSynchronizationInterface -{ -public: - - /** - * Create an update/render synchronization object. - * @param[in] adaptorInterfaces base adaptor interface - * @param[in] numberOfVSyncsPerRender The number of frames per render - */ - ThreadSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender ); - - /** - * Non virtual destructor. Not intended as base class. - */ - ~ThreadSynchronization(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by the Event Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Initialises the ThreadSynchronisation class. The expectation is that this function will be - * called when all threads are about to be set up and that Start will be called when - * the the scene is actually prepared and ready to be displayed. This way our first update - * will have the actual scene we require. - * - * @note Should only be called by the Event Thread. - */ - void Initialise(); - - /** - * Starts running all threads. This waits until all threads are up and running. - * - * @pre A call to Initialise has been made. - * - * @note Should only be called by the Event Thread. - */ - void Start(); - - /** - * Stop the threads. - * - * @note Should only be called by the Event Thread. - */ - void Stop(); - - /** - * Pause the controller (and threads). - * - * @note Should only be called by the Event Thread. - */ - void Pause(); - - /** - * Resume the controller (and threads). - * - * @note Should only be called by the Event Thread. - */ - void Resume(); - - /** - * Wake update thread if sleeping. If the update thread is not sleeping - * this becomes a no-op. - * Called when an update is requested by Core. - * i.e. when a batch of messages have been queued for the next update. - * - * @note Should only be called by the Event Thread. - */ - void UpdateRequest(); - - /** - * Update once (even if paused) - * - * @note Should only be called by the Event Thread. - */ - void UpdateOnce(); - - /** - * Inform the render thread that there is a new surface, and that - * it should replace the current surface. - * - * @param[in] newSurface The new surface for rendering. - * - * @note Should only be called by the Event Thread. - */ - void ReplaceSurface( RenderSurface* newSurface ); - - /** - * Set the refresh rate for rendering - * - * @param[in] numberOfVSyncsPerRender The number of vsync frames per render - * - * @note Should only be called by the Event Thread. - */ - void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender ); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by the Update Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Called by Update thread when it is ready to run the update. - * - * @param[in] notifyEvent Whether the event thread should be woken up. - * @param[in] runUpdate Whether to run another update. If false, then the update-thread will attempt to sleep. - * @param[out] lastFrameDeltaSeconds The delta, in seconds (with float precision), between the last two renders. - * @param[out] lastSyncTimeMilliseconds The time, in milliseconds, of the last Sync. - * @param[out] nextSyncTimeMilliseconds The estimated time, in milliseconds, at the next Sync. - * @return true if updating should continue, false if the update-thread should quit. - * - * @note Should only be called by the Update thread. - */ - bool UpdateReady( bool notifyEvent, bool runUpdate, float& lastFrameDeltaSeconds, unsigned int& lastSyncTimeMilliseconds, unsigned int& nextSyncTimeMilliseconds ); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by the Render Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Called by the Render thread when it is ready to render. - * - * @param[in] request Pointer to set if there are any requests. This does not need to be freed by the caller. - * - * @note Should only be called by the Render thread. - * @note If there is a request, then the Render thread should NOT perform a Render and only process the request - */ - bool RenderReady( RenderRequest*& request ); - - /** - * Called by the render thread after it renders a frame. - * Used to notify the update-thread that a frame has been rendered. - * @pre Called by render thread only. - */ - void RenderFinished(); - - /** - * Called by the Render thread to inform the synchronization class that the surface has been replaced. - * - * @note Should only be called by the Render thread. - */ - void RenderInformSurfaceReplaced(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by the V-Sync Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Called by the VSync notifier thread so it can sleep if Update/Render threads are sleeping/paused - * - * @param[in] validSync True if the sync was valid (@see VSyncMonitor::DoSync) - * @param[in] frameNumber The current frame number - * @param[in] seconds The current time - * @param[in] microseconds The current time - * @param[out] numberOfVSyncsPerRender The number of frames per render. - * @return true if VSync monitoring/notifications should continue. - * - * @note Should only be called by the VSync thread. - * @note The first call to this method should be BEFORE the actual VSync so a thread-sync point can be established (and startup time is not delayed). - */ - bool VSyncReady( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender ); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // POST RENDERING - ///////////////////////////////////////////////////////////////////////////////////////////////// - - ///////////////////////////////////////////////////////////////////////////////////////////////// - //// Called by the Event Thread if post-rendering is required - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * @copydoc ThreadSynchronizationInterface::PostRenderComplete() - */ - void PostRenderComplete(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - //// Called by the Render Thread if post-rendering is required - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * @copydoc ThreadSynchronizationInterface::PostRenderStarted() - */ - void PostRenderStarted(); - - /** - * @copydoc ThreadSynchronizationInterface::PostRenderStarted() - */ - void PostRenderWaitForCompletion(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by ALL Threads - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Helper to add a performance marker to the performance server (if it's active) - * @param type performance marker type - */ - void AddPerformanceMarker( PerformanceInterface::MarkerType type ); - -private: - - // Undefined copy constructor. - ThreadSynchronization( const ThreadSynchronization& ); - - // Undefined assignment operator. - ThreadSynchronization& operator=( const ThreadSynchronization& ); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by ALL Threads - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Called by the update, render & v-sync thread when they up and running. - * This will lock the mutex in mEventThreadWaitCondition. - */ - inline void NotifyThreadInitialised(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by Update Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Called by the update-thread when the state is State::INITIALISING. - * Calls methods that lock and locks itself so should NOT be called while a scoped-lock is held. - */ - void UpdateInitialising(); - - /** - * Called by the update thread to attempt to sleep. - * @param[in] runUpdate Whether to run another update. If false, then the update-thread will attempt to sleep. - */ - void UpdateTryToSleep( bool runUpdate ); - - /** - * Called by the update thread to wait while the render-surface is being replaced. - * Calls methods that lock and locks itself so should NOT be called while a scoped-lock is held. - */ - void UpdateWaitIfReplacingSurface(); - - /** - * Called by the update thread to check if we're just resuming. - * This will lock the mutex in mUpdateThreadWaitCondition. - */ - inline bool IsUpdateThreadResuming(); - - /** - * Called by the update thread to check if the update thread should be running. - * This will lock the mutex in mUpdateThreadWaitCondition. - * - * @return True if we're stopping, false otherwise. - */ - inline bool IsUpdateThreadStopping(); - - /** - * Called by the update thread to check if we've filled all update buffers. - * This will lock the mutex in mRenderThreadWaitCondition. - * - * @return True if all update buffers are full. - */ - inline bool MaximumUpdateAheadOfRenderReached(); - - /** - * Called by the update thread when we are about to stop. - * This will call other functions which lock various conditional wait mutexes. - */ - inline void StopAllThreads(); - - /** - * Runs the V-Sync Thread. - * This will lock the mutex in mVSyncThreadWaitCondition. - */ - inline void RunVSyncThread(); - - /** - * Pauses the V-Sync Thread. - * This will lock the mutex in mVSyncThreadWaitCondition. - */ - inline void PauseVSyncThread(); - - /** - * Stops the V-Sync Thread. - * This will lock the mutex in mVSyncThreadWaitCondition. - */ - inline void StopVSyncThread(); - - /** - * Stops the Render Thread. - * This will lock the mutex in mRenderThreadWaitCondition. - */ - inline void StopRenderThread(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by V-Sync Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Checks if the V-Sync thread should be running. - * This will lock the mutex in mVSyncThreadWaitCondition. - * - * @return true if running, false otherwise. - */ - inline bool IsVSyncThreadRunning(); - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Called by Render Thread - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Checks if the Render thread should be running. - * This will lock the mutex in mRenderThreadWaitCondition. - * - * @return true if running, false otherwise. - */ - inline bool IsRenderThreadRunning(); - - /** - * Checks if the render thread should be replacing the surface - * This will lock the mutex in mRenderThreadWaitCondition. - * - * @return true if the render thread should be replacing the surface, false otherwise. - */ - inline bool IsRenderThreadReplacingSurface(); - -private: - - struct State - { - enum Type - { - STOPPED, - INITIALISING, - RUNNING, - PAUSED, - SLEEPING, - REPLACING_SURFACE - }; - }; - - FrameTime mFrameTime; ///< Frame timer predicts next vsync time - TriggerEventInterface& mNotificationTrigger; ///< Reference to notification event trigger - PerformanceInterface* mPerformanceInterface; ///< The performance logging interface - ReplaceSurfaceRequest mReplaceSurfaceRequest; ///< Holder for a replace surface request - - ConditionalWait mUpdateThreadWaitCondition; ///< The wait condition for the update-thread. - ConditionalWait mRenderThreadWaitCondition; ///< The wait condition for the render-thread. - ConditionalWait mVSyncThreadWaitCondition; ///< The wait condition for the v-sync-thread. - ConditionalWait mEventThreadWaitCondition; ///< The wait condition for the event-thread. - - const int mMaximumUpdateCount; ///< How many frames may be prepared, ahead of the rendering. - unsigned int mNumberOfVSyncsPerRender; ///< How many frames for each update/render cycle. - - unsigned int mTryToSleepCount; ///< Count to ensure we don't go to sleep too early - - volatile State::Type mState; ///< The current state of synchronisation (set & read by both the event & update threads). - - volatile int mVSyncAheadOfUpdate; ///< The number of frames vsync is ahead of update (set & read by both the v-sync & update threads). - volatile int mUpdateAheadOfRender; ///< The number of frames update is ahead of render (set & read by both the update & render threads). - volatile int mNumberOfThreadsStarted; ///< The number of threads that are initialised and running (set by update, v-sync & render threads, read by event-thread). - - // - // NOTE: cannot use booleans as these are used from multiple threads, must use variable with machine word size for atomic read/write - // - - volatile unsigned int mUpdateThreadResuming; ///< Whether the update-thread is resuming. - - volatile unsigned int mVSyncThreadRunning; ///< Whether the V-Sync thread is running (set by the update-thread, read by v-sync-thread). - volatile unsigned int mVSyncThreadStop; ///< Whether the V-Sync thread should be stopped (set by the update-thread, read by the v-sync-thread). - - volatile unsigned int mRenderThreadStop; ///< Whether the render-thread should be stopped (set by the update-thread, read by the render-thread). - volatile unsigned int mRenderThreadReplacingSurface;///< Whether the render-thread should replace the surface (set by the event & render threads, read by the render-thread). - - volatile unsigned int mRenderThreadPostRendering; ///< Whether post-rendering is taking place (set by the event & render threads, read by the render-thread). - - volatile unsigned int mEventThreadSurfaceReplaced; ///< Checked by the event-thread & set by the render-thread when the surface has been replaced (set by the event & render threads, read by the event-thread). - - unsigned int mVSyncThreadInitialised; ///< Whether the V-Sync thread has been initialised (only used by v-sync-thread). - unsigned int mRenderThreadInitialised; ///< Whether the render-thread has been initialised (only used by the render-thread). - unsigned int mRenderThreadSurfaceReplaced; ///< Whether the render-thread has replaced the surface (only used by render-thread). -}; // class ThreadSynchronization - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_THREAD_SYNCHRONIZATION_H__ diff --git a/adaptors/base/separate-update-render/update-thread.cpp b/adaptors/base/separate-update-render/update-thread.cpp deleted file mode 100644 index a0bcd97..0000000 --- a/adaptors/base/separate-update-render/update-thread.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 "update-thread.h" - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -#if defined(DEBUG_ENABLED) -Integration::Log::Filter* gUpdateLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_THREAD"); -#endif -} // unnamed namespace - -UpdateThread::UpdateThread( ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions ) -: mThreadSynchronization( sync ), - mCore( adaptorInterfaces.GetCore()), - mFpsTracker( environmentOptions ), - mUpdateStatusLogger( environmentOptions ), - mThread( NULL ), - mEnvironmentOptions( environmentOptions ) -{ -} - -UpdateThread::~UpdateThread() -{ - Stop(); -} - -void UpdateThread::Start() -{ - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Start()\n"); - if ( !mThread ) - { - // Create and run the update-thread - mThread = new pthread_t(); - int error = pthread_create( mThread, NULL, InternalThreadEntryFunc, this ); - DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() in UpdateThread" ); - } -} - -void UpdateThread::Stop() -{ - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Stop()\n"); - if( mThread ) - { - // wait for the thread to finish - pthread_join(*mThread, NULL); - - delete mThread; - mThread = NULL; - } -} - -bool UpdateThread::Run() -{ - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run()\n"); - - // Install a function for logging - mEnvironmentOptions.InstallLogFunction(); - - Integration::UpdateStatus status; - bool runUpdate = true; - float lastFrameDelta( 0.0f ); - unsigned int lastSyncTime( 0 ); - unsigned int nextSyncTime( 0 ); - - // Update loop, we stay inside here while the update-thread is running - // We also get the last delta and the predict when this update will be rendered - while ( mThreadSynchronization.UpdateReady( status.NeedsNotification(), runUpdate, lastFrameDelta, lastSyncTime, nextSyncTime ) ) - { - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 1 - UpdateReady(delta:%f, lastSync:%u, nextSync:%u)\n", lastFrameDelta, lastSyncTime, nextSyncTime); - - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 2 - Core.Update()\n"); - - mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::UPDATE_START ); - mCore.Update( lastFrameDelta, lastSyncTime, nextSyncTime, status ); - mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::UPDATE_END ); - - mFpsTracker.Track( status.SecondsFromLastFrame() ); - - unsigned int keepUpdatingStatus = status.KeepUpdating(); - - // Optional logging of update/render status - mUpdateStatusLogger.Log( keepUpdatingStatus ); - - // 2 things can keep update running. - // - The status of the last update - // - The status of the last render - runUpdate = (Integration::KeepUpdating::NOT_REQUESTED != keepUpdatingStatus); - - DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 3 - runUpdate(%d)\n", runUpdate ); - - // Reset time variables - lastFrameDelta = 0.0f; - lastSyncTime = 0; - nextSyncTime = 0; - } - - // Uninstall the logging function - mEnvironmentOptions.UnInstallLogFunction(); - - return true; -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/separate-update-render/update-thread.h b/adaptors/base/separate-update-render/update-thread.h deleted file mode 100644 index 0f861a9..0000000 --- a/adaptors/base/separate-update-render/update-thread.h +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef __DALI_INTERNAL_UPDATE_THREAD_H__ -#define __DALI_INTERNAL_UPDATE_THREAD_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. - * - */ - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include -#include - -namespace Dali -{ - -namespace Integration -{ -class Core; -} - -namespace Internal -{ - -namespace Adaptor -{ - -class ThreadSynchronization; -class AdaptorInternalServices; -class EnvironmentOptions; - -/** - * The update-thread is responsible for calling Core::Update(), and - * for triggering the render-thread after each update. - */ -class UpdateThread -{ -public: - - /** - * Create the update-thread; this will not do anything until Start() is called. - * @param[in] sync An object used to synchronize update & render threads. - * @param[in] adaptorInterfaces base adaptor interface - * @param[in] environmentOptions environment options - */ - UpdateThread(ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions ); - - /** - * Non-virtual destructor; UpdateThread is not suitable as a base class. - */ - ~UpdateThread(); - - /** - * Starts the update-thread - */ - void Start(); - - /** - * Stops the update-thread - */ - void Stop(); - -private: - - /** - * This method is used by the update-thread for calling Core::Update(). - * @return true, if the thread finishes properly. - */ - bool Run(); - - /** - * Helper for the thread calling the entry function - * @param[in] This A pointer to the current UpdateThread object - */ - static inline void* InternalThreadEntryFunc( void* This ) - { - ( static_cast( This ) )->Run(); - return NULL; - } - -private: // Data - - ThreadSynchronization& mThreadSynchronization; ///< Used to synchronize all the threads - - Dali::Integration::Core& mCore; ///< Dali core reference - - FpsTracker mFpsTracker; ///< Object that tracks the FPS - UpdateStatusLogger mUpdateStatusLogger; ///< Object that logs the update-status as required. - - pthread_t* mThread; ///< The actual update-thread. - const EnvironmentOptions& mEnvironmentOptions; ///< environment options -}; // class UpdateThread - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_UPDATE_THREAD_H__ diff --git a/adaptors/base/separate-update-render/vsync-notifier.cpp b/adaptors/base/separate-update-render/vsync-notifier.cpp deleted file mode 100644 index 7ea74b4..0000000 --- a/adaptors/base/separate-update-render/vsync-notifier.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2016 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 "vsync-notifier.h" - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ - -const unsigned int NANOSECONDS_PER_SECOND( 1e+9 ); -const unsigned int NANOSECONDS_PER_MICROSECOND( 1000u ); -const unsigned int MICROSECONDS_PER_SECOND( 1000000u ); -const unsigned int TIME_PER_FRAME_IN_MICROSECONDS( 16667u ); - -#if defined(DEBUG_ENABLED) -Integration::Log::Filter* gSyncLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_VSYNC_NOTIFIER"); -#endif - -} // unnamed namespace - -VSyncNotifier::VSyncNotifier( ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions ) -: mThreadSynchronization( sync ), - mCore( adaptorInterfaces.GetCore() ), - mVSyncMonitor( adaptorInterfaces.GetVSyncMonitorInterface() ), - mThread( NULL ), - mEnvironmentOptions( environmentOptions ), - mNumberOfVSyncsPerRender(1) -{ -} - -VSyncNotifier::~VSyncNotifier() -{ - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ ); - - Stop(); -} - -void VSyncNotifier::Start() -{ - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ ); - - if ( !mThread ) - { - mVSyncMonitor->Initialize(); - - mThread = new pthread_t(); - int error = pthread_create( mThread, NULL, InternalThreadEntryFunc, this ); - DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() in VSyncNotifier" ); - } -} - -void VSyncNotifier::Stop() -{ - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ ); - - if( mThread ) - { - // wait for the thread to finish - pthread_join(*mThread, NULL); - - delete mThread; - mThread = NULL; - } - - mVSyncMonitor->Terminate(); -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// The following is executed inside the notifier thread !!! -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void VSyncNotifier::Run() -{ - // install a function for logging - mEnvironmentOptions.InstallLogFunction(); - - unsigned int frameNumber( 0u ); // frameCount, updated when the thread is paused - unsigned int currentSequenceNumber( 0u ); // platform specific vsync sequence number (increments with each vsync) - unsigned int currentSeconds( 0u ); // timestamp at latest sync - unsigned int currentMicroseconds( 0u ); // timestamp at latest sync - uint64_t seconds( 0u ); - uint64_t microseconds( 0u ); - - bool validSync( true ); - while( mThreadSynchronization.VSyncReady( validSync, frameNumber++, currentSeconds, currentMicroseconds, mNumberOfVSyncsPerRender ) ) - { - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 1 SyncWithUpdateAndRender(frame#:%d, current Sec:%u current uSec:%u)\n", frameNumber-1, currentSeconds, currentMicroseconds); - - // Hardware VSyncs available? - if( mVSyncMonitor->UseHardware() ) - { - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 2 Start hardware sync (%d frames) \n", mNumberOfVSyncsPerRender); - - for( unsigned int i=0; iDoSync( currentSequenceNumber, currentSeconds, currentMicroseconds ); - } - } - else - { - // No..use software timer - uint64_t nanoseconds = 0; - TimeService::GetNanoseconds( nanoseconds ); - - seconds = nanoseconds / NANOSECONDS_PER_SECOND; // Convert to seconds - nanoseconds -= seconds * NANOSECONDS_PER_SECOND; // Only want remainder nanoseconds - microseconds = nanoseconds / NANOSECONDS_PER_MICROSECOND; // Convert to microseconds - - unsigned int timeDelta( MICROSECONDS_PER_SECOND * (seconds - currentSeconds) ); - if( microseconds < currentMicroseconds) - { - timeDelta += (microseconds + MICROSECONDS_PER_SECOND) - currentMicroseconds; - } - else - { - timeDelta += microseconds - currentMicroseconds; - } - - currentSeconds = seconds; - currentMicroseconds = microseconds; - - unsigned int sleepTimeInMicroseconds = 0; - - if( timeDelta < TIME_PER_FRAME_IN_MICROSECONDS ) - { - sleepTimeInMicroseconds = TIME_PER_FRAME_IN_MICROSECONDS - timeDelta; - } - sleepTimeInMicroseconds += mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS; - - DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 2 Start software sync (%d frames, %u microseconds) \n", mNumberOfVSyncsPerRender, sleepTimeInMicroseconds); - - timespec sleepTime; - sleepTime.tv_sec = 0; - sleepTime.tv_nsec = sleepTimeInMicroseconds; - sleepTime.tv_nsec *= NANOSECONDS_PER_MICROSECOND; - nanosleep( &sleepTime, NULL ); - } - mThreadSynchronization.AddPerformanceMarker( PerformanceInterface::VSYNC ); - } - - // uninstall a function for logging - mEnvironmentOptions.UnInstallLogFunction(); - -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/separate-update-render/vsync-notifier.h b/adaptors/base/separate-update-render/vsync-notifier.h deleted file mode 100644 index 86cdc24..0000000 --- a/adaptors/base/separate-update-render/vsync-notifier.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef __DALI_INTERNAL_VSYNC_NOTIFIER_H__ -#define __DALI_INTERNAL_VSYNC_NOTIFIER_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. - * - */ - -// EXTERNAL INCLUDES -#include - -namespace Dali -{ - -namespace Integration -{ - -class Core; -class PlatformAbstraction; - -} // namespace Integration - -namespace Internal -{ - -namespace Adaptor -{ - -class VSyncMonitorInterface; -class ThreadSynchronization; -class EnvironmentOptions; -class AdaptorInternalServices; - -/** - * Implements a simple class that either monitors vertical blanks from libdrm, or manages - * a software timer to handle syncing. - */ -class VSyncNotifier -{ -public: - - /** - * Create the vsync notification thread; this will not start to monitor vsync and - * send notifications until Start() is called. - * @param[in] sync An object used to synchronize update, render and vsync threads. - * @param[in] adaptorInterfaces base adaptor interface - * @param[in] environmentOptions environment options - */ - VSyncNotifier( ThreadSynchronization& sync, - AdaptorInternalServices& adaptorInterfaces, - const EnvironmentOptions& environmentOptions); - - /** - * Non-virtual destructor; VSyncNotifier is not suitable as a base class. - */ - ~VSyncNotifier(); - - /** - * Starts the thread - */ - void Start(); - - /** - * Stops the thread - */ - void Stop(); - -private: - - /** - * The main thread loop. The system thread will be destroyed on - * exit from this function. - */ - void Run(); - - /** - * Helper for the thread calling the entry function - * @param[in] This A pointer to the current VSyncNotifier object - */ - static inline void* InternalThreadEntryFunc( void* This ) - { - ( static_cast( This ) )->Run(); - return NULL; - } - -private: - - ThreadSynchronization& mThreadSynchronization; ///< Used to synchronize all the threads - Dali::Integration::Core& mCore; ///< Dali core reference - VSyncMonitorInterface* mVSyncMonitor; ///< VSyncMonitor interface - pthread_t* mThread; ///< The actual thread. - const EnvironmentOptions& mEnvironmentOptions; ///< Environment options - unsigned int mNumberOfVSyncsPerRender; ///< How many frames for each update/render cycle. - -}; // class VSyncNotifier - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_VSYNC_NOTIFIER_H__ diff --git a/adaptors/base/single-threaded/single-thread-controller.cpp b/adaptors/base/single-threaded/single-thread-controller.cpp deleted file mode 100644 index e24429a..0000000 --- a/adaptors/base/single-threaded/single-thread-controller.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * 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 "single-thread-controller.h" - -// EXTERNAL INCLUDES -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ - -namespace Adaptor -{ - -namespace -{ -const unsigned int MILLISECONDS_PER_FRAME = 17u; -const float SECONDS_PER_FRAME = MILLISECONDS_PER_FRAME * 0.001f; - -const unsigned int NANOSECONDS_PER_MICROSECOND( 1000u ); -const float NANOSECONDS_TO_SECONDS( 1e-9f ); - -#if defined(DEBUG_ENABLED) -Integration::Log::Filter* gLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_THREAD_SYNC"); -#endif - -} // unnamed namespace - -SingleThreadController::SingleThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions ) -: ConnectionTracker(), - ThreadControllerInterface(), - mTimer(), - mFpsTracker( environmentOptions ), - mUpdateStatusLogger( environmentOptions ), - mRenderHelper( adaptorInterfaces ), - mCore( adaptorInterfaces.GetCore()), - mPerformanceInterface( adaptorInterfaces.GetPerformanceInterface() ), - mLastUpdateRenderTime( 0 ), - mSystemTime( 0 ), - mRefreshRate( environmentOptions.GetRenderRefreshRate() ), - mState( State::STOPPED ), - mUpdatingAndRendering( false ), - mStopRequestedWhileRendering( false ) -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); -} - -SingleThreadController::~SingleThreadController() -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - Stop(); -} - -void SingleThreadController::Initialize() -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - mTimer = Dali::Timer::New( mRefreshRate * MILLISECONDS_PER_FRAME ); - - // Create a tick-signal so that we can update and render every frame - mTimer.TickSignal().Connect( this, &SingleThreadController::OnTimerTick ); -} - -void SingleThreadController::Start() -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - mRenderHelper.Start(); - mRenderHelper.InitializeEgl(); - - // tell core it has a context - mCore.ContextCreated(); - - // Do an update/render straight away - UpdateTimeSinceLastRender(); - UpdateRender( false ); - - ChangeState( State::RUNNING ); -} - -void SingleThreadController::Pause() -{ - if( mState == State::RUNNING ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - ChangeState( State::PAUSED ); - - AddPerformanceMarker( PerformanceInterface::PAUSED ); - } -} - -void SingleThreadController::Resume() -{ - if( mState == State::PAUSED ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - // Do an update/render straight away - UpdateTimeSinceLastRender(); - UpdateRender( false ); - - ChangeState( State::RUNNING ); - - AddPerformanceMarker( PerformanceInterface::RESUME ); - } -} - -void SingleThreadController::Stop() -{ - if( mState != State::STOPPED ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - ChangeState( State::STOPPED ); - - if( mUpdatingAndRendering ) - { - // If we interrupted an update/render for this stop, then we should NOT terminate GL just yet - mStopRequestedWhileRendering = true; - } - else - { - StopRendering(); - } - } -} - -void SingleThreadController::RequestUpdate() -{ - if( mState == State::SLEEPING ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - // Do an update/render straight away - UpdateTimeSinceLastRender(); - UpdateRender( false ); - - ChangeState( State::RUNNING ); - } -} - -void SingleThreadController::RequestUpdateOnce() -{ - if( mState == State::SLEEPING || mState == State::PAUSED ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - // Just do one update and render - - Integration::UpdateStatus status; - mCore.Update( 0.0f, mLastUpdateRenderTime, mLastUpdateRenderTime + mRefreshRate * MILLISECONDS_PER_FRAME, status ); - - Render(); - } -} - -void SingleThreadController::ReplaceSurface( RenderSurface* newSurface ) -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - mRenderHelper.ReplaceSurface( newSurface ); -} - -void SingleThreadController::SetRenderRefreshRate( unsigned int refreshRate ) -{ - if ( refreshRate != mRefreshRate ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - mRefreshRate = refreshRate; - - if( mTimer ) - { - mTimer.SetInterval( mRefreshRate * MILLISECONDS_PER_FRAME ); - } - } -} - -bool SingleThreadController::OnTimerTick() -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s()\n", __FUNCTION__ ); - - if( mState == State::RUNNING ) - { - UpdateRender( true ); - } - else if( mState == State::STOPPED && - mStopRequestedWhileRendering ) - { - DALI_LOG_INFO( gLogFilter, Debug::General, "%s(): STOPPING\n", __FUNCTION__ ); - - StopRendering(); - - mStopRequestedWhileRendering = false; - - return false; // Stop the timer - } - return true; -} - -void SingleThreadController::UpdateRender( bool incrementTime ) -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "%s():START\n", __FUNCTION__ ); - - mUpdatingAndRendering = true; - - float lastFrameDelta( 0.0f ); - - if( incrementTime ) - { - // Use our usual time per frame for smoother animations rather than the real elapsed time - - lastFrameDelta = mRefreshRate * SECONDS_PER_FRAME; - mLastUpdateRenderTime += mRefreshRate * MILLISECONDS_PER_FRAME; - } - - Integration::UpdateStatus updateStatus; - AddPerformanceMarker( PerformanceInterface::UPDATE_START ); - mCore.Update( lastFrameDelta, mLastUpdateRenderTime, mLastUpdateRenderTime + mRefreshRate * MILLISECONDS_PER_FRAME, updateStatus ); - AddPerformanceMarker( PerformanceInterface::UPDATE_END ); - - mFpsTracker.Track( UpdateTimeSinceLastRender() ); - - unsigned int keepUpdatingStatus = updateStatus.KeepUpdating(); - - // Optional logging of update/render status - mUpdateStatusLogger.Log( keepUpdatingStatus ); - - // Ensure we did not get interrupted an STOPPED - if( mState != State::STOPPED ) - { - mRenderHelper.ConsumeEvents(); - - const bool needsUpdate = Render(); - - if( !keepUpdatingStatus && !needsUpdate ) - { - ChangeState( State::SLEEPING ); - } - } - - mUpdatingAndRendering = false; - - DALI_LOG_INFO( gLogFilter, Debug::General, "%s():END\n", __FUNCTION__ ); -} - -float SingleThreadController::UpdateTimeSinceLastRender() -{ - float timeSinceLastRender = 0.0f; - - // No need calculating if FPS tracking is NOT enabled - if( mFpsTracker.Enabled() ) - { - uint64_t currentTime = 0; - TimeService::GetNanoseconds( currentTime ); - - uint64_t delta = currentTime - mSystemTime; - mSystemTime = currentTime; - - timeSinceLastRender = delta * NANOSECONDS_TO_SECONDS; - } - - return timeSinceLastRender; -} - - -void SingleThreadController::AddPerformanceMarker( PerformanceInterface::MarkerType type ) -{ - if( mPerformanceInterface ) - { - mPerformanceInterface->AddMarker( type ); - } -} - -void SingleThreadController::ChangeState( State::Type state ) -{ - mState = state; - - switch( state ) - { - case State::RUNNING: - { - mTimer.Start(); - break; - } - - case State::STOPPED: - case State::PAUSED: - case State::SLEEPING: - { - mTimer.Stop(); - } - } -} - -void SingleThreadController::StopRendering() -{ - mRenderHelper.Stop(); - - // Inform core of context destruction & shutdown EGL - mCore.ContextDestroyed(); - mRenderHelper.ShutdownEgl(); -} - -bool SingleThreadController::Render() -{ - mRenderHelper.PreRender(); - - Integration::RenderStatus renderStatus; - AddPerformanceMarker( PerformanceInterface::RENDER_START ); - mCore.Render( renderStatus ); - AddPerformanceMarker( PerformanceInterface::RENDER_END ); - - if( renderStatus.NeedsPostRender() ) - { - mRenderHelper.PostRender(); - } - - return renderStatus.NeedsUpdate(); -} - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali diff --git a/adaptors/base/single-threaded/single-thread-controller.h b/adaptors/base/single-threaded/single-thread-controller.h deleted file mode 100644 index 01dbdb1..0000000 --- a/adaptors/base/single-threaded/single-thread-controller.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef __DALI_INTERNAL_SINGLE_THREAD_CONTROLLER_H__ -#define __DALI_INTERNAL_SINGLE_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. - * - */ - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include - -namespace Dali -{ - -class RenderSurface; - -namespace Internal -{ - -namespace Adaptor -{ - -class AdaptorInternalServices; -class EnvironmentOptions; - -/** - * Single Thread Controller, where events, updates & renders ALL occur on the same thread. - */ -class SingleThreadController : public ConnectionTracker, - public ThreadControllerInterface -{ -public: - - /** - * Constructor - */ - SingleThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions ); - - /** - * Non virtual destructor. Not intended as base class. - */ - ~SingleThreadController(); - - /** - * @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 refreshRate ); - -private: - - /** - * State Machine - */ - struct State - { - enum Type - { - STOPPED, - RUNNING, - PAUSED, - SLEEPING - }; - }; - - // Undefined copy constructor. - SingleThreadController( const SingleThreadController& ); - - // Undefined assignment operator. - SingleThreadController& operator=( const SingleThreadController& ); - - /** - * Ticks whenever the timer expires - */ - bool OnTimerTick(); - - /** - * Runs the update and render - * - * @param[in] incrementTime If true, then the animation times are incremented. - */ - void UpdateRender( bool incrementTime ); - - /** - * Updates mCurrentTime and gets the time elapsed (in seconds) since last time this function was called. - * - * @return time elapsed (in seconds) since last call. - */ - float UpdateTimeSinceLastRender(); - - /** - * Helper to add a performance marker to the performance server (if it's active) - * @param type performance marker type - */ - void AddPerformanceMarker( PerformanceInterface::MarkerType type ); - - /** - * Changes the state and performs any other state-change related functionality. - * @param[in] state The new state - */ - void ChangeState( State::Type state ); - - /** - * Performs operations to stop rendering, e.g. informing Core of context being destroyed & shutting down EGL. - */ - void StopRendering(); - - /** - * Runs render (along with pre & post steps as required). - * @return True if an update is required. - */ - bool Render(); - -private: - - Dali::Timer mTimer; ///< Ensures an update & render is run every frame. - FpsTracker mFpsTracker; ///< Object that tracks the FPS - UpdateStatusLogger mUpdateStatusLogger; ///< Object that logs the update-status as required. - - RenderHelper mRenderHelper; ///< Helper class for EGL, pre & post rendering - - Integration::Core& mCore; ///< DALi core reference - PerformanceInterface* mPerformanceInterface; ///< The performance logging interface - - uint64_t mLastUpdateRenderTime; ///< Last time we did an update and render - uint64_t mSystemTime; ///< The current system time for FPS calculations - unsigned int mRefreshRate; ///< Frame skipping count - State::Type mState; ///< The state - bool mUpdatingAndRendering:1; ///< Set to true when we are updating and rendering. - bool mStopRequestedWhileRendering:1; ///< Set to true if we were told to stop while we were in the middle of a render -}; - -} // namespace Adaptor - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_SINGLE_THREAD_CONTROLLER_H__ diff --git a/adaptors/base/thread-controller.cpp b/adaptors/base/thread-controller.cpp index ed12064..84d4cf8 100644 --- a/adaptors/base/thread-controller.cpp +++ b/adaptors/base/thread-controller.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include namespace Dali { @@ -39,23 +37,11 @@ ThreadController::ThreadController( AdaptorInternalServices& adaptorInterfaces, { switch( environmentOptions.GetThreadingMode() ) { - case ThreadingMode::SEPARATE_UPDATE_RENDER: - { - mThreadControllerInterface = new SeparateUpdateRenderController( adaptorInterfaces, environmentOptions ); - break; - } - case ThreadingMode::COMBINED_UPDATE_RENDER: { mThreadControllerInterface = new CombinedUpdateRenderController( adaptorInterfaces, environmentOptions ); break; } - - case ThreadingMode::SINGLE_THREADED: - { - mThreadControllerInterface = new SingleThreadController( adaptorInterfaces, environmentOptions ); - break; - } } } diff --git a/adaptors/base/threading-mode.h b/adaptors/base/threading-mode.h index 73df356..cafefb9 100644 --- a/adaptors/base/threading-mode.h +++ b/adaptors/base/threading-mode.h @@ -31,9 +31,7 @@ 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. + COMBINED_UPDATE_RENDER = 1, ///< Three threads: Event, V-Sync & a Joint Update/Render thread. }; }; diff --git a/adaptors/wayland/render-surface/render-surface-wl.cpp b/adaptors/wayland/render-surface/render-surface-wl.cpp index e9c1348..e2c83cd 100644 --- a/adaptors/wayland/render-surface/render-surface-wl.cpp +++ b/adaptors/wayland/render-surface/render-surface-wl.cpp @@ -26,7 +26,6 @@ #include // INTERNAL INCLUDES -#include #include #include #include -- 2.7.4