1/* 2 * Copyright (C) 2013 The Android Open Source Project 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 17package android.renderscript; 18 19import java.util.BitSet; 20 21/** 22 * Utility class for packing arguments and structures from Android system objects to 23 * RenderScript objects. 24 * 25 * This class is only intended to be used to support the 26 * reflected code generated by the RS tool chain. It should not 27 * be called directly. 28 * 29 **/ 30public class FieldPacker { 31 public FieldPacker(int len) { 32 mPos = 0; 33 mLen = len; 34 mData = new byte[len]; 35 mAlignment = new BitSet(); 36 } 37 38 public FieldPacker(byte[] data) { 39 // Advance mPos to the end of the buffer, since we are copying in the 40 // full data input. 41 mPos = data.length; 42 mLen = data.length; 43 mData = data; 44 mAlignment = new BitSet(); 45 // TODO: We should either have an actual FieldPacker copy constructor 46 // or drop support for computing alignment like this. As it stands, 47 // subAlign() can never work correctly for copied FieldPacker objects. 48 } 49 50 public void align(int v) { 51 if ((v <= 0) || ((v & (v - 1)) != 0)) { 52 throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v); 53 } 54 55 while ((mPos & (v - 1)) != 0) { 56 mAlignment.flip(mPos); 57 mData[mPos++] = 0; 58 } 59 } 60 61 public void subalign(int v) { 62 if ((v & (v - 1)) != 0) { 63 throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v); 64 } 65 66 while ((mPos & (v - 1)) != 0) { 67 mPos--; 68 } 69 70 if (mPos > 0) { 71 while (mAlignment.get(mPos - 1) == true) { 72 mPos--; 73 mAlignment.flip(mPos); 74 } 75 } 76 77 } 78 79 public void reset() { 80 mPos = 0; 81 } 82 public void reset(int i) { 83 if ((i < 0) || (i > mLen)) { 84 throw new RSIllegalArgumentException("out of range argument: " + i); 85 } 86 mPos = i; 87 } 88 89 public void skip(int i) { 90 int res = mPos + i; 91 if ((res < 0) || (res > mLen)) { 92 throw new RSIllegalArgumentException("out of range argument: " + i); 93 } 94 mPos = res; 95 } 96 97 public void addI8(byte v) { 98 mData[mPos++] = v; 99 } 100 101 public byte subI8() { 102 subalign(1); 103 return mData[--mPos]; 104 } 105 106 public void addI16(short v) { 107 align(2); 108 mData[mPos++] = (byte)(v & 0xff); 109 mData[mPos++] = (byte)(v >> 8); 110 } 111 112 public short subI16() { 113 subalign(2); 114 short v = 0; 115 v = (short)((mData[--mPos] & 0xff) << 8); 116 v = (short)(v | (short)(mData[--mPos] & 0xff)); 117 return v; 118 } 119 120 121 public void addI32(int v) { 122 align(4); 123 mData[mPos++] = (byte)(v & 0xff); 124 mData[mPos++] = (byte)((v >> 8) & 0xff); 125 mData[mPos++] = (byte)((v >> 16) & 0xff); 126 mData[mPos++] = (byte)((v >> 24) & 0xff); 127 } 128 129 public int subI32() { 130 subalign(4); 131 int v = 0; 132 v = ((mData[--mPos] & 0xff) << 24); 133 v = v | ((mData[--mPos] & 0xff) << 16); 134 v = v | ((mData[--mPos] & 0xff) << 8); 135 v = v | ((mData[--mPos] & 0xff)); 136 return v; 137 } 138 139 140 public void addI64(long v) { 141 align(8); 142 mData[mPos++] = (byte)(v & 0xff); 143 mData[mPos++] = (byte)((v >> 8) & 0xff); 144 mData[mPos++] = (byte)((v >> 16) & 0xff); 145 mData[mPos++] = (byte)((v >> 24) & 0xff); 146 mData[mPos++] = (byte)((v >> 32) & 0xff); 147 mData[mPos++] = (byte)((v >> 40) & 0xff); 148 mData[mPos++] = (byte)((v >> 48) & 0xff); 149 mData[mPos++] = (byte)((v >> 56) & 0xff); 150 } 151 152 public long subI64() { 153 subalign(8); 154 long v = 0; 155 byte x = 0; 156 x = ((mData[--mPos])); 157 v = (long)(v | (((long)x) & 0xff) << 56l); 158 x = ((mData[--mPos])); 159 v = (long)(v | (((long)x) & 0xff) << 48l); 160 x = ((mData[--mPos])); 161 v = (long)(v | (((long)x) & 0xff) << 40l); 162 x = ((mData[--mPos])); 163 v = (long)(v | (((long)x) & 0xff) << 32l); 164 x = ((mData[--mPos])); 165 v = (long)(v | (((long)x) & 0xff) << 24l); 166 x = ((mData[--mPos])); 167 v = (long)(v | (((long)x) & 0xff) << 16l); 168 x = ((mData[--mPos])); 169 v = (long)(v | (((long)x) & 0xff) << 8l); 170 x = ((mData[--mPos])); 171 v = (long)(v | (((long)x) & 0xff)); 172 return v; 173 } 174 175 public void addU8(short v) { 176 if ((v < 0) || (v > 0xff)) { 177 android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )"); 178 throw new IllegalArgumentException("Saving value out of range for type"); 179 } 180 mData[mPos++] = (byte)v; 181 } 182 183 public void addU16(int v) { 184 if ((v < 0) || (v > 0xffff)) { 185 android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )"); 186 throw new IllegalArgumentException("Saving value out of range for type"); 187 } 188 align(2); 189 mData[mPos++] = (byte)(v & 0xff); 190 mData[mPos++] = (byte)(v >> 8); 191 } 192 193 public void addU32(long v) { 194 if ((v < 0) || (v > 0xffffffffL)) { 195 android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )"); 196 throw new IllegalArgumentException("Saving value out of range for type"); 197 } 198 align(4); 199 mData[mPos++] = (byte)(v & 0xff); 200 mData[mPos++] = (byte)((v >> 8) & 0xff); 201 mData[mPos++] = (byte)((v >> 16) & 0xff); 202 mData[mPos++] = (byte)((v >> 24) & 0xff); 203 } 204 205 public void addU64(long v) { 206 if (v < 0) { 207 android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )"); 208 throw new IllegalArgumentException("Saving value out of range for type"); 209 } 210 align(8); 211 mData[mPos++] = (byte)(v & 0xff); 212 mData[mPos++] = (byte)((v >> 8) & 0xff); 213 mData[mPos++] = (byte)((v >> 16) & 0xff); 214 mData[mPos++] = (byte)((v >> 24) & 0xff); 215 mData[mPos++] = (byte)((v >> 32) & 0xff); 216 mData[mPos++] = (byte)((v >> 40) & 0xff); 217 mData[mPos++] = (byte)((v >> 48) & 0xff); 218 mData[mPos++] = (byte)((v >> 56) & 0xff); 219 } 220 221 public void addF32(float v) { 222 addI32(Float.floatToRawIntBits(v)); 223 } 224 225 public float subF32() { 226 return Float.intBitsToFloat(subI32()); 227 } 228 229 public void addF64(double v) { 230 addI64(Double.doubleToRawLongBits(v)); 231 } 232 233 public double subF64() { 234 return Double.longBitsToDouble(subI64()); 235 } 236 237 public void addObj(BaseObj obj) { 238 if (obj != null) { 239 if (RenderScript.sPointerSize == 8) { 240 addI64(obj.getID(null)); 241 addI64(0); 242 addI64(0); 243 addI64(0); 244 } 245 else { 246 addI32((int)obj.getID(null)); 247 } 248 } else { 249 if (RenderScript.sPointerSize == 8) { 250 addI64(0); 251 addI64(0); 252 addI64(0); 253 addI64(0); 254 } else { 255 addI32(0); 256 } 257 } 258 } 259 260 public void addF32(Float2 v) { 261 addF32(v.x); 262 addF32(v.y); 263 } 264 public void addF32(Float3 v) { 265 addF32(v.x); 266 addF32(v.y); 267 addF32(v.z); 268 } 269 public void addF32(Float4 v) { 270 addF32(v.x); 271 addF32(v.y); 272 addF32(v.z); 273 addF32(v.w); 274 } 275 276 public void addF64(Double2 v) { 277 addF64(v.x); 278 addF64(v.y); 279 } 280 public void addF64(Double3 v) { 281 addF64(v.x); 282 addF64(v.y); 283 addF64(v.z); 284 } 285 public void addF64(Double4 v) { 286 addF64(v.x); 287 addF64(v.y); 288 addF64(v.z); 289 addF64(v.w); 290 } 291 292 public void addI8(Byte2 v) { 293 addI8(v.x); 294 addI8(v.y); 295 } 296 public void addI8(Byte3 v) { 297 addI8(v.x); 298 addI8(v.y); 299 addI8(v.z); 300 } 301 public void addI8(Byte4 v) { 302 addI8(v.x); 303 addI8(v.y); 304 addI8(v.z); 305 addI8(v.w); 306 } 307 308 public void addU8(Short2 v) { 309 addU8(v.x); 310 addU8(v.y); 311 } 312 public void addU8(Short3 v) { 313 addU8(v.x); 314 addU8(v.y); 315 addU8(v.z); 316 } 317 public void addU8(Short4 v) { 318 addU8(v.x); 319 addU8(v.y); 320 addU8(v.z); 321 addU8(v.w); 322 } 323 324 public void addI16(Short2 v) { 325 addI16(v.x); 326 addI16(v.y); 327 } 328 public void addI16(Short3 v) { 329 addI16(v.x); 330 addI16(v.y); 331 addI16(v.z); 332 } 333 public void addI16(Short4 v) { 334 addI16(v.x); 335 addI16(v.y); 336 addI16(v.z); 337 addI16(v.w); 338 } 339 340 public void addU16(Int2 v) { 341 addU16(v.x); 342 addU16(v.y); 343 } 344 public void addU16(Int3 v) { 345 addU16(v.x); 346 addU16(v.y); 347 addU16(v.z); 348 } 349 public void addU16(Int4 v) { 350 addU16(v.x); 351 addU16(v.y); 352 addU16(v.z); 353 addU16(v.w); 354 } 355 356 public void addI32(Int2 v) { 357 addI32(v.x); 358 addI32(v.y); 359 } 360 public void addI32(Int3 v) { 361 addI32(v.x); 362 addI32(v.y); 363 addI32(v.z); 364 } 365 public void addI32(Int4 v) { 366 addI32(v.x); 367 addI32(v.y); 368 addI32(v.z); 369 addI32(v.w); 370 } 371 372 public void addU32(Long2 v) { 373 addU32(v.x); 374 addU32(v.y); 375 } 376 public void addU32(Long3 v) { 377 addU32(v.x); 378 addU32(v.y); 379 addU32(v.z); 380 } 381 public void addU32(Long4 v) { 382 addU32(v.x); 383 addU32(v.y); 384 addU32(v.z); 385 addU32(v.w); 386 } 387 388 public void addI64(Long2 v) { 389 addI64(v.x); 390 addI64(v.y); 391 } 392 public void addI64(Long3 v) { 393 addI64(v.x); 394 addI64(v.y); 395 addI64(v.z); 396 } 397 public void addI64(Long4 v) { 398 addI64(v.x); 399 addI64(v.y); 400 addI64(v.z); 401 addI64(v.w); 402 } 403 404 public void addU64(Long2 v) { 405 addU64(v.x); 406 addU64(v.y); 407 } 408 public void addU64(Long3 v) { 409 addU64(v.x); 410 addU64(v.y); 411 addU64(v.z); 412 } 413 public void addU64(Long4 v) { 414 addU64(v.x); 415 addU64(v.y); 416 addU64(v.z); 417 addU64(v.w); 418 } 419 420 421 public Float2 subFloat2() { 422 Float2 v = new Float2(); 423 v.y = subF32(); 424 v.x = subF32(); 425 return v; 426 } 427 public Float3 subFloat3() { 428 Float3 v = new Float3(); 429 v.z = subF32(); 430 v.y = subF32(); 431 v.x = subF32(); 432 return v; 433 } 434 public Float4 subFloat4() { 435 Float4 v = new Float4(); 436 v.w = subF32(); 437 v.z = subF32(); 438 v.y = subF32(); 439 v.x = subF32(); 440 return v; 441 } 442 443 public Double2 subDouble2() { 444 Double2 v = new Double2(); 445 v.y = subF64(); 446 v.x = subF64(); 447 return v; 448 } 449 public Double3 subDouble3() { 450 Double3 v = new Double3(); 451 v.z = subF64(); 452 v.y = subF64(); 453 v.x = subF64(); 454 return v; 455 } 456 public Double4 subDouble4() { 457 Double4 v = new Double4(); 458 v.w = subF64(); 459 v.z = subF64(); 460 v.y = subF64(); 461 v.x = subF64(); 462 return v; 463 } 464 465 public Byte2 subByte2() { 466 Byte2 v = new Byte2(); 467 v.y = subI8(); 468 v.x = subI8(); 469 return v; 470 } 471 public Byte3 subByte3() { 472 Byte3 v = new Byte3(); 473 v.z = subI8(); 474 v.y = subI8(); 475 v.x = subI8(); 476 return v; 477 } 478 public Byte4 subByte4() { 479 Byte4 v = new Byte4(); 480 v.w = subI8(); 481 v.z = subI8(); 482 v.y = subI8(); 483 v.x = subI8(); 484 return v; 485 } 486 487 public Short2 subShort2() { 488 Short2 v = new Short2(); 489 v.y = subI16(); 490 v.x = subI16(); 491 return v; 492 } 493 public Short3 subShort3() { 494 Short3 v = new Short3(); 495 v.z = subI16(); 496 v.y = subI16(); 497 v.x = subI16(); 498 return v; 499 } 500 public Short4 subShort4() { 501 Short4 v = new Short4(); 502 v.w = subI16(); 503 v.z = subI16(); 504 v.y = subI16(); 505 v.x = subI16(); 506 return v; 507 } 508 509 public Int2 subInt2() { 510 Int2 v = new Int2(); 511 v.y = subI32(); 512 v.x = subI32(); 513 return v; 514 } 515 public Int3 subInt3() { 516 Int3 v = new Int3(); 517 v.z = subI32(); 518 v.y = subI32(); 519 v.x = subI32(); 520 return v; 521 } 522 public Int4 subInt4() { 523 Int4 v = new Int4(); 524 v.w = subI32(); 525 v.z = subI32(); 526 v.y = subI32(); 527 v.x = subI32(); 528 return v; 529 } 530 531 public Long2 subLong2() { 532 Long2 v = new Long2(); 533 v.y = subI64(); 534 v.x = subI64(); 535 return v; 536 } 537 public Long3 subLong3() { 538 Long3 v = new Long3(); 539 v.z = subI64(); 540 v.y = subI64(); 541 v.x = subI64(); 542 return v; 543 } 544 public Long4 subLong4() { 545 Long4 v = new Long4(); 546 v.w = subI64(); 547 v.z = subI64(); 548 v.y = subI64(); 549 v.x = subI64(); 550 return v; 551 } 552 553 554 555 public void addMatrix(Matrix4f v) { 556 for (int i=0; i < v.mMat.length; i++) { 557 addF32(v.mMat[i]); 558 } 559 } 560 561 public Matrix4f subMatrix4f() { 562 Matrix4f v = new Matrix4f(); 563 for (int i = v.mMat.length - 1; i >= 0; i--) { 564 v.mMat[i] = subF32(); 565 } 566 return v; 567 } 568 569 public void addMatrix(Matrix3f v) { 570 for (int i=0; i < v.mMat.length; i++) { 571 addF32(v.mMat[i]); 572 } 573 } 574 575 public Matrix3f subMatrix3f() { 576 Matrix3f v = new Matrix3f(); 577 for (int i = v.mMat.length - 1; i >= 0; i--) { 578 v.mMat[i] = subF32(); 579 } 580 return v; 581 } 582 583 public void addMatrix(Matrix2f v) { 584 for (int i=0; i < v.mMat.length; i++) { 585 addF32(v.mMat[i]); 586 } 587 } 588 589 public Matrix2f subMatrix2f() { 590 Matrix2f v = new Matrix2f(); 591 for (int i = v.mMat.length - 1; i >= 0; i--) { 592 v.mMat[i] = subF32(); 593 } 594 return v; 595 } 596 597 public void addBoolean(boolean v) { 598 addI8((byte)(v ? 1 : 0)); 599 } 600 601 public boolean subBoolean() { 602 byte v = subI8(); 603 if (v == 1) { 604 return true; 605 } 606 return false; 607 } 608 609 public final byte[] getData() { 610 return mData; 611 } 612 613 /** 614 * Get the actual length used for the FieldPacker. 615 * 616 * @hide 617 */ 618 public int getPos() { 619 return mPos; 620 } 621 622 private final byte mData[]; 623 private int mPos; 624 private int mLen; 625 private BitSet mAlignment; 626 627} 628 629 630