2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 #include <dali/internal/common/message-buffer.h>
25 #include <dali/integration-api/debug.h>
27 namespace // unnamed namespace
30 // Increase capacity by 1.5 when buffer limit reached
31 const unsigned int INCREMENT_NUMERATOR = 3u;
32 const unsigned int INCREMENT_DENOMINATOR = 2u;
34 const unsigned int MESSAGE_SIZE_FIELD = 1u; // Size required to mark the message size
35 const unsigned int MESSAGE_END_FIELD = 1u; // Size required to mark the end of messages
37 const unsigned int MESSAGE_SIZE_PLUS_END_FIELD = MESSAGE_SIZE_FIELD + MESSAGE_END_FIELD;
39 const unsigned int MAX_DIVISION_BY_WORD_REMAINDER = sizeof(unsigned int) - 1u; // For word alignment on ARM
41 } // unnamed namespace
49 MessageBuffer::MessageBuffer( std::size_t initialCapacity )
50 : mInitialCapacity( initialCapacity / sizeof(unsigned int) ),
58 MessageBuffer::~MessageBuffer()
63 unsigned int* MessageBuffer::ReserveMessageSlot( std::size_t size )
65 DALI_ASSERT_DEBUG( 0 != size );
67 std::size_t requestedSize = (size + MAX_DIVISION_BY_WORD_REMAINDER) / sizeof(unsigned int);
68 std::size_t requiredSize = requestedSize + MESSAGE_SIZE_PLUS_END_FIELD;
70 // Keep doubling the additional capacity until we have enough
71 std::size_t nextCapacity = mCapacity ? mCapacity : mInitialCapacity;
73 if ( (nextCapacity - mSize) < requiredSize )
75 nextCapacity = nextCapacity * INCREMENT_NUMERATOR / INCREMENT_DENOMINATOR;
77 // Something has gone badly wrong if requiredSize is this big
78 DALI_ASSERT_DEBUG( (nextCapacity - mSize) > requiredSize );
81 if ( nextCapacity > mCapacity )
83 IncreaseCapacity( nextCapacity );
86 // Now reserve the slot
87 unsigned int* slot = mNextSlot;
89 *slot++ = requestedSize; // Object size marker is stored in first word
91 mSize += requestedSize + MESSAGE_SIZE_FIELD;
92 mNextSlot = mData + mSize;
100 std::size_t MessageBuffer::GetCapacity() const
102 return mCapacity * sizeof(unsigned int);
105 MessageBuffer::Iterator MessageBuffer::Begin() const
109 return Iterator( mData );
112 return Iterator( NULL );
115 void MessageBuffer::Reset()
117 // All messages have been processed, reset the buffer
122 void MessageBuffer::IncreaseCapacity( std::size_t newCapacity )
124 DALI_ASSERT_DEBUG( newCapacity > mCapacity );
128 // Often this avoids the need to copy memory
129 mData = reinterpret_cast<unsigned int*>( realloc( mData, newCapacity * sizeof(unsigned int) ) );
133 mData = reinterpret_cast<unsigned int*>( malloc( newCapacity * sizeof(unsigned int) ) );
135 DALI_ASSERT_ALWAYS( NULL != mData );
137 mCapacity = newCapacity;
138 mNextSlot = mData + mSize;
141 MessageBuffer::Iterator::Iterator(unsigned int* current)
145 if( NULL != mCurrent )
147 // The first word is the size of the following object
148 mMessageSize = *mCurrent++;
152 MessageBuffer::Iterator::Iterator(const Iterator& copy)
153 : mCurrent( copy.mCurrent ),
154 mMessageSize( copy.mMessageSize )
158 } // namespace Internal