xref: /aosp_15_r20/external/deqp/framework/delibs/decpp/deRingBuffer.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker #ifndef _DERINGBUFFER_HPP
2*35238bceSAndroid Build Coastguard Worker #define _DERINGBUFFER_HPP
3*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  * drawElements C++ Base Library
5*35238bceSAndroid Build Coastguard Worker  * -----------------------------
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
8*35238bceSAndroid Build Coastguard Worker  *
9*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
10*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
11*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
14*35238bceSAndroid Build Coastguard Worker  *
15*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
16*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
17*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
19*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
20*35238bceSAndroid Build Coastguard Worker  *
21*35238bceSAndroid Build Coastguard Worker  *//*!
22*35238bceSAndroid Build Coastguard Worker  * \file
23*35238bceSAndroid Build Coastguard Worker  * \brief Ring buffer template.
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deDefs.hpp"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker namespace de
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker void RingBuffer_selfTest(void);
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker /** Ring buffer template. */
34*35238bceSAndroid Build Coastguard Worker template <typename T>
35*35238bceSAndroid Build Coastguard Worker class RingBuffer
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker public:
38*35238bceSAndroid Build Coastguard Worker     RingBuffer(int size);
39*35238bceSAndroid Build Coastguard Worker     ~RingBuffer(void);
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker     void clear(void);
42*35238bceSAndroid Build Coastguard Worker     void resize(int newSize);
43*35238bceSAndroid Build Coastguard Worker 
getSize(void) const44*35238bceSAndroid Build Coastguard Worker     int getSize(void) const
45*35238bceSAndroid Build Coastguard Worker     {
46*35238bceSAndroid Build Coastguard Worker         return m_size;
47*35238bceSAndroid Build Coastguard Worker     }
getNumElements(void) const48*35238bceSAndroid Build Coastguard Worker     int getNumElements(void) const
49*35238bceSAndroid Build Coastguard Worker     {
50*35238bceSAndroid Build Coastguard Worker         return m_numElements;
51*35238bceSAndroid Build Coastguard Worker     }
getNumFree(void) const52*35238bceSAndroid Build Coastguard Worker     int getNumFree(void) const
53*35238bceSAndroid Build Coastguard Worker     {
54*35238bceSAndroid Build Coastguard Worker         return m_size - m_numElements;
55*35238bceSAndroid Build Coastguard Worker     }
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker     void pushFront(const T &elem);
58*35238bceSAndroid Build Coastguard Worker     void pushFront(const T *elemBuf, int count);
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker     void peekBack(T *elemBuf, int count) const;
61*35238bceSAndroid Build Coastguard Worker     T peekBack(int offset) const;
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker     T popBack(void);
popBack(T * elemBuf,int count)64*35238bceSAndroid Build Coastguard Worker     void popBack(T *elemBuf, int count)
65*35238bceSAndroid Build Coastguard Worker     {
66*35238bceSAndroid Build Coastguard Worker         peekBack(elemBuf, count);
67*35238bceSAndroid Build Coastguard Worker         popBack(count);
68*35238bceSAndroid Build Coastguard Worker     }
69*35238bceSAndroid Build Coastguard Worker     void popBack(int count);
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker protected:
72*35238bceSAndroid Build Coastguard Worker     int m_numElements;
73*35238bceSAndroid Build Coastguard Worker     int m_front;
74*35238bceSAndroid Build Coastguard Worker     int m_back;
75*35238bceSAndroid Build Coastguard Worker 
76*35238bceSAndroid Build Coastguard Worker     T *m_buffer;
77*35238bceSAndroid Build Coastguard Worker     int m_size;
78*35238bceSAndroid Build Coastguard Worker };
79*35238bceSAndroid Build Coastguard Worker 
80*35238bceSAndroid Build Coastguard Worker // RingBuffer implementation.
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker template <typename T>
RingBuffer(int size)83*35238bceSAndroid Build Coastguard Worker RingBuffer<T>::RingBuffer(int size) : m_numElements(0)
84*35238bceSAndroid Build Coastguard Worker                                     , m_front(0)
85*35238bceSAndroid Build Coastguard Worker                                     , m_back(0)
86*35238bceSAndroid Build Coastguard Worker                                     , m_size(size)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(size > 0);
89*35238bceSAndroid Build Coastguard Worker     m_buffer = new T[m_size];
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker template <typename T>
~RingBuffer()93*35238bceSAndroid Build Coastguard Worker RingBuffer<T>::~RingBuffer()
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker     delete[] m_buffer;
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker template <typename T>
clear(void)99*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::clear(void)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker     m_numElements = 0;
102*35238bceSAndroid Build Coastguard Worker     m_front       = 0;
103*35238bceSAndroid Build Coastguard Worker     m_back        = 0;
104*35238bceSAndroid Build Coastguard Worker }
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker template <typename T>
resize(int newSize)107*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::resize(int newSize)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(newSize >= m_numElements);
110*35238bceSAndroid Build Coastguard Worker     T *buf = new T[newSize];
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     try
113*35238bceSAndroid Build Coastguard Worker     {
114*35238bceSAndroid Build Coastguard Worker         // Copy old elements.
115*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < m_numElements; ndx++)
116*35238bceSAndroid Build Coastguard Worker             buf[ndx] = m_buffer[(m_back + ndx) % m_size];
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker         // Reset pointers.
119*35238bceSAndroid Build Coastguard Worker         m_front = m_numElements;
120*35238bceSAndroid Build Coastguard Worker         m_back  = 0;
121*35238bceSAndroid Build Coastguard Worker         m_size  = newSize;
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker         DE_SWAP(T *, buf, m_buffer);
124*35238bceSAndroid Build Coastguard Worker         delete[] buf;
125*35238bceSAndroid Build Coastguard Worker     }
126*35238bceSAndroid Build Coastguard Worker     catch (...)
127*35238bceSAndroid Build Coastguard Worker     {
128*35238bceSAndroid Build Coastguard Worker         delete[] buf;
129*35238bceSAndroid Build Coastguard Worker         throw;
130*35238bceSAndroid Build Coastguard Worker     }
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker template <typename T>
pushFront(const T & elem)134*35238bceSAndroid Build Coastguard Worker inline void RingBuffer<T>::pushFront(const T &elem)
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getNumFree() > 0);
137*35238bceSAndroid Build Coastguard Worker     m_buffer[m_front] = elem;
138*35238bceSAndroid Build Coastguard Worker     m_front           = (m_front + 1) % m_size;
139*35238bceSAndroid Build Coastguard Worker     m_numElements += 1;
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker template <typename T>
pushFront(const T * elemBuf,int count)143*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::pushFront(const T *elemBuf, int count)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(count, 0, getNumFree()));
146*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < count; i++)
147*35238bceSAndroid Build Coastguard Worker         m_buffer[(m_front + i) % m_size] = elemBuf[i];
148*35238bceSAndroid Build Coastguard Worker     m_front = (m_front + count) % m_size;
149*35238bceSAndroid Build Coastguard Worker     m_numElements += count;
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker template <typename T>
popBack()153*35238bceSAndroid Build Coastguard Worker inline T RingBuffer<T>::popBack()
154*35238bceSAndroid Build Coastguard Worker {
155*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getNumElements() > 0);
156*35238bceSAndroid Build Coastguard Worker     int ndx = m_back;
157*35238bceSAndroid Build Coastguard Worker     m_back  = (m_back + 1) % m_size;
158*35238bceSAndroid Build Coastguard Worker     m_numElements -= 1;
159*35238bceSAndroid Build Coastguard Worker     return m_buffer[ndx];
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker 
162*35238bceSAndroid Build Coastguard Worker template <typename T>
peekBack(int offset) const163*35238bceSAndroid Build Coastguard Worker inline T RingBuffer<T>::peekBack(int offset) const
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inBounds(offset, 0, getNumElements()));
166*35238bceSAndroid Build Coastguard Worker     return m_buffer[(m_back + offset) % m_size];
167*35238bceSAndroid Build Coastguard Worker }
168*35238bceSAndroid Build Coastguard Worker 
169*35238bceSAndroid Build Coastguard Worker template <typename T>
peekBack(T * elemBuf,int count) const170*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::peekBack(T *elemBuf, int count) const
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(count, 0, getNumElements()));
173*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < count; i++)
174*35238bceSAndroid Build Coastguard Worker         elemBuf[i] = m_buffer[(m_back + i) % m_size];
175*35238bceSAndroid Build Coastguard Worker }
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker template <typename T>
popBack(int count)178*35238bceSAndroid Build Coastguard Worker void RingBuffer<T>::popBack(int count)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(count, 0, getNumElements()));
181*35238bceSAndroid Build Coastguard Worker     m_back = (m_back + count) % m_size;
182*35238bceSAndroid Build Coastguard Worker     m_numElements -= count;
183*35238bceSAndroid Build Coastguard Worker }
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker } // namespace de
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker #endif // _DERINGBUFFER_HPP
188