1 /*-------------------------------------------------------------------------
2  * drawElements C++ Base Library
3  * -----------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
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  * \file
21  * \brief Array buffer
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deArrayBuffer.hpp"
25 
26 #if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
27 #	include <valgrind/memcheck.h>
28 #endif
29 
30 namespace de
31 {
32 namespace detail
33 {
34 
ArrayBuffer_AlignedMalloc(size_t numBytes,size_t alignment)35 void* ArrayBuffer_AlignedMalloc (size_t numBytes, size_t alignment)
36 {
37 	const int	sizeAsInt	= (int)numBytes;
38 	void*		ptr;
39 
40 	// int overflow
41 	if (sizeAsInt < 0 || numBytes != (size_t)sizeAsInt)
42 		throw std::bad_alloc();
43 
44 	// alloc
45 	ptr = deAlignedMalloc(sizeAsInt, (int)alignment);
46 	if (!ptr)
47 		throw std::bad_alloc();
48 
49 	// mark area as undefined for valgrind
50 #if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
51 	if (RUNNING_ON_VALGRIND)
52 	{
53 		VALGRIND_MAKE_MEM_UNDEFINED(ptr, numBytes);
54 	}
55 #endif
56 
57 	return ptr;
58 }
59 
ArrayBuffer_AlignedFree(void * ptr)60 void ArrayBuffer_AlignedFree (void* ptr)
61 {
62 	deAlignedFree(ptr);
63 }
64 
65 } // detail
66 
ArrayBuffer_selfTest(void)67 void ArrayBuffer_selfTest (void)
68 {
69 	// default constructor
70 	{
71 		de::ArrayBuffer<int> buf;
72 		DE_TEST_ASSERT(buf.size() == 0);
73 		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
74 	}
75 
76 	// sized constructor
77 	{
78 		de::ArrayBuffer<int> buf(4);
79 		DE_TEST_ASSERT(buf.size() == 4);
80 		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
81 	}
82 
83 	// copy constructor
84 	{
85 		de::ArrayBuffer<int> originalBuf(4);
86 		*originalBuf.getElementPtr(0) = 1;
87 		*originalBuf.getElementPtr(1) = 2;
88 		*originalBuf.getElementPtr(2) = 3;
89 		*originalBuf.getElementPtr(3) = 4;
90 
91 		de::ArrayBuffer<int> targetBuf(originalBuf);
92 
93 		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
94 		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
95 		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
96 		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);
97 
98 		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
99 		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
100 		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
101 		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
102 	}
103 
104 	// assignment
105 	{
106 		de::ArrayBuffer<int> originalBuf(4);
107 		*originalBuf.getElementPtr(0) = 1;
108 		*originalBuf.getElementPtr(1) = 2;
109 		*originalBuf.getElementPtr(2) = 3;
110 		*originalBuf.getElementPtr(3) = 4;
111 
112 		de::ArrayBuffer<int> targetBuf(1);
113 
114 		targetBuf = originalBuf;
115 
116 		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
117 		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
118 		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
119 		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);
120 
121 		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
122 		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
123 		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
124 		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
125 	}
126 
127 	// clear
128 	{
129 		de::ArrayBuffer<int> buf(4);
130 		buf.clear();
131 		DE_TEST_ASSERT(buf.size() == 0);
132 		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
133 	}
134 
135 	// setStorage
136 	{
137 		de::ArrayBuffer<int> buf(4);
138 		buf.setStorage(12);
139 		DE_TEST_ASSERT(buf.size() == 12);
140 		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
141 	}
142 
143 	// setStorage, too large
144 	{
145 		de::ArrayBuffer<int> buf(4);
146 		*buf.getElementPtr(0) = 1;
147 		*buf.getElementPtr(1) = 2;
148 		*buf.getElementPtr(2) = 3;
149 		*buf.getElementPtr(3) = 4;
150 
151 		try
152 		{
153 			buf.setStorage((size_t)-1);
154 
155 			// setStorage succeeded, all ok
156 		}
157 		catch (std::bad_alloc&)
158 		{
159 			// alloc failed, check storage not changed
160 
161 			DE_TEST_ASSERT(buf.size() == 4);
162 			DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
163 			DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
164 			DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
165 			DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
166 		}
167 	}
168 
169 	// swap
170 	{
171 		de::ArrayBuffer<int> buf;
172 		de::ArrayBuffer<int> source(4);
173 		*source.getElementPtr(0) = 1;
174 		*source.getElementPtr(1) = 2;
175 		*source.getElementPtr(2) = 3;
176 		*source.getElementPtr(3) = 4;
177 
178 		buf.swap(source);
179 
180 		DE_TEST_ASSERT(source.size() == 0);
181 		DE_TEST_ASSERT(buf.size() == 4);
182 		DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
183 		DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
184 		DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
185 		DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
186 	}
187 
188 	// default
189 	{
190 		de::ArrayBuffer<int> source(4);
191 		int dst;
192 		*source.getElementPtr(1) = 2;
193 
194 		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));
195 
196 		DE_TEST_ASSERT(dst == 2);
197 	}
198 
199 	// Aligned
200 	{
201 		de::ArrayBuffer<int, 64, sizeof(int)> source(4);
202 		int dst;
203 		*source.getElementPtr(1) = 2;
204 
205 		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));
206 
207 		DE_TEST_ASSERT(dst == 2);
208 	}
209 
210 	// Strided
211 	{
212 		de::ArrayBuffer<int, 4, 64> source(4);
213 		int dst;
214 		*source.getElementPtr(1) = 2;
215 
216 		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));
217 
218 		DE_TEST_ASSERT(dst == 2);
219 	}
220 
221 	// Aligned, Strided
222 	{
223 		de::ArrayBuffer<int, 32, 64> source(4);
224 		int dst;
225 		*source.getElementPtr(1) = 2;
226 
227 		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));
228 
229 		DE_TEST_ASSERT(dst == 2);
230 	}
231 }
232 
233 } // de
234