X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fqueue%2Fupdate-message-queue.cpp;h=8b80412832bb5692c3e37f844f9900f04fab6355;hb=5de727a5d6b9ef995c93eff4d4e47a086784a332;hp=330234de1c26187e00e0b20f857d84119acf1d5e;hpb=5d435004a1f8ef8dece4ee6c151a5b91c1f3adb4;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/queue/update-message-queue.cpp b/dali/internal/update/queue/update-message-queue.cpp index 330234d..8b80412 100644 --- a/dali/internal/update/queue/update-message-queue.cpp +++ b/dali/internal/update/queue/update-message-queue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -19,12 +19,12 @@ #include // INTERNAL INCLUDES -#include #include #include -#include #include +#include #include +#include using std::vector; @@ -33,113 +33,109 @@ using Dali::Internal::SceneGraph::SceneGraphBuffers; namespace Dali { - namespace Internal { - namespace // unnamed namespace { - // A message to set Actor::SIZE is 72 bytes on 32bit device // A buffer of size 32768 would store (32768 - 4) / (72 + 4) = 431 of those messages -static const std::size_t INITIAL_BUFFER_SIZE = 32768; -static const std::size_t MAX_BUFFER_CAPACITY = 73728; // Avoid keeping buffers which exceed this -static const std::size_t MAX_FREE_BUFFER_COUNT = 3; // Allow this number of buffers to be recycled +static const std::size_t INITIAL_BUFFER_SIZE = 32768; +static const std::size_t MAX_BUFFER_CAPACITY = 73728; // Avoid keeping buffers which exceed this +static const std::size_t MAX_FREE_BUFFER_COUNT = 3; // Allow this number of buffers to be recycled // A queue of message buffers -typedef vector< MessageBuffer* > MessageBufferQueue; -typedef MessageBufferQueue::iterator MessageBufferIter; +typedef vector MessageBufferQueue; +using MessageBufferIter = MessageBufferQueue::iterator; -typedef Dali::Mutex MessageQueueMutex; +using MessageQueueMutex = Dali::Mutex; } // unnamed namespace namespace Update { - /** * Private MessageQueue data */ struct MessageQueue::Impl { - Impl( RenderController& controller, const SceneGraphBuffers& buffers ) + Impl(RenderController& controller, const SceneGraphBuffers& buffers) : renderController(controller), sceneGraphBuffers(buffers), processingEvents(false), queueWasEmpty(true), - sceneUpdateFlag( false ), - sceneUpdate( 0 ), - currentMessageBuffer(NULL) + sceneUpdateFlag(false), + sceneUpdate(0), + currentMessageBuffer(nullptr) { } ~Impl() { // Delete the current buffer - if( currentMessageBuffer ) + if(currentMessageBuffer) { - DeleteBufferContents( currentMessageBuffer ); + DeleteBufferContents(currentMessageBuffer); delete currentMessageBuffer; } // Delete the unprocessed buffers const MessageBufferIter processQueueEndIter = processQueue.end(); - for ( MessageBufferIter iter = processQueue.begin(); iter != processQueueEndIter; ++iter ) + for(MessageBufferIter iter = processQueue.begin(); iter != processQueueEndIter; ++iter) { MessageBuffer* unprocessedBuffer = *iter; - DeleteBufferContents( unprocessedBuffer ); + DeleteBufferContents(unprocessedBuffer); delete unprocessedBuffer; } // Delete the recycled buffers const MessageBufferIter recycleQueueEndIter = recycleQueue.end(); - for ( MessageBufferIter iter = recycleQueue.begin(); iter != recycleQueueEndIter; ++iter ) + for(MessageBufferIter iter = recycleQueue.begin(); iter != recycleQueueEndIter; ++iter) { MessageBuffer* recycledBuffer = *iter; - DeleteBufferContents( recycledBuffer ); + DeleteBufferContents(recycledBuffer); delete recycledBuffer; } const MessageBufferIter freeQueueEndIter = freeQueue.end(); - for ( MessageBufferIter iter = freeQueue.begin(); iter != freeQueueEndIter; ++iter ) + for(MessageBufferIter iter = freeQueue.begin(); iter != freeQueueEndIter; ++iter) { MessageBuffer* freeBuffer = *iter; - DeleteBufferContents( freeBuffer ); + DeleteBufferContents(freeBuffer); delete freeBuffer; } } - void DeleteBufferContents( MessageBuffer* buffer ) + void DeleteBufferContents(MessageBuffer* buffer) { - for( MessageBuffer::Iterator iter = buffer->Begin(); iter.IsValid(); iter.Next() ) + for(MessageBuffer::Iterator iter = buffer->Begin(); iter.IsValid(); iter.Next()) { - MessageBase* message = reinterpret_cast< MessageBase* >( iter.Get() ); + MessageBase* message = reinterpret_cast(iter.Get()); // Call virtual destructor explictly; since delete will not be called after placement new message->~MessageBase(); } } - RenderController& renderController; ///< render controller - const SceneGraphBuffers& sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read. + RenderController& renderController; ///< render controller + const SceneGraphBuffers& sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read. - bool processingEvents; ///< Whether messages queued will be flushed by core - bool queueWasEmpty; ///< Flag whether the queue was empty during the Update() - bool sceneUpdateFlag; ///< true when there is a new message that requires a scene-graph node tree update - int sceneUpdate; ///< Non zero when there is a message in the queue requiring a scene-graph node tree update + bool processingEvents; ///< Whether messages queued will be flushed by core + bool queueWasEmpty; ///< Flag whether the queue was empty during the Update() + bool sceneUpdateFlag; ///< true when there is a new message that requires a scene-graph node tree update + int sceneUpdate; ///< Non zero when there is a message in the queue requiring a scene-graph node tree update - MessageQueueMutex queueMutex; ///< queueMutex must be locked whilst accessing processQueue or recycleQueue - MessageBufferQueue processQueue; ///< to process in the next update - MessageBufferQueue recycleQueue; ///< to recycle MessageBuffers after the messages have been processed + MessageQueueMutex queueMutex; ///< queueMutex must be locked whilst accessing processQueue or recycleQueue + MessageBufferQueue processQueue; ///< to process in the next update + MessageBufferQueue recycleQueue; ///< to recycle MessageBuffers after the messages have been processed - MessageBuffer* currentMessageBuffer; ///< can be used without locking - MessageBufferQueue freeQueue; ///< buffers from the recycleQueue; can be used without locking + MessageBuffer* currentMessageBuffer; ///< can be used without locking + MessageBufferQueue freeQueue; ///< buffers from the recycleQueue; can be used without locking }; -MessageQueue::MessageQueue( Integration::RenderController& controller, const SceneGraph::SceneGraphBuffers& buffers ) -: mImpl(NULL) +MessageQueue::MessageQueue(Integration::RenderController& controller, const SceneGraph::SceneGraphBuffers& buffers) +: mImpl(nullptr) { - mImpl = new Impl( controller, buffers ); + mImpl = new Impl(controller, buffers); } MessageQueue::~MessageQueue() @@ -153,85 +149,85 @@ void MessageQueue::EventProcessingStarted() } // Called from event thread -unsigned int* MessageQueue::ReserveMessageSlot( unsigned int requestedSize, bool updateScene ) +uint32_t* MessageQueue::ReserveMessageSlot(uint32_t requestedSize, bool updateScene) { - DALI_ASSERT_DEBUG( 0 != requestedSize ); + DALI_ASSERT_DEBUG(0 != requestedSize); - if( updateScene ) + if(updateScene) { mImpl->sceneUpdateFlag = true; } - if ( !mImpl->currentMessageBuffer ) + if(!mImpl->currentMessageBuffer) { const MessageBufferIter endIter = mImpl->freeQueue.end(); // Find the largest recycled buffer from freeQueue MessageBufferIter nextBuffer = endIter; - for ( MessageBufferIter iter = mImpl->freeQueue.begin(); iter != endIter; ++iter ) + for(MessageBufferIter iter = mImpl->freeQueue.begin(); iter != endIter; ++iter) { - if ( endIter == nextBuffer || - (*nextBuffer)->GetCapacity() < (*iter)->GetCapacity() ) + if(endIter == nextBuffer || + (*nextBuffer)->GetCapacity() < (*iter)->GetCapacity()) { nextBuffer = iter; } } - if ( endIter != nextBuffer ) + if(endIter != nextBuffer) { // Reuse a recycled buffer from freeQueue mImpl->currentMessageBuffer = *nextBuffer; - mImpl->freeQueue.erase( nextBuffer ); + mImpl->freeQueue.erase(nextBuffer); } else { - mImpl->currentMessageBuffer = new MessageBuffer( INITIAL_BUFFER_SIZE ); + mImpl->currentMessageBuffer = new MessageBuffer(INITIAL_BUFFER_SIZE); } } // If we are inside Core::ProcessEvents(), core will automatically flush the queue. // If we are outside, then we have to request a call to Core::ProcessEvents() on idle. - if ( false == mImpl->processingEvents ) + if(false == mImpl->processingEvents) { - mImpl->renderController.RequestProcessEventsOnIdle( false ); + mImpl->renderController.RequestProcessEventsOnIdle(false); } - return mImpl->currentMessageBuffer->ReserveMessageSlot( requestedSize ); + return mImpl->currentMessageBuffer->ReserveMessageSlot(requestedSize); } // Called from event thread bool MessageQueue::FlushQueue() { - const bool messagesToProcess = ( NULL != mImpl->currentMessageBuffer ); + const bool messagesToProcess = (nullptr != mImpl->currentMessageBuffer); // If there're messages to flush - if ( messagesToProcess ) + if(messagesToProcess) { // queueMutex must be locked whilst accessing processQueue or recycleQueue - MessageQueueMutex::ScopedLock lock( mImpl->queueMutex ); + MessageQueueMutex::ScopedLock lock(mImpl->queueMutex); - mImpl->processQueue.push_back( mImpl->currentMessageBuffer ); - mImpl->currentMessageBuffer = NULL; + mImpl->processQueue.push_back(mImpl->currentMessageBuffer); + mImpl->currentMessageBuffer = nullptr; // Grab any recycled MessageBuffers - while ( !mImpl->recycleQueue.empty() ) + while(!mImpl->recycleQueue.empty()) { MessageBuffer* recycled = mImpl->recycleQueue.back(); mImpl->recycleQueue.pop_back(); // Guard against excessive message buffer growth - if ( MAX_FREE_BUFFER_COUNT < mImpl->freeQueue.size() || - MAX_BUFFER_CAPACITY < recycled->GetCapacity() ) + if(MAX_FREE_BUFFER_COUNT < mImpl->freeQueue.size() || + MAX_BUFFER_CAPACITY < recycled->GetCapacity()) { delete recycled; } else { - mImpl->freeQueue.push_back( recycled ); + mImpl->freeQueue.push_back(recycled); } } - if( mImpl->sceneUpdateFlag ) + if(mImpl->sceneUpdateFlag) { mImpl->sceneUpdate |= 2; mImpl->sceneUpdateFlag = false; @@ -243,23 +239,23 @@ bool MessageQueue::FlushQueue() return messagesToProcess; } -bool MessageQueue::ProcessMessages( BufferIndex updateBufferIndex ) +bool MessageQueue::ProcessMessages(BufferIndex updateBufferIndex) { PERF_MONITOR_START(PerformanceMonitor::PROCESS_MESSAGES); // queueMutex must be locked whilst accessing queue - MessageQueueMutex::ScopedLock lock( mImpl->queueMutex ); + MessageQueueMutex::ScopedLock lock(mImpl->queueMutex); const MessageBufferIter processQueueEndIter = mImpl->processQueue.end(); - for ( MessageBufferIter iter = mImpl->processQueue.begin(); iter != processQueueEndIter ; ++iter ) + for(MessageBufferIter iter = mImpl->processQueue.begin(); iter != processQueueEndIter; ++iter) { MessageBuffer* buffer = *iter; - for( MessageBuffer::Iterator iter = buffer->Begin(); iter.IsValid(); iter.Next() ) + for(MessageBuffer::Iterator iter = buffer->Begin(); iter.IsValid(); iter.Next()) { - MessageBase* message = reinterpret_cast< MessageBase* >( iter.Get() ); + MessageBase* message = reinterpret_cast(iter.Get()); - message->Process( updateBufferIndex ); + message->Process(updateBufferIndex); // Call virtual destructor explictly; since delete will not be called after placement new message->~MessageBase(); @@ -267,7 +263,7 @@ bool MessageQueue::ProcessMessages( BufferIndex updateBufferIndex ) buffer->Reset(); // Pass back for use in the event-thread - mImpl->recycleQueue.push_back( buffer ); + mImpl->recycleQueue.push_back(buffer); } mImpl->sceneUpdate >>= 1; @@ -278,7 +274,7 @@ bool MessageQueue::ProcessMessages( BufferIndex updateBufferIndex ) PERF_MONITOR_END(PerformanceMonitor::PROCESS_MESSAGES); - return ( mImpl->sceneUpdate & 0x01 ); // if it was previously 2, scene graph was updated. + return (mImpl->sceneUpdate & 0x01); // if it was previously 2, scene graph was updated. } bool MessageQueue::WasEmpty() const @@ -291,6 +287,28 @@ bool MessageQueue::IsSceneUpdateRequired() const return mImpl->sceneUpdate; } +std::size_t MessageQueue::GetCapacity() const +{ + MessageQueueMutex::ScopedLock lock(mImpl->queueMutex); + + uint32_t capacity = 0u; + MessageBufferIter endIter = mImpl->freeQueue.end(); + for(MessageBufferIter iter = mImpl->freeQueue.begin(); iter != endIter; ++iter) + { + capacity += (*iter)->GetCapacity(); + } + endIter = mImpl->processQueue.end(); + for(MessageBufferIter iter = mImpl->processQueue.begin(); iter != endIter; ++iter) + { + capacity += (*iter)->GetCapacity(); + } + if(mImpl->currentMessageBuffer != nullptr) + { + capacity += mImpl->currentMessageBuffer->GetCapacity(); + } + return capacity; +} + } // namespace Update } // namespace Internal