Making DALi core internals typesafe using guaranteed types; uint8_t, uint32_t
[platform/core/uifw/dali-core.git] / dali / integration-api / lockless-buffer.h
1 #ifndef __DALI_INTEGRATION_LOCKLESS_BUFFER_H__
2 #define __DALI_INTEGRATION_LOCKLESS_BUFFER_H__
3
4 /*
5  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdint> // uint32_t, uint8_t
23
24 // INTERNAL INCLUDES
25 #include <cstring>
26 #include <dali/public-api/common/vector-wrapper.h>
27 #include <dali/public-api/common/dali-common.h>
28
29 namespace Dali
30 {
31
32 namespace Integration
33 {
34
35 /**
36  * The LocklessBuffer class implements double buffering eligible for multi-(two) threaded use,
37  * where it's possible to read from one thread and write from another
38  * without requiring a mutex lock to avoid performance hit.
39  * It's intended to be used for reading bitmap data in render thread
40  * while still possible to write data in another thread.
41  *
42  * Ideally Write() and Read() calls should be alternating, otherwise written data might be thrown away.
43  *
44  * The buffers are swapped in the reading thread, just before reading begins.
45  * In case the other thread is writing at that moment, buffers are not swapped and previously available data is read.
46  * Similarly if Write() is called before a Read() has finished the previous write buffer is overwritten.
47  */
48 class DALI_CORE_API LocklessBuffer
49 {
50
51 public:
52   /**
53    * Constructor.
54    * @param[in] size The size of buffers in bytes.
55    */
56   LocklessBuffer( uint32_t size );
57
58   /**
59    * Destructor.
60    */
61   ~LocklessBuffer();
62
63   /**
64    * Write data to buffer.
65    * @param[in] src data source
66    * @param[in] size size of data in bytes
67    */
68   void Write( const uint8_t *src, uint32_t size );
69
70   /**
71    * Try to swap buffers and read data.
72    * @note returned value only valid until Read() is called again or object is destroyed
73    * @return current read buffer contents
74    */
75   const uint8_t* Read();
76
77   /**
78    * @return the buffer size in bytes
79    */
80   uint32_t GetSize() const;
81
82 private:
83   /**
84    * Atomically set state.
85    * We're always writing to one buffer and reading from the other.
86    * Write() sets WRITING bit when started and unsets it when finished.
87    */
88   enum BufferState
89   {
90     R0W1    = 0, ///< Read from buffer 0 write to buffer 1
91     R1W0    = 1, ///< Read from buffer 1 write to buffer 0
92     WRITING = 2, ///< Currently writing to buffer
93     UPDATED = 4, ///< Swapping buffer required; there is new data available
94     WRITE_BUFFER_MASK = 1, ///< indicates which buffer to write to
95     WRITING_MASK      = 2, ///< indicates whether currently writing
96     UPDATED_MASK      = 4  ///< indicates whether new data is available
97   };
98
99 private:
100   LocklessBuffer(); ///< undefined default constructor, need to give size on construction
101   LocklessBuffer( const LocklessBuffer& );            ///< undefined copy constructor
102   LocklessBuffer& operator=( const LocklessBuffer& ); ///< undefined assignment operator
103
104 private:
105   uint8_t* mBuffer[2];         ///< bitmap buffers
106   BufferState volatile mState; ///< readbuffer number and whether we're currently writing into writebuffer or not
107   uint32_t mSize;              ///< size of buffers
108 };
109
110 } // Internal
111
112 } // Dali
113
114 #endif // __DALI_INTEGRATION_LOCKLESS_H__