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