• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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 package com.badlogic.gdx.tests;
18 
19 import java.nio.ByteBuffer;
20 import java.nio.CharBuffer;
21 import java.nio.DoubleBuffer;
22 import java.nio.FloatBuffer;
23 import java.nio.IntBuffer;
24 import java.nio.LongBuffer;
25 import java.nio.ShortBuffer;
26 
27 import com.badlogic.gdx.Application.ApplicationType;
28 import com.badlogic.gdx.Gdx;
29 import com.badlogic.gdx.tests.utils.GdxTest;
30 import com.badlogic.gdx.utils.BufferUtils;
31 import com.badlogic.gdx.utils.GdxRuntimeException;
32 import com.badlogic.gdx.utils.TimeUtils;
33 
34 public class BufferUtilsTest extends GdxTest {
35 	static final int NUM_MB = 5;
36 
37 	@Override
create()38 	public void create () {
39 		//Not emulated in gwt
40 		//ByteBuffer bytebuffer = BufferUtils.newUnsafeByteBuffer(1000 * 1000);
41 		//BufferUtils.disposeUnsafeByteBuffer(bytebuffer);
42 
43 		ByteBuffer bb = BufferUtils.newByteBuffer(8);
44 		CharBuffer cb = BufferUtils.newCharBuffer(8);
45 		ShortBuffer sb = BufferUtils.newShortBuffer(8);
46 		IntBuffer ib = BufferUtils.newIntBuffer(8);
47 		LongBuffer lb = BufferUtils.newLongBuffer(8);
48 		FloatBuffer fb = BufferUtils.newFloatBuffer(8);
49 		DoubleBuffer db = BufferUtils.newDoubleBuffer(8);
50 
51 		bb.position(4);
52 		BufferUtils.copy(new byte[] {1, 2, 3, 4}, 0, bb, 4);
53 		checkInt(bb.get(), 1);
54 		checkInt(bb.get(), 2);
55 		checkInt(bb.get(), 3);
56 		checkInt(bb.get(), 4);
57 
58 		cb.position(4);
59 		BufferUtils.copy(new char[] {1, 2, 3, 4}, 0, cb, 4);
60 		checkInt(cb.get(), 1);
61 		checkInt(cb.get(), 2);
62 		checkInt(cb.get(), 3);
63 		checkInt(cb.get(), 4);
64 		cb.position(0);
65 		BufferUtils.copy(new char[] {5, 6, 7, 8}, 1, cb, 3);
66 		checkInt(cb.get(), 6);
67 		checkInt(cb.get(), 7);
68 		checkInt(cb.get(), 8);
69 
70 		sb.position(4);
71 		BufferUtils.copy(new short[] {1, 2, 3, 4}, 0, sb, 4);
72 		checkInt(sb.get(), 1);
73 		checkInt(sb.get(), 2);
74 		checkInt(sb.get(), 3);
75 		checkInt(sb.get(), 4);
76 		sb.position(0);
77 		BufferUtils.copy(new short[] {5, 6, 7, 8}, 1, sb, 3);
78 		checkInt(sb.get(), 6);
79 		checkInt(sb.get(), 7);
80 		checkInt(sb.get(), 8);
81 
82 		ib.position(4);
83 		BufferUtils.copy(new int[] {1, 2, 3, 4}, 0, ib, 4);
84 		checkInt(ib.get(), 1);
85 		checkInt(ib.get(), 2);
86 		checkInt(ib.get(), 3);
87 		checkInt(ib.get(), 4);
88 		ib.position(0);
89 		BufferUtils.copy(new int[] {5, 6, 7, 8}, 1, ib, 3);
90 		checkInt(ib.get(), 6);
91 		checkInt(ib.get(), 7);
92 		checkInt(ib.get(), 8);
93 
94 		lb.position(4);
95 		BufferUtils.copy(new long[] {1, 2, 3, 4}, 0, lb, 4);
96 		checkInt(lb.get(), 1);
97 		checkInt(lb.get(), 2);
98 		checkInt(lb.get(), 3);
99 		checkInt(lb.get(), 4);
100 		lb.position(0);
101 		BufferUtils.copy(new long[] {5, 6, 7, 8}, 1, lb, 3);
102 		checkInt(lb.get(), 6);
103 		checkInt(lb.get(), 7);
104 		checkInt(lb.get(), 8);
105 
106 		fb.position(4);
107 		BufferUtils.copy(new float[] {1, 2, 3, 4}, 0, fb, 4);
108 		checkFloat(fb.get(), 1);
109 		checkFloat(fb.get(), 2);
110 		checkFloat(fb.get(), 3);
111 		checkFloat(fb.get(), 4);
112 		fb.position(0);
113 		BufferUtils.copy(new float[] {5, 6, 7, 8}, 1, fb, 3);
114 		checkFloat(fb.get(), 6);
115 		checkFloat(fb.get(), 7);
116 		checkFloat(fb.get(), 8);
117 
118 		if (Gdx.app.getType() != ApplicationType.WebGL) { // gwt throws: NYI: Numbers.doubleToRawLongBits
119 			db.position(4);
120 			BufferUtils.copy(new double[] {1, 2, 3, 4}, 0, db, 4);
121 			checkFloat(db.get(), 1);
122 			checkFloat(db.get(), 2);
123 			checkFloat(db.get(), 3);
124 			checkFloat(db.get(), 4);
125 			db.position(0);
126 			BufferUtils.copy(new double[] {5, 6, 7, 8}, 1, db, 3);
127 			checkFloat(db.get(), 6);
128 			checkFloat(db.get(), 7);
129 			checkFloat(db.get(), 8);
130 		}
131 
132 		ByteBuffer bb2 = BufferUtils.newByteBuffer(4);
133 		bb.position(4);
134 		BufferUtils.copy(bb, bb2, 4);
135 		checkInt(bb2.get(), 1);
136 		checkInt(bb2.get(), 2);
137 		checkInt(bb2.get(), 3);
138 		checkInt(bb2.get(), 4);
139 
140 		bench();
141 	}
142 
bench()143 	private void bench () {
144 		benchByte();
145 		benchShort();
146 		benchInt();
147 		benchLong();
148 		benchFloat();
149 		benchDouble();
150 	}
151 
benchByte()152 	private void benchByte () {
153 		ByteBuffer bb = BufferUtils.newByteBuffer(1024 * 1024);
154 		byte[] bytes = new byte[1024 * 1024];
155 		int len = bytes.length;
156 		final int NUM_MB = 5;
157 
158 		// relative put
159 		long start = TimeUtils.nanoTime();
160 		for (int j = 0; j < NUM_MB; j++) {
161 			bb.clear();
162 			for (int i = 0; i < len; i++)
163 				bb.put(bytes[i]);
164 		}
165 		Gdx.app.log("BufferUtilsTest", "ByteBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
166 
167 		// absolute put
168 		start = TimeUtils.nanoTime();
169 		for (int j = 0; j < NUM_MB; j++) {
170 			bb.clear();
171 			for (int i = 0; i < len; i++)
172 				bb.put(i, bytes[i]);
173 		}
174 		Gdx.app.log("BufferUtilsTest", "ByteBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
175 
176 		// bulk put
177 		start = TimeUtils.nanoTime();
178 		for (int j = 0; j < NUM_MB; j++) {
179 			bb.clear();
180 			bb.put(bytes);
181 		}
182 		Gdx.app.log("BufferUtilsTest", "ByteBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
183 
184 		// JNI put
185 		start = TimeUtils.nanoTime();
186 		for (int j = 0; j < NUM_MB; j++) {
187 			bb.clear();
188 			BufferUtils.copy(bytes, 0, bb, len);
189 		}
190 		Gdx.app.log("BufferUtilsTest", "ByteBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
191 	}
192 
benchShort()193 	private void benchShort () {
194 		ShortBuffer sb = BufferUtils.newShortBuffer(1024 * 1024 / 2);
195 		short[] shorts = new short[1024 * 1024 / 2];
196 		int len = shorts.length;
197 
198 		// relative put
199 		long start = TimeUtils.nanoTime();
200 		for (int j = 0; j < NUM_MB; j++) {
201 			sb.clear();
202 			for (int i = 0; i < len; i++)
203 				sb.put(shorts[i]);
204 		}
205 		Gdx.app.log("BufferUtilsTest", "ShortBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
206 
207 		// absolute put
208 		start = TimeUtils.nanoTime();
209 		for (int j = 0; j < NUM_MB; j++) {
210 			sb.clear();
211 			for (int i = 0; i < len; i++)
212 				sb.put(i, shorts[i]);
213 		}
214 		Gdx.app.log("BufferUtilsTest", "ShortBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
215 
216 		// bulk put
217 		start = TimeUtils.nanoTime();
218 		for (int j = 0; j < NUM_MB; j++) {
219 			sb.clear();
220 			sb.put(shorts);
221 		}
222 		Gdx.app.log("BufferUtilsTest", "ShortBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
223 
224 		// JNI put
225 		start = TimeUtils.nanoTime();
226 		for (int j = 0; j < NUM_MB; j++) {
227 			sb.clear();
228 			BufferUtils.copy(shorts, 0, sb, len);
229 		}
230 		Gdx.app.log("BufferUtilsTest", "ShortBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
231 	}
232 
benchInt()233 	private void benchInt () {
234 		IntBuffer ib = BufferUtils.newIntBuffer(1024 * 1024 / 4);
235 		int[] ints = new int[1024 * 1024 / 4];
236 		int len = ints.length;
237 
238 		// relative put
239 		long start = TimeUtils.nanoTime();
240 		for (int j = 0; j < NUM_MB; j++) {
241 			ib.clear();
242 			for (int i = 0; i < len; i++)
243 				ib.put(ints[i]);
244 		}
245 		Gdx.app.log("BufferUtilsTest", "IntBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
246 
247 		// absolute put
248 		start = TimeUtils.nanoTime();
249 		for (int j = 0; j < NUM_MB; j++) {
250 			ib.clear();
251 			for (int i = 0; i < len; i++)
252 				ib.put(i, ints[i]);
253 		}
254 		Gdx.app.log("BufferUtilsTest", "IntBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
255 
256 		// bulk put
257 		start = TimeUtils.nanoTime();
258 		for (int j = 0; j < NUM_MB; j++) {
259 			ib.clear();
260 			ib.put(ints);
261 		}
262 		Gdx.app.log("BufferUtilsTest", "IntBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
263 
264 		// JNI put
265 		start = TimeUtils.nanoTime();
266 		for (int j = 0; j < NUM_MB; j++) {
267 			ib.clear();
268 			BufferUtils.copy(ints, 0, ib, len);
269 		}
270 		Gdx.app.log("BufferUtilsTest", "IntBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
271 	}
272 
benchLong()273 	private void benchLong () {
274 		LongBuffer lb = BufferUtils.newLongBuffer(1024 * 1024 / 8);
275 		long[] longs = new long[1024 * 1024 / 8];
276 		int len = longs.length;
277 
278 		// relative put
279 		long start = TimeUtils.nanoTime();
280 		for (int j = 0; j < NUM_MB; j++) {
281 			lb.clear();
282 			for (int i = 0; i < len; i++)
283 				lb.put(longs[i]);
284 		}
285 		Gdx.app.log("BufferUtilsTest", "LongBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
286 
287 		// absolute put
288 		start = TimeUtils.nanoTime();
289 		for (int j = 0; j < NUM_MB; j++) {
290 			lb.clear();
291 			for (int i = 0; i < len; i++)
292 				lb.put(i, longs[i]);
293 		}
294 		Gdx.app.log("BufferUtilsTest", "LongBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
295 
296 		// bulk put
297 		start = TimeUtils.nanoTime();
298 		for (int j = 0; j < NUM_MB; j++) {
299 			lb.clear();
300 			lb.put(longs);
301 		}
302 		Gdx.app.log("BufferUtilsTest", "LongBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
303 
304 		// JNI put
305 		start = TimeUtils.nanoTime();
306 		for (int j = 0; j < NUM_MB; j++) {
307 			lb.clear();
308 			BufferUtils.copy(longs, 0, lb, len);
309 		}
310 		Gdx.app.log("BufferUtilsTest", "LongBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
311 	}
312 
benchFloat()313 	private void benchFloat () {
314 		FloatBuffer fb = BufferUtils.newFloatBuffer(1024 * 1024 / 4);
315 		float[] floats = new float[1024 * 1024 / 4];
316 		int len = floats.length;
317 
318 		// relative put
319 		long start = TimeUtils.nanoTime();
320 		for (int j = 0; j < NUM_MB; j++) {
321 			fb.clear();
322 			for (int i = 0; i < len; i++)
323 				fb.put(floats[i]);
324 		}
325 		Gdx.app.log("BufferUtilsTest", "FloatBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
326 
327 		// absolute put
328 		start = TimeUtils.nanoTime();
329 		for (int j = 0; j < NUM_MB; j++) {
330 			fb.clear();
331 			for (int i = 0; i < len; i++)
332 				fb.put(i, floats[i]);
333 		}
334 		Gdx.app.log("BufferUtilsTest", "FloatBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
335 
336 		// bulk put
337 		start = TimeUtils.nanoTime();
338 		for (int j = 0; j < NUM_MB; j++) {
339 			fb.clear();
340 			fb.put(floats);
341 		}
342 		Gdx.app.log("BufferUtilsTest", "FloatBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
343 
344 		// JNI put
345 		start = TimeUtils.nanoTime();
346 		for (int j = 0; j < NUM_MB; j++) {
347 			fb.clear();
348 			BufferUtils.copy(floats, 0, fb, len);
349 		}
350 		Gdx.app.log("BufferUtilsTest", "FloatBuffer native bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
351 	}
352 
benchDouble()353 	private void benchDouble () {
354 		DoubleBuffer db = BufferUtils.newDoubleBuffer(1024 * 1024 / 8);
355 		double[] doubles = new double[1024 * 1024 / 8];
356 		int len = doubles.length;
357 
358 		// relative put
359 		long start = TimeUtils.nanoTime();
360 		for (int j = 0; j < NUM_MB; j++) {
361 			db.clear();
362 			for (int i = 0; i < len; i++)
363 				db.put(doubles[i]);
364 		}
365 		Gdx.app.log("BufferUtilsTest", "DoubleBuffer relative put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
366 
367 		// absolute put
368 		start = TimeUtils.nanoTime();
369 		for (int j = 0; j < NUM_MB; j++) {
370 			db.clear();
371 			for (int i = 0; i < len; i++)
372 				db.put(i, doubles[i]);
373 		}
374 		Gdx.app.log("BufferUtilsTest", "DoubleBuffer absolute put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
375 
376 		// bulk put
377 		start = TimeUtils.nanoTime();
378 		for (int j = 0; j < NUM_MB; j++) {
379 			db.clear();
380 			db.put(doubles);
381 		}
382 		Gdx.app.log("BufferUtilsTest", "DoubleBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
383 
384 		// JNI put
385 		start = TimeUtils.nanoTime();
386 		for (int j = 0; j < NUM_MB; j++) {
387 			db.clear();
388 			BufferUtils.copy(doubles, 0, db, len);
389 		}
390 		Gdx.app.log("BufferUtilsTest", "DoubleBuffer bulk put: " + (TimeUtils.nanoTime() - start) / 1000000000.0f);
391 	}
392 
checkInt(long val1, long val2)393 	private void checkInt (long val1, long val2) {
394 		if (val1 != val2) {
395 			Gdx.app.error("BufferUtilsTest", "checkInt failed: "+val1+" != "+val2);
396 			throw new GdxRuntimeException("Error, val1 != val2");
397 		}
398 	}
399 
checkFloat(double val1, double val2)400 	private void checkFloat (double val1, double val2) {
401 		if (val1 != val2) {
402 			Gdx.app.error("BufferUtilsTest", "checkFloat failed: "+val1+" != "+val2);
403 			throw new GdxRuntimeException("Error, val1 != val2");
404 		}
405 	}
406 }
407