From: Adeel Kazmi Date: Fri, 5 Jul 2019 16:47:36 +0000 (+0000) Subject: Merge "Ability to retrieve all the property values of a handle" into devel/master X-Git-Tag: dali_1.4.28~4 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=3d764bd366a93b07eae6e6ab29a23c6f8c98250d;hp=5ffeb6f8f963302fa1ac675677692dc6b258c710 Merge "Ability to retrieve all the property values of a handle" into devel/master --- diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 8267394..17c4767 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -93,6 +93,7 @@ SET(TC_SOURCES utc-Dali-Texture.cpp utc-Dali-TextureSet.cpp utc-Dali-Thread.cpp + utc-Dali-ThreadPool.cpp utc-Dali-TouchEventCombiner.cpp utc-Dali-TouchProcessing.cpp utc-Dali-TouchDataProcessing.cpp diff --git a/automated-tests/src/dali/utc-Dali-KeyEvent.cpp b/automated-tests/src/dali/utc-Dali-KeyEvent.cpp index e2de6e5..bdc7d4a 100755 --- a/automated-tests/src/dali/utc-Dali-KeyEvent.cpp +++ b/automated-tests/src/dali/utc-Dali-KeyEvent.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -400,3 +401,14 @@ int UtcDaliKeyEventSetDeviceSubclass(void) END_TEST; } + +int UtcDaliKeyEventSetLogicalKey(void) +{ + TestApplication application; + + KeyEvent event(TEST_STRING_1,"i", 99, SHIFT_MODIFIER, 0lu, KeyEvent::Down); + + DALI_TEST_EQUALS( DevelKeyEvent::GetLogicalKey( event ), "", TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-ThreadPool.cpp b/automated-tests/src/dali/utc-Dali-ThreadPool.cpp new file mode 100644 index 0000000..c7c6335 --- /dev/null +++ b/automated-tests/src/dali/utc-Dali-ThreadPool.cpp @@ -0,0 +1,185 @@ +/* + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +namespace +{ +Dali::ThreadPool gThreadPool; + +// Helper function dividing workload into N batches +// the loop lambda contains +Dali::UniqueFutureGroup ForEachMT( Dali::ThreadPool* pThreadPool, + uint32_t first, + uint32_t size, + std::function task ) +{ + uint32_t i = 0; + uint32_t j = 0; + const auto workerCount = uint32_t(pThreadPool->GetWorkerCount()); + const auto step = size / workerCount; + j = workerCount + step; + + std::vector tasks; + tasks.reserve( workerCount ); + + for( auto threadIndex = 0u; threadIndex < workerCount; ++threadIndex ) + { + Dali::Task lambda = [task, i, j]( int workerIndex ) + { + task( uint32_t(workerIndex), i, j ); + }; + tasks.emplace_back( lambda ); + i = j; + j = i + step; + if( j > size ) + j = size; + } + return pThreadPool->SubmitTasks( tasks, workerCount ); +} + +} + +int UtcDaliThreadPoolMultipleTasks(void) +{ + // initialise global thread pool + if( !gThreadPool.GetWorkerCount() ) + { + gThreadPool.Initialize( 0u ); + } + + // populate inputs + std::array inputs; + int checksum = 0; + for( auto i = 0; i < decltype(i)(inputs.size()); ++i ) + { + inputs[i] = i; + checksum += i; + } + + // allocate outputs ( number of outputs equals number of worker threads + auto workerCount = gThreadPool.GetWorkerCount(); + + std::vector outputs; + outputs.resize( workerCount ); + std::fill( outputs.begin(), outputs.end(), 0 ); + + // submit + auto future = ForEachMT( &gThreadPool, 0, inputs.size(), [&inputs, &outputs]( uint32_t workerIndex, uint32_t begin, uint32_t end ) + { + for( auto i = begin; i < end; ++i ) + { + outputs[workerIndex] += inputs[i]; + } + }); + + future->Wait(); + + // check outputs + int checksum2 = 0; + for( auto output : outputs ) + { + checksum2 += output; + } + + printf("sum: %d, sum2: %d\n", checksum, checksum2); + + + DALI_TEST_EQUALS( checksum, checksum2, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliThreadPoolSingleTask(void) +{ + // initialise global thread pool + if( !gThreadPool.GetWorkerCount() ) + { + gThreadPool.Initialize( 0u ); + } + + // some long lasting task + int counter = 0; + auto task = [&counter]( int workerIndex ){ + for( int i = 0; i < 10; ++i ) + { + counter++; + usleep( 16 * 1000 ); + } + }; + + auto future = gThreadPool.SubmitTask( 0, task ); + future->Wait(); + DALI_TEST_EQUALS( counter, 10, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliThreadPoolSubmitTasksCopyArray(void) +{ + // initialise global thread pool + if( !gThreadPool.GetWorkerCount() ) + { + gThreadPool.Initialize( 0u ); + } + + std::array dataSrc; + for( auto i = 0; i < decltype(i)(dataSrc.size()); ++i) + { + dataSrc[i] = (std::rand() % 0xff); + } + + std::array dataDst; + + // each task copies 1kb od data + std::vector tasks; + for( int i = 0; i < 1024; ++i ) + { + auto task = [&dataSrc, &dataDst, i ]( int workerIndex ) + { + for( int k = 0; k < 1024; ++k ) + { + dataDst[i*1024+k] = dataSrc[i*1024+k]; + } + }; + tasks.push_back( task ); + } + + DALI_TEST_EQUALS( 1024, tasks.size(), TEST_LOCATION ); + + gThreadPool.SubmitTasks( tasks ); + + // wait for pool to finish + gThreadPool.Wait(); + + // compare arrays + for( auto i = 0; i < decltype(i)(dataSrc.size()); ++i ) + { + DALI_TEST_EQUALS( dataSrc[i], dataDst[i], TEST_LOCATION ); + if( dataSrc[i] != dataDst[i] ) + { + break; + } + } + + END_TEST; +} \ No newline at end of file diff --git a/dali/devel-api/CMakeLists.txt b/dali/devel-api/CMakeLists.txt index 0aca8ad..c9c559e 100644 --- a/dali/devel-api/CMakeLists.txt +++ b/dali/devel-api/CMakeLists.txt @@ -8,6 +8,7 @@ SET( SOURCES ${SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/common/hash.cpp ${CMAKE_CURRENT_SOURCE_DIR}/common/stage-devel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/events/hit-test-algorithm.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/events/key-event-devel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-data-devel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/images/distance-field.cpp ${CMAKE_CURRENT_SOURCE_DIR}/images/texture-set-image.cpp @@ -44,6 +45,7 @@ SET( DEVEL_API_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/common/stage-devel.h ${CMAKE_CURRENT_SOURCE_DIR}/events/hit-test-algorithm.h + ${CMAKE_CURRENT_SOURCE_DIR}/events/key-event-devel.h ${CMAKE_CURRENT_SOURCE_DIR}/events/touch-data-devel.h ${CMAKE_CURRENT_SOURCE_DIR}/images/distance-field.h diff --git a/dali/devel-api/events/key-event-devel.cpp b/dali/devel-api/events/key-event-devel.cpp new file mode 100644 index 0000000..502404e --- /dev/null +++ b/dali/devel-api/events/key-event-devel.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 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 +#include + +namespace Dali +{ + +namespace DevelKeyEvent +{ + +std::string GetLogicalKey( KeyEvent keyEvent ) +{ + return GetImplementation( &keyEvent )->GetLogicalKey(); +} + +} // namespace DevelKeyEvent + +} // namespace Dali + diff --git a/dali/devel-api/events/key-event-devel.h b/dali/devel-api/events/key-event-devel.h new file mode 100644 index 0000000..bdf1680 --- /dev/null +++ b/dali/devel-api/events/key-event-devel.h @@ -0,0 +1,45 @@ +#ifndef DALI_KEY_EVENT_DEVEL_H +#define DALI_KEY_EVENT_DEVEL_H + +/* + * Copyright (c) 2019 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 +{ + +namespace DevelKeyEvent +{ + +/** + * @brief Gets the logical key string. + * + * For example, when the user presses 'shift' key and '1' key together, the logical key is "exclamation". + * Plus, the keyPressedName is "1", and the keyPressed is "!". + * + * @param[in] keyEvent The instance of KeyEvent. + * @return The logical key symbol + */ +DALI_CORE_API std::string GetLogicalKey( KeyEvent keyEvent ); + +} // namespace DevelKeyEvent + +} // namespace Dali + +#endif // DALI_KEY_EVENT_DEVEL_H diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index bd74e49..42b3256 100755 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -9,6 +9,7 @@ devel_api_src_files = \ $(devel_api_src_dir)/common/stage-devel.cpp \ $(devel_api_src_dir)/events/hit-test-algorithm.cpp \ $(devel_api_src_dir)/events/touch-data-devel.cpp \ + $(devel_api_src_dir)/events/key-event-devel.cpp \ $(devel_api_src_dir)/images/distance-field.cpp \ $(devel_api_src_dir)/images/texture-set-image.cpp \ $(devel_api_src_dir)/images/nine-patch-image.cpp \ @@ -20,6 +21,7 @@ devel_api_src_files = \ $(devel_api_src_dir)/threading/conditional-wait.cpp \ $(devel_api_src_dir)/threading/mutex.cpp \ $(devel_api_src_dir)/threading/thread.cpp \ + $(devel_api_src_dir)/threading/thread-pool.cpp \ $(devel_api_src_dir)/update/frame-callback-interface.cpp \ $(devel_api_src_dir)/update/update-proxy.cpp @@ -47,7 +49,8 @@ devel_api_core_common_header_files = \ devel_api_core_events_header_files = \ $(devel_api_src_dir)/events/hit-test-algorithm.h \ - $(devel_api_src_dir)/events/touch-data-devel.h + $(devel_api_src_dir)/events/touch-data-devel.h \ + $(devel_api_src_dir)/events/key-event-devel.h devel_api_core_images_header_files = \ $(devel_api_src_dir)/images/distance-field.h \ @@ -75,7 +78,8 @@ devel_api_core_scripting_header_files = \ devel_api_core_threading_header_files = \ $(devel_api_src_dir)/threading/conditional-wait.h \ $(devel_api_src_dir)/threading/mutex.h \ - $(devel_api_src_dir)/threading/thread.h + $(devel_api_src_dir)/threading/thread.h \ + $(devel_api_src_dir)/threading/thread-pool.h devel_api_core_update_header_files = \ $(devel_api_src_dir)/update/frame-callback-interface.h \ diff --git a/dali/devel-api/threading/thread-pool.cpp b/dali/devel-api/threading/thread-pool.cpp new file mode 100644 index 0000000..bf55715 --- /dev/null +++ b/dali/devel-api/threading/thread-pool.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "thread-pool.h" +#include + + + +namespace Dali +{ +namespace +{ +template +std::unique_ptr make_unique(Args&&... args) +{ + return std::unique_ptr(new T(std::forward(args)...)); +} +} + +/** + * WorkerThread executes tasks submitted to the pool + */ +class WorkerThread +{ +public: + + /** + * @brief Constructor of worker thread + * @param index Thread index assigned to the object during pool initialisation + */ + explicit WorkerThread( uint32_t index ); + + /** + * @brief Destructor of the worker thread + */ + ~WorkerThread(); + + WorkerThread(const WorkerThread &other) = delete; + WorkerThread &operator=(const WorkerThread &other) = delete; + + /** + * @brief Adds task to the task queue + * @param task Task to be executed by the thread + */ + void AddTask( Task task ); + + /** + * @brief Wakes up thread. + */ + void Notify(); + + /** + * @brief Waits for the thread to complete all the tasks currently in the queue. + */ + void Wait(); + +private: + + /** + * @brief Internal thread loop function + */ + void WaitAndExecute(); + + std::thread mWorker; + uint32_t mIndex; + TaskQueue mTaskQueue; + std::mutex mTaskQueueMutex; + std::condition_variable mConditionVariable; + + bool mTerminating {false} ; +}; + +void WorkerThread::WaitAndExecute() +{ + while( true ) + { + Task task; + + { + std::unique_lock< std::mutex > lock{ mTaskQueueMutex }; + + mConditionVariable.wait( lock, [ this ]() -> bool { + return !mTaskQueue.empty() || mTerminating; + } ); + + if( mTerminating ) + { + break; + } + + task = mTaskQueue.front(); + } + + task( mIndex ); + + { + std::lock_guard< std::mutex > lock{ mTaskQueueMutex }; + + mTaskQueue.pop(); + + mConditionVariable.notify_one(); + } + } +} + +WorkerThread::WorkerThread(uint32_t index) : mIndex( index ) +{ + // Have to pass "this" as an argument because WaitAndExecute is a member function. + mWorker = std::thread{ &WorkerThread::WaitAndExecute, this }; +} + +WorkerThread::~WorkerThread() +{ + if( mWorker.joinable() ) + { + Notify(); + Wait(); + + { + std::lock_guard< std::mutex > lock{ mTaskQueueMutex }; + mTerminating = true; + mConditionVariable.notify_one(); + } + + mWorker.join(); + } +} + +void WorkerThread::AddTask( Task task ) +{ + std::lock_guard< std::mutex > lock{ mTaskQueueMutex }; + mTaskQueue.push( std::move( task ) ); + mConditionVariable.notify_one(); +} + +void WorkerThread::Notify() +{ + std::lock_guard< std::mutex > lock{ mTaskQueueMutex }; + mConditionVariable.notify_one(); +} + +void WorkerThread::Wait() +{ + std::unique_lock< std::mutex > lock{ mTaskQueueMutex }; + mConditionVariable.wait( lock, [ this ]() -> bool { + return mTaskQueue.empty(); + } ); +} + +// ThreadPool ----------------------------------------------------------------------------------------------- + +struct ThreadPool::Impl +{ + std::vector> mWorkers; + uint32_t mWorkerIndex{ 0u }; +}; + +ThreadPool::ThreadPool() +{ + mImpl = make_unique(); +} + +ThreadPool::~ThreadPool() = default; + +bool ThreadPool::Initialize( uint32_t threadCount ) +{ + /** + * Get the system's supported thread count. + */ + auto thread_count = threadCount + 1; + if( !threadCount ) + { + thread_count = std::thread::hardware_concurrency(); + if( !thread_count ) + { + return false; + } + } + + /** + * Spawn the worker threads. + */ + for( auto i = 0u; i < thread_count - 1; i++ ) + { + /** + * The workers will execute an infinite loop function + * and will wait for a job to enter the job queue. Once a job is in the the queue + * the threads will wake up to acquire and execute it. + */ + mImpl->mWorkers.push_back( make_unique< WorkerThread >( i ) ); + } + + return true; +} + + +void ThreadPool::Wait() +{ + for( auto& worker : mImpl->mWorkers ) + { + worker->Wait(); + } +} + +SharedFuture ThreadPool::SubmitTask( uint32_t workerIndex, const Task& task ) +{ + auto future = std::shared_ptr< Future< void > >( new Future< void > ); + mImpl->mWorkers[workerIndex]->AddTask( [task, future]( uint32_t index ) + { + task( index ); + + future->mPromise.set_value(); + }); + + return future; +} + +SharedFuture ThreadPool::SubmitTasks( const std::vector< Task >& tasks ) +{ + auto future = std::shared_ptr< Future< void > >( new Future< void > ); + + mImpl->mWorkers[ mImpl->mWorkerIndex++ % static_cast< uint32_t >( mImpl->mWorkers.size() )]->AddTask( + [ future, tasks ]( uint32_t index ) { + for( auto& task : tasks ) + { + task( index ); + } + + future->mPromise.set_value(); + + } ); + + return future; +} + +UniqueFutureGroup ThreadPool::SubmitTasks( const std::vector< Task >& tasks, uint32_t threadMask ) +{ + auto retval = make_unique>(); + + /** + * Use square root of number of sumbitted tasks to estimate optimal number of threads + * used to execute jobs + */ + auto threads = uint32_t(std::log2(float(tasks.size()))); + + if( threadMask != 0 ) + { + threads = threadMask; + } + + if( threads > mImpl->mWorkers.size() ) + { + threads = uint32_t(mImpl->mWorkers.size()); + } + else if( !threads ) + { + threads = 1; + } + + auto payloadPerThread = uint32_t(tasks.size() / threads); + auto remaining = uint32_t(tasks.size() % threads); + + uint32_t taskIndex = 0; + uint32_t taskSize = uint32_t(remaining + payloadPerThread); // add 'remaining' tasks to the very first job list + + for( auto wt = 0u; wt < threads; ++wt ) + { + auto future = std::shared_ptr< Future< void > >( new Future< void > ); + retval->mFutures.emplace_back( future ); + mImpl->mWorkers[ mImpl->mWorkerIndex++ % static_cast< uint32_t >( mImpl->mWorkers.size() )]->AddTask( + [ future, tasks, taskIndex, taskSize ]( uint32_t index ) { + auto begin = tasks.begin() + int(taskIndex); + auto end = begin + int(taskSize); + for( auto it = begin; it < end; ++it ) + { + (*it)( index ); + } + future->mPromise.set_value(); + } ); + + taskIndex += taskSize; + taskSize = payloadPerThread; + } + + return retval; +} + +size_t ThreadPool::GetWorkerCount() const +{ + return mImpl->mWorkers.size(); +} + +} //namespace Dali diff --git a/dali/devel-api/threading/thread-pool.h b/dali/devel-api/threading/thread-pool.h new file mode 100644 index 0000000..b90fb28 --- /dev/null +++ b/dali/devel-api/threading/thread-pool.h @@ -0,0 +1,213 @@ +#ifndef DALI_THREAD_POOL_H +#define DALI_THREAD_POOL_H + +/* + * Copyright (c) 2019 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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Dali +{ +using Task = std::function; + +using TaskQueue = std::queue; + +/** + * Future contains the result of submitted task. When queried + * it applies internal synchronization mechanism to make sure + * the value is available. + */ +template +class DALI_INTERNAL Future final +{ + friend class ThreadPool; + +public: + + /** + * @brief Constructor of Future + */ + Future() + { + mFuture = mPromise.get_future(); + } + + /** + * @brief Destructor of Future + */ + ~Future() + { + Wait(); + } + + /** + * @brief Returns value of future, blocks if needed. + * @return Value stored by the future + */ + T Get() const + { + return mFuture.get(); + } + + /** + * @brief Waits until the value of future is ready. This function + * is a fencing mechanism. + */ + void Wait() const + { + if( IsValid() ) + { + mFuture.wait(); + } + } + + /** + * @brief Tests whether the future is valid + * @return True if valid, False otherwise + */ + bool IsValid() const + { + return mFuture.valid(); + } + + /** + * @brief Resets the future bringing it to the initial state. + * It's required in order to reuse the same Future object. + */ + void Reset() + { + mPromise = std::promise(); + mFuture = mPromise.get_future(); + } + +private: + + std::promise mPromise{}; + std::future mFuture{}; +}; + +using SharedFuture = std::shared_ptr>; + +/** + * FutureGroup binds many Future objects and applies synchronization. + */ +template +class FutureGroup final +{ + friend class ThreadPool; + +public: + + /** + * Waits for all the Futures to complete. + */ + void Wait() + { + for (auto &future : mFutures) + { + future->Wait(); + } + } + +private: + + std::vector > > mFutures; +}; + +using UniqueFutureGroup = std::unique_ptr>; + + + +/** + * ThreadPool creates and manages worker threads and tasks submitted for execution. + */ +class DALI_CORE_API ThreadPool final +{ +public: + + /** + * @brief Constructor of thread pool. + */ + ThreadPool(); + + /** + * @brief Destructor of thread pool. + */ + ~ThreadPool(); + + /** + * @brief Intializes thread pool + * @param threadCount Number of worker threads to use. If 0 then thread count equals hardware thread count. + * @return True if success + */ + bool Initialize( uint32_t threadCount = 0u ); + + /** + * @brief Waits until all threads finish execution and go back to the idle state. + */ + void Wait(); + + /** + * @brief Submits a single task to specified ( by the index ) worker thread. + * @param workerIndex Index of thread to be used + * @param task Task submitted for execution + * @return Shared pointer to the Future object + */ + SharedFuture SubmitTask(uint32_t workerIndex, const Task &task); + + /** + * @brief Submits vector of tasks to the pool + * @param tasks Vector containing tasks to be executed + * @return Shared pointer to the Future object + */ + SharedFuture SubmitTasks(const std::vector& tasks); + + /** + * @brief Submits tasks to threads specified by thread mask. + * @param tasks Vector of tasks + * @param threadMask Mask of threads to be used or 0 to use all available threads + * @return Unique pointer to the FutureGroup object + */ + UniqueFutureGroup SubmitTasks(const std::vector& tasks, uint32_t threadMask); + + /** + * @brief Returns number of worker threads + * @return Number of worker threads + */ + size_t GetWorkerCount() const; + +private: + + struct Impl; + std::unique_ptr mImpl; +}; + +} //namespace Dali + +#endif // DALI_THREAD_POOL_H diff --git a/dali/public-api/dali-core-version.cpp b/dali/public-api/dali-core-version.cpp index 2ff48a3..2a2f439 100644 --- a/dali/public-api/dali-core-version.cpp +++ b/dali/public-api/dali-core-version.cpp @@ -28,7 +28,7 @@ namespace Dali const uint32_t CORE_MAJOR_VERSION = 1; const uint32_t CORE_MINOR_VERSION = 4; -const uint32_t CORE_MICRO_VERSION = 26; +const uint32_t CORE_MICRO_VERSION = 27; const char * const CORE_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali.spec b/packaging/dali.spec index 95b55ae..3ae63b9 100644 --- a/packaging/dali.spec +++ b/packaging/dali.spec @@ -1,6 +1,6 @@ Name: dali Summary: DALi 3D Engine -Version: 1.4.26 +Version: 1.4.27 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT