Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-core.git] / dali / internal / common / message-buffer.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://floralicense.org/license/
9 //
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.
15 //
16
17 // CLASS HEADER
18 #include <dali/internal/common/message-buffer.h>
19
20 // EXTERNAL INCLUDES
21 #include <limits>
22 #include <cstdlib>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26
27 namespace // unnamed namespace
28 {
29
30 // Increase capacity by 1.5 when buffer limit reached
31 const unsigned int INCREMENT_NUMERATOR   = 3u;
32 const unsigned int INCREMENT_DENOMINATOR = 2u;
33
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
36
37 const unsigned int MESSAGE_SIZE_PLUS_END_FIELD = MESSAGE_SIZE_FIELD + MESSAGE_END_FIELD;
38
39 const unsigned int MAX_DIVISION_BY_WORD_REMAINDER = sizeof(unsigned int) - 1u; // For word alignment on ARM
40
41 } // unnamed namespace
42
43 namespace Dali
44 {
45
46 namespace Internal
47 {
48
49 MessageBuffer::MessageBuffer( std::size_t initialCapacity )
50 : mInitialCapacity( initialCapacity / sizeof(unsigned int) ),
51   mData( NULL ),
52   mNextSlot( NULL ),
53   mCapacity( 0 ),
54   mSize( 0 )
55 {
56 }
57
58 MessageBuffer::~MessageBuffer()
59 {
60   free( mData );
61 }
62
63 unsigned int* MessageBuffer::ReserveMessageSlot( std::size_t size )
64 {
65   DALI_ASSERT_DEBUG( 0 != size );
66
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;
69
70   // Keep doubling the additional capacity until we have enough
71   std::size_t nextCapacity = mCapacity ? mCapacity : mInitialCapacity;
72
73   if ( (nextCapacity - mSize) < requiredSize )
74   {
75     nextCapacity = nextCapacity * INCREMENT_NUMERATOR / INCREMENT_DENOMINATOR;
76
77     // Something has gone badly wrong if requiredSize is this big
78     DALI_ASSERT_DEBUG( (nextCapacity - mSize) > requiredSize );
79   }
80
81   if ( nextCapacity > mCapacity )
82   {
83     IncreaseCapacity( nextCapacity );
84   }
85
86   // Now reserve the slot
87   unsigned int* slot = mNextSlot;
88
89   *slot++ = requestedSize; // Object size marker is stored in first word
90
91   mSize += requestedSize + MESSAGE_SIZE_FIELD;
92   mNextSlot = mData + mSize;
93
94   // End marker
95   *mNextSlot = 0;
96
97   return slot;
98 }
99
100 std::size_t MessageBuffer::GetCapacity() const
101 {
102   return mCapacity * sizeof(unsigned int);
103 }
104
105 MessageBuffer::Iterator MessageBuffer::Begin() const
106 {
107   if ( 0 != mSize )
108   {
109     return Iterator( mData );
110   }
111
112   return Iterator( NULL );
113 }
114
115 void MessageBuffer::Reset()
116 {
117   // All messages have been processed, reset the buffer
118   mSize = 0;
119   mNextSlot = mData;
120 }
121
122 void MessageBuffer::IncreaseCapacity( std::size_t newCapacity )
123 {
124   DALI_ASSERT_DEBUG( newCapacity > mCapacity );
125
126   if ( mData )
127   {
128     // Often this avoids the need to copy memory
129     mData = reinterpret_cast<unsigned int*>( realloc( mData, newCapacity * sizeof(unsigned int) ) );
130   }
131   else
132   {
133     mData = reinterpret_cast<unsigned int*>( malloc( newCapacity * sizeof(unsigned int) ) );
134   }
135   DALI_ASSERT_ALWAYS( NULL != mData );
136
137   mCapacity = newCapacity;
138   mNextSlot = mData + mSize;
139 }
140
141 MessageBuffer::Iterator::Iterator(unsigned int* current)
142 : mCurrent(current),
143   mMessageSize(0)
144 {
145   if( NULL != mCurrent )
146   {
147     // The first word is the size of the following object
148     mMessageSize = *mCurrent++;
149   }
150 }
151
152 MessageBuffer::Iterator::Iterator(const Iterator& copy)
153 : mCurrent( copy.mCurrent ),
154   mMessageSize( copy.mMessageSize )
155 {
156 }
157
158 } // namespace Internal
159
160 } // namespace Dali