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 17 package android.renderscript; 18 19 import 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 **/ 30 public 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 static FieldPacker createFromArray(Object[] args) { 51 FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8); 52 for (Object arg : args) { 53 fp.addSafely(arg); 54 } 55 fp.resize(fp.mPos); 56 return fp; 57 } 58 59 public void align(int v) { 60 if ((v <= 0) || ((v & (v - 1)) != 0)) { 61 throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v); 62 } 63 64 while ((mPos & (v - 1)) != 0) { 65 mAlignment.flip(mPos); 66 mData[mPos++] = 0; 67 } 68 } 69 70 public void subalign(int v) { 71 if ((v & (v - 1)) != 0) { 72 throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v); 73 } 74 75 while ((mPos & (v - 1)) != 0) { 76 mPos--; 77 } 78 79 if (mPos > 0) { 80 while (mAlignment.get(mPos - 1) == true) { 81 mPos--; 82 mAlignment.flip(mPos); 83 } 84 } 85 86 } 87 88 public void reset() { 89 mPos = 0; 90 } 91 public void reset(int i) { 92 if ((i < 0) || (i > mLen)) { 93 throw new RSIllegalArgumentException("out of range argument: " + i); 94 } 95 mPos = i; 96 } 97 98 public void skip(int i) { 99 int res = mPos + i; 100 if ((res < 0) || (res > mLen)) { 101 throw new RSIllegalArgumentException("out of range argument: " + i); 102 } 103 mPos = res; 104 } 105 106 public void addI8(byte v) { 107 mData[mPos++] = v; 108 } 109 110 public byte subI8() { 111 subalign(1); 112 return mData[--mPos]; 113 } 114 115 public void addI16(short v) { 116 align(2); 117 mData[mPos++] = (byte)(v & 0xff); 118 mData[mPos++] = (byte)(v >> 8); 119 } 120 121 public short subI16() { 122 subalign(2); 123 short v = 0; 124 v = (short)((mData[--mPos] & 0xff) << 8); 125 v = (short)(v | (short)(mData[--mPos] & 0xff)); 126 return v; 127 } 128 129 130 public void addI32(int v) { 131 align(4); 132 mData[mPos++] = (byte)(v & 0xff); 133 mData[mPos++] = (byte)((v >> 8) & 0xff); 134 mData[mPos++] = (byte)((v >> 16) & 0xff); 135 mData[mPos++] = (byte)((v >> 24) & 0xff); 136 } 137 138 public int subI32() { 139 subalign(4); 140 int v = 0; 141 v = ((mData[--mPos] & 0xff) << 24); 142 v = v | ((mData[--mPos] & 0xff) << 16); 143 v = v | ((mData[--mPos] & 0xff) << 8); 144 v = v | ((mData[--mPos] & 0xff)); 145 return v; 146 } 147 148 149 public void addI64(long v) { 150 align(8); 151 mData[mPos++] = (byte)(v & 0xff); 152 mData[mPos++] = (byte)((v >> 8) & 0xff); 153 mData[mPos++] = (byte)((v >> 16) & 0xff); 154 mData[mPos++] = (byte)((v >> 24) & 0xff); 155 mData[mPos++] = (byte)((v >> 32) & 0xff); 156 mData[mPos++] = (byte)((v >> 40) & 0xff); 157 mData[mPos++] = (byte)((v >> 48) & 0xff); 158 mData[mPos++] = (byte)((v >> 56) & 0xff); 159 } 160 161 public long subI64() { 162 subalign(8); 163 long v = 0; 164 byte x = 0; 165 x = ((mData[--mPos])); 166 v = (long)(v | (((long)x) & 0xff) << 56l); 167 x = ((mData[--mPos])); 168 v = (long)(v | (((long)x) & 0xff) << 48l); 169 x = ((mData[--mPos])); 170 v = (long)(v | (((long)x) & 0xff) << 40l); 171 x = ((mData[--mPos])); 172 v = (long)(v | (((long)x) & 0xff) << 32l); 173 x = ((mData[--mPos])); 174 v = (long)(v | (((long)x) & 0xff) << 24l); 175 x = ((mData[--mPos])); 176 v = (long)(v | (((long)x) & 0xff) << 16l); 177 x = ((mData[--mPos])); 178 v = (long)(v | (((long)x) & 0xff) << 8l); 179 x = ((mData[--mPos])); 180 v = (long)(v | (((long)x) & 0xff)); 181 return v; 182 } 183 184 public void addU8(short v) { 185 if ((v < 0) || (v > 0xff)) { 186 android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )"); 187 throw new IllegalArgumentException("Saving value out of range for type"); 188 } 189 mData[mPos++] = (byte)v; 190 } 191 192 public void addU16(int v) { 193 if ((v < 0) || (v > 0xffff)) { 194 android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )"); 195 throw new IllegalArgumentException("Saving value out of range for type"); 196 } 197 align(2); 198 mData[mPos++] = (byte)(v & 0xff); 199 mData[mPos++] = (byte)(v >> 8); 200 } 201 202 public void addU32(long v) { 203 if ((v < 0) || (v > 0xffffffffL)) { 204 android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )"); 205 throw new IllegalArgumentException("Saving value out of range for type"); 206 } 207 align(4); 208 mData[mPos++] = (byte)(v & 0xff); 209 mData[mPos++] = (byte)((v >> 8) & 0xff); 210 mData[mPos++] = (byte)((v >> 16) & 0xff); 211 mData[mPos++] = (byte)((v >> 24) & 0xff); 212 } 213 214 public void addU64(long v) { 215 if (v < 0) { 216 android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )"); 217 throw new IllegalArgumentException("Saving value out of range for type"); 218 } 219 align(8); 220 mData[mPos++] = (byte)(v & 0xff); 221 mData[mPos++] = (byte)((v >> 8) & 0xff); 222 mData[mPos++] = (byte)((v >> 16) & 0xff); 223 mData[mPos++] = (byte)((v >> 24) & 0xff); 224 mData[mPos++] = (byte)((v >> 32) & 0xff); 225 mData[mPos++] = (byte)((v >> 40) & 0xff); 226 mData[mPos++] = (byte)((v >> 48) & 0xff); 227 mData[mPos++] = (byte)((v >> 56) & 0xff); 228 } 229 230 public void addF32(float v) { 231 addI32(Float.floatToRawIntBits(v)); 232 } 233 234 public float subF32() { 235 return Float.intBitsToFloat(subI32()); 236 } 237 238 public void addF64(double v) { 239 addI64(Double.doubleToRawLongBits(v)); 240 } 241 242 public double subF64() { 243 return Double.longBitsToDouble(subI64()); 244 } 245 246 public void addObj(BaseObj obj) { 247 if (obj != null) { 248 if (RenderScript.sPointerSize == 8) { 249 addI64(obj.getID(null)); 250 addI64(0); 251 addI64(0); 252 addI64(0); 253 } else { 254 addI32((int)obj.getID(null)); 255 } 256 } else { 257 if (RenderScript.sPointerSize == 8) { 258 addI64(0); 259 addI64(0); 260 addI64(0); 261 addI64(0); 262 } else { 263 addI32(0); 264 } 265 } 266 } 267 268 public void addF32(Float2 v) { 269 addF32(v.x); 270 addF32(v.y); 271 } 272 public void addF32(Float3 v) { 273 addF32(v.x); 274 addF32(v.y); 275 addF32(v.z); 276 } 277 public void addF32(Float4 v) { 278 addF32(v.x); 279 addF32(v.y); 280 addF32(v.z); 281 addF32(v.w); 282 } 283 284 public void addF64(Double2 v) { 285 addF64(v.x); 286 addF64(v.y); 287 } 288 public void addF64(Double3 v) { 289 addF64(v.x); 290 addF64(v.y); 291 addF64(v.z); 292 } 293 public void addF64(Double4 v) { 294 addF64(v.x); 295 addF64(v.y); 296 addF64(v.z); 297 addF64(v.w); 298 } 299 300 public void addI8(Byte2 v) { 301 addI8(v.x); 302 addI8(v.y); 303 } 304 public void addI8(Byte3 v) { 305 addI8(v.x); 306 addI8(v.y); 307 addI8(v.z); 308 } 309 public void addI8(Byte4 v) { 310 addI8(v.x); 311 addI8(v.y); 312 addI8(v.z); 313 addI8(v.w); 314 } 315 316 public void addU8(Short2 v) { 317 addU8(v.x); 318 addU8(v.y); 319 } 320 public void addU8(Short3 v) { 321 addU8(v.x); 322 addU8(v.y); 323 addU8(v.z); 324 } 325 public void addU8(Short4 v) { 326 addU8(v.x); 327 addU8(v.y); 328 addU8(v.z); 329 addU8(v.w); 330 } 331 332 public void addI16(Short2 v) { 333 addI16(v.x); 334 addI16(v.y); 335 } 336 public void addI16(Short3 v) { 337 addI16(v.x); 338 addI16(v.y); 339 addI16(v.z); 340 } 341 public void addI16(Short4 v) { 342 addI16(v.x); 343 addI16(v.y); 344 addI16(v.z); 345 addI16(v.w); 346 } 347 348 public void addU16(Int2 v) { 349 addU16(v.x); 350 addU16(v.y); 351 } 352 public void addU16(Int3 v) { 353 addU16(v.x); 354 addU16(v.y); 355 addU16(v.z); 356 } 357 public void addU16(Int4 v) { 358 addU16(v.x); 359 addU16(v.y); 360 addU16(v.z); 361 addU16(v.w); 362 } 363 364 public void addI32(Int2 v) { 365 addI32(v.x); 366 addI32(v.y); 367 } 368 public void addI32(Int3 v) { 369 addI32(v.x); 370 addI32(v.y); 371 addI32(v.z); 372 } 373 public void addI32(Int4 v) { 374 addI32(v.x); 375 addI32(v.y); 376 addI32(v.z); 377 addI32(v.w); 378 } 379 380 public void addU32(Long2 v) { 381 addU32(v.x); 382 addU32(v.y); 383 } 384 public void addU32(Long3 v) { 385 addU32(v.x); 386 addU32(v.y); 387 addU32(v.z); 388 } 389 public void addU32(Long4 v) { 390 addU32(v.x); 391 addU32(v.y); 392 addU32(v.z); 393 addU32(v.w); 394 } 395 396 public void addI64(Long2 v) { 397 addI64(v.x); 398 addI64(v.y); 399 } 400 public void addI64(Long3 v) { 401 addI64(v.x); 402 addI64(v.y); 403 addI64(v.z); 404 } 405 public void addI64(Long4 v) { 406 addI64(v.x); 407 addI64(v.y); 408 addI64(v.z); 409 addI64(v.w); 410 } 411 412 public void addU64(Long2 v) { 413 addU64(v.x); 414 addU64(v.y); 415 } 416 public void addU64(Long3 v) { 417 addU64(v.x); 418 addU64(v.y); 419 addU64(v.z); 420 } 421 public void addU64(Long4 v) { 422 addU64(v.x); 423 addU64(v.y); 424 addU64(v.z); 425 addU64(v.w); 426 } 427 428 429 public Float2 subFloat2() { 430 Float2 v = new Float2(); 431 v.y = subF32(); 432 v.x = subF32(); 433 return v; 434 } 435 public Float3 subFloat3() { 436 Float3 v = new Float3(); 437 v.z = subF32(); 438 v.y = subF32(); 439 v.x = subF32(); 440 return v; 441 } 442 public Float4 subFloat4() { 443 Float4 v = new Float4(); 444 v.w = subF32(); 445 v.z = subF32(); 446 v.y = subF32(); 447 v.x = subF32(); 448 return v; 449 } 450 451 public Double2 subDouble2() { 452 Double2 v = new Double2(); 453 v.y = subF64(); 454 v.x = subF64(); 455 return v; 456 } 457 public Double3 subDouble3() { 458 Double3 v = new Double3(); 459 v.z = subF64(); 460 v.y = subF64(); 461 v.x = subF64(); 462 return v; 463 } 464 public Double4 subDouble4() { 465 Double4 v = new Double4(); 466 v.w = subF64(); 467 v.z = subF64(); 468 v.y = subF64(); 469 v.x = subF64(); 470 return v; 471 } 472 473 public Byte2 subByte2() { 474 Byte2 v = new Byte2(); 475 v.y = subI8(); 476 v.x = subI8(); 477 return v; 478 } 479 public Byte3 subByte3() { 480 Byte3 v = new Byte3(); 481 v.z = subI8(); 482 v.y = subI8(); 483 v.x = subI8(); 484 return v; 485 } 486 public Byte4 subByte4() { 487 Byte4 v = new Byte4(); 488 v.w = subI8(); 489 v.z = subI8(); 490 v.y = subI8(); 491 v.x = subI8(); 492 return v; 493 } 494 495 public Short2 subShort2() { 496 Short2 v = new Short2(); 497 v.y = subI16(); 498 v.x = subI16(); 499 return v; 500 } 501 public Short3 subShort3() { 502 Short3 v = new Short3(); 503 v.z = subI16(); 504 v.y = subI16(); 505 v.x = subI16(); 506 return v; 507 } 508 public Short4 subShort4() { 509 Short4 v = new Short4(); 510 v.w = subI16(); 511 v.z = subI16(); 512 v.y = subI16(); 513 v.x = subI16(); 514 return v; 515 } 516 517 public Int2 subInt2() { 518 Int2 v = new Int2(); 519 v.y = subI32(); 520 v.x = subI32(); 521 return v; 522 } 523 public Int3 subInt3() { 524 Int3 v = new Int3(); 525 v.z = subI32(); 526 v.y = subI32(); 527 v.x = subI32(); 528 return v; 529 } 530 public Int4 subInt4() { 531 Int4 v = new Int4(); 532 v.w = subI32(); 533 v.z = subI32(); 534 v.y = subI32(); 535 v.x = subI32(); 536 return v; 537 } 538 539 public Long2 subLong2() { 540 Long2 v = new Long2(); 541 v.y = subI64(); 542 v.x = subI64(); 543 return v; 544 } 545 public Long3 subLong3() { 546 Long3 v = new Long3(); 547 v.z = subI64(); 548 v.y = subI64(); 549 v.x = subI64(); 550 return v; 551 } 552 public Long4 subLong4() { 553 Long4 v = new Long4(); 554 v.w = subI64(); 555 v.z = subI64(); 556 v.y = subI64(); 557 v.x = subI64(); 558 return v; 559 } 560 561 562 563 public void addMatrix(Matrix4f v) { 564 for (int i=0; i < v.mMat.length; i++) { 565 addF32(v.mMat[i]); 566 } 567 } 568 569 public Matrix4f subMatrix4f() { 570 Matrix4f v = new Matrix4f(); 571 for (int i = v.mMat.length - 1; i >= 0; i--) { 572 v.mMat[i] = subF32(); 573 } 574 return v; 575 } 576 577 public void addMatrix(Matrix3f v) { 578 for (int i=0; i < v.mMat.length; i++) { 579 addF32(v.mMat[i]); 580 } 581 } 582 583 public Matrix3f subMatrix3f() { 584 Matrix3f v = new Matrix3f(); 585 for (int i = v.mMat.length - 1; i >= 0; i--) { 586 v.mMat[i] = subF32(); 587 } 588 return v; 589 } 590 591 public void addMatrix(Matrix2f v) { 592 for (int i=0; i < v.mMat.length; i++) { 593 addF32(v.mMat[i]); 594 } 595 } 596 597 public Matrix2f subMatrix2f() { 598 Matrix2f v = new Matrix2f(); 599 for (int i = v.mMat.length - 1; i >= 0; i--) { 600 v.mMat[i] = subF32(); 601 } 602 return v; 603 } 604 605 public void addBoolean(boolean v) { 606 addI8((byte)(v ? 1 : 0)); 607 } 608 609 public boolean subBoolean() { 610 byte v = subI8(); 611 if (v == 1) { 612 return true; 613 } 614 return false; 615 } 616 617 public final byte[] getData() { 618 return mData; 619 } 620 621 /** 622 * Get the actual length used for the FieldPacker. 623 * 624 * @hide 625 */ 626 public int getPos() { 627 return mPos; 628 } 629 630 private void add(Object obj) { 631 if (obj instanceof Boolean) { 632 addBoolean((Boolean)obj); 633 return; 634 } 635 636 if (obj instanceof Byte) { 637 addI8((Byte)obj); 638 return; 639 } 640 641 if (obj instanceof Short) { 642 addI16((Short)obj); 643 return; 644 } 645 646 if (obj instanceof Integer) { 647 addI32((Integer)obj); 648 return; 649 } 650 651 if (obj instanceof Long) { 652 addI64((Long)obj); 653 return; 654 } 655 656 if (obj instanceof Float) { 657 addF32((Float)obj); 658 return; 659 } 660 661 if (obj instanceof Double) { 662 addF64((Double)obj); 663 return; 664 } 665 666 if (obj instanceof Byte2) { 667 addI8((Byte2)obj); 668 return; 669 } 670 671 if (obj instanceof Byte3) { 672 addI8((Byte3)obj); 673 return; 674 } 675 676 if (obj instanceof Byte4) { 677 addI8((Byte4)obj); 678 return; 679 } 680 681 if (obj instanceof Short2) { 682 addI16((Short2)obj); 683 return; 684 } 685 686 if (obj instanceof Short3) { 687 addI16((Short3)obj); 688 return; 689 } 690 691 if (obj instanceof Short4) { 692 addI16((Short4)obj); 693 return; 694 } 695 696 if (obj instanceof Int2) { 697 addI32((Int2)obj); 698 return; 699 } 700 701 if (obj instanceof Int3) { 702 addI32((Int3)obj); 703 return; 704 } 705 706 if (obj instanceof Int4) { 707 addI32((Int4)obj); 708 return; 709 } 710 711 if (obj instanceof Long2) { 712 addI64((Long2)obj); 713 return; 714 } 715 716 if (obj instanceof Long3) { 717 addI64((Long3)obj); 718 return; 719 } 720 721 if (obj instanceof Long4) { 722 addI64((Long4)obj); 723 return; 724 } 725 726 if (obj instanceof Float2) { 727 addF32((Float2)obj); 728 return; 729 } 730 731 if (obj instanceof Float3) { 732 addF32((Float3)obj); 733 return; 734 } 735 736 if (obj instanceof Float4) { 737 addF32((Float4)obj); 738 return; 739 } 740 741 if (obj instanceof Double2) { 742 addF64((Double2)obj); 743 return; 744 } 745 746 if (obj instanceof Double3) { 747 addF64((Double3)obj); 748 return; 749 } 750 751 if (obj instanceof Double4) { 752 addF64((Double4)obj); 753 return; 754 } 755 756 if (obj instanceof Matrix2f) { 757 addMatrix((Matrix2f)obj); 758 return; 759 } 760 761 if (obj instanceof Matrix3f) { 762 addMatrix((Matrix3f)obj); 763 return; 764 } 765 766 if (obj instanceof Matrix4f) { 767 addMatrix((Matrix4f)obj); 768 return; 769 } 770 771 if (obj instanceof BaseObj) { 772 addObj((BaseObj)obj); 773 return; 774 } 775 } 776 777 private boolean resize(int newSize) { 778 if (newSize == mLen) { 779 return false; 780 } 781 782 byte[] newData = new byte[newSize]; 783 System.arraycopy(mData, 0, newData, 0, mPos); 784 mData = newData; 785 mLen = newSize; 786 return true; 787 } 788 789 private void addSafely(Object obj) { 790 boolean retry; 791 final int oldPos = mPos; 792 do { 793 retry = false; 794 try { 795 add(obj); 796 } catch (ArrayIndexOutOfBoundsException e) { 797 mPos = oldPos; 798 resize(mLen * 2); 799 retry = true; 800 } 801 } while (retry); 802 } 803 804 private byte mData[]; 805 private int mPos; 806 private int mLen; 807 private BitSet mAlignment; 808 } 809