1/* 2 * Copyright (C) 2008 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.lang.reflect.Field; 20import android.util.Log; 21 22/** 23 * <p>The most basic data type. An element represents one cell of a memory allocation. 24 * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms. 25 * Examples of basic elements are:</p> 26 * <ul> 27 * <li>Single float value</li> 28 * <li>4 element float vector</li> 29 * <li>single RGB-565 color</li> 30 * <li>single unsigned int 16</li> 31 * </ul> 32 * <p>Complex elements contain a list of sub-elements and names that 33 * represents a structure of data. The fields can be accessed by name 34 * from a script or shader. The memory layout is defined and ordered. Data 35 * alignment is determined by the most basic primitive type. i.e. a float4 36 * vector will be aligned to sizeof(float) and not sizeof(float4). The 37 * ordering of elements in memory will be the order in which they were added 38 * with each component aligned as necessary. No re-ordering will be done.</p> 39 * 40 * <p>The primary source of elements are from scripts. A script that exports a 41 * bind point for a data structure generates a Renderscript element to represent the 42 * data exported by the script. The other common source of elements is from bitmap formats.</p> 43 **/ 44public class Element extends BaseObj { 45 int mSize; 46 Element[] mElements; 47 String[] mElementNames; 48 int[] mArraySizes; 49 int[] mOffsetInBytes; 50 51 DataType mType; 52 DataKind mKind; 53 boolean mNormalized; 54 int mVectorSize; 55 56 /** 57 * @hide 58 * @return element size in bytes 59 */ 60 public int getSizeBytes() {return mSize;} 61 62 63 /** 64 * DataType represents the basic type information for a basic element. The 65 * naming convention follows. For numeric types its FLOAT, SIGNED, UNSIGNED 66 * followed by the _BITS where BITS is the size of the data. BOOLEAN is a 67 * true / false (1,0) represented in an 8 bit container. The UNSIGNED 68 * variants with multiple bit definitions are for packed graphical data 69 * formats and represents vectors with per vector member sizes which are 70 * treated as a single unit for packing and alignment purposes. 71 * 72 * MATRIX the three matrix types contain FLOAT_32 elements and are treated 73 * as 32 bits for alignment purposes. 74 * 75 * RS_* objects. 32 bit opaque handles. 76 */ 77 public enum DataType { 78 //FLOAT_16 (1, 2), 79 FLOAT_32 (2, 4), 80 FLOAT_64 (3, 8), 81 SIGNED_8 (4, 1), 82 SIGNED_16 (5, 2), 83 SIGNED_32 (6, 4), 84 SIGNED_64 (7, 8), 85 UNSIGNED_8 (8, 1), 86 UNSIGNED_16 (9, 2), 87 UNSIGNED_32 (10, 4), 88 UNSIGNED_64 (11, 8), 89 90 BOOLEAN(12, 1), 91 92 UNSIGNED_5_6_5 (13, 2), 93 UNSIGNED_5_5_5_1 (14, 2), 94 UNSIGNED_4_4_4_4 (15, 2), 95 96 MATRIX_4X4 (16, 64), 97 MATRIX_3X3 (17, 36), 98 MATRIX_2X2 (18, 16), 99 100 RS_ELEMENT (1000, 4), 101 RS_TYPE (1001, 4), 102 RS_ALLOCATION (1002, 4), 103 RS_SAMPLER (1003, 4), 104 RS_SCRIPT (1004, 4), 105 RS_MESH (1005, 4), 106 RS_PROGRAM_FRAGMENT (1006, 4), 107 RS_PROGRAM_VERTEX (1007, 4), 108 RS_PROGRAM_RASTER (1008, 4), 109 RS_PROGRAM_STORE (1009, 4); 110 111 int mID; 112 int mSize; 113 DataType(int id, int size) { 114 mID = id; 115 mSize = size; 116 } 117 } 118 119 /** 120 * The special interpretation of the data if required. This is primarly 121 * useful for graphical data. USER indicates no special interpretation is 122 * expected. PIXEL is used in conjunction with the standard data types for 123 * representing texture formats. 124 */ 125 public enum DataKind { 126 USER (0), 127 128 PIXEL_L (7), 129 PIXEL_A (8), 130 PIXEL_LA (9), 131 PIXEL_RGB (10), 132 PIXEL_RGBA (11), 133 PIXEL_DEPTH (12); 134 135 int mID; 136 DataKind(int id) { 137 mID = id; 138 } 139 } 140 141 /** 142 * Return if a element is too complex for use as a data source for a Mesh or 143 * a Program. 144 * 145 * @return boolean 146 */ 147 public boolean isComplex() { 148 if (mElements == null) { 149 return false; 150 } 151 for (int ct=0; ct < mElements.length; ct++) { 152 if (mElements[ct].mElements != null) { 153 return true; 154 } 155 } 156 return false; 157 } 158 159 /** 160 * @hide 161 * @return number of sub-elements in this element 162 */ 163 public int getSubElementCount() { 164 if (mElements == null) { 165 return 0; 166 } 167 return mElements.length; 168 } 169 170 /** 171 * @hide 172 * @param index index of the sub-element to return 173 * @return sub-element in this element at given index 174 */ 175 public Element getSubElement(int index) { 176 if (mElements == null) { 177 throw new RSIllegalArgumentException("Element contains no sub-elements"); 178 } 179 if (index < 0 || index >= mElements.length) { 180 throw new RSIllegalArgumentException("Illegal sub-element index"); 181 } 182 return mElements[index]; 183 } 184 185 /** 186 * @hide 187 * @param index index of the sub-element 188 * @return sub-element in this element at given index 189 */ 190 public String getSubElementName(int index) { 191 if (mElements == null) { 192 throw new RSIllegalArgumentException("Element contains no sub-elements"); 193 } 194 if (index < 0 || index >= mElements.length) { 195 throw new RSIllegalArgumentException("Illegal sub-element index"); 196 } 197 return mElementNames[index]; 198 } 199 200 /** 201 * @hide 202 * @param index index of the sub-element 203 * @return array size of sub-element in this element at given index 204 */ 205 public int getSubElementArraySize(int index) { 206 if (mElements == null) { 207 throw new RSIllegalArgumentException("Element contains no sub-elements"); 208 } 209 if (index < 0 || index >= mElements.length) { 210 throw new RSIllegalArgumentException("Illegal sub-element index"); 211 } 212 return mArraySizes[index]; 213 } 214 215 /** 216 * @hide 217 * @param index index of the sub-element 218 * @return offset in bytes of sub-element in this element at given index 219 */ 220 public int getSubElementOffsetBytes(int index) { 221 if (mElements == null) { 222 throw new RSIllegalArgumentException("Element contains no sub-elements"); 223 } 224 if (index < 0 || index >= mElements.length) { 225 throw new RSIllegalArgumentException("Illegal sub-element index"); 226 } 227 return mOffsetInBytes[index]; 228 } 229 230 /** 231 * Utility function for returning an Element containing a single Boolean. 232 * 233 * @param rs Context to which the element will belong. 234 * 235 * @return Element 236 */ 237 public static Element BOOLEAN(RenderScript rs) { 238 if(rs.mElement_BOOLEAN == null) { 239 rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN); 240 } 241 return rs.mElement_BOOLEAN; 242 } 243 244 /** 245 * Utility function for returning an Element containing a single UNSIGNED_8. 246 * 247 * @param rs Context to which the element will belong. 248 * 249 * @return Element 250 */ 251 public static Element U8(RenderScript rs) { 252 if(rs.mElement_U8 == null) { 253 rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8); 254 } 255 return rs.mElement_U8; 256 } 257 258 /** 259 * Utility function for returning an Element containing a single SIGNED_8. 260 * 261 * @param rs Context to which the element will belong. 262 * 263 * @return Element 264 */ 265 public static Element I8(RenderScript rs) { 266 if(rs.mElement_I8 == null) { 267 rs.mElement_I8 = createUser(rs, DataType.SIGNED_8); 268 } 269 return rs.mElement_I8; 270 } 271 272 public static Element U16(RenderScript rs) { 273 if(rs.mElement_U16 == null) { 274 rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16); 275 } 276 return rs.mElement_U16; 277 } 278 279 public static Element I16(RenderScript rs) { 280 if(rs.mElement_I16 == null) { 281 rs.mElement_I16 = createUser(rs, DataType.SIGNED_16); 282 } 283 return rs.mElement_I16; 284 } 285 286 public static Element U32(RenderScript rs) { 287 if(rs.mElement_U32 == null) { 288 rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32); 289 } 290 return rs.mElement_U32; 291 } 292 293 public static Element I32(RenderScript rs) { 294 if(rs.mElement_I32 == null) { 295 rs.mElement_I32 = createUser(rs, DataType.SIGNED_32); 296 } 297 return rs.mElement_I32; 298 } 299 300 public static Element U64(RenderScript rs) { 301 if(rs.mElement_U64 == null) { 302 rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64); 303 } 304 return rs.mElement_U64; 305 } 306 307 public static Element I64(RenderScript rs) { 308 if(rs.mElement_I64 == null) { 309 rs.mElement_I64 = createUser(rs, DataType.SIGNED_64); 310 } 311 return rs.mElement_I64; 312 } 313 314 public static Element F32(RenderScript rs) { 315 if(rs.mElement_F32 == null) { 316 rs.mElement_F32 = createUser(rs, DataType.FLOAT_32); 317 } 318 return rs.mElement_F32; 319 } 320 321 public static Element F64(RenderScript rs) { 322 if(rs.mElement_F64 == null) { 323 rs.mElement_F64 = createUser(rs, DataType.FLOAT_64); 324 } 325 return rs.mElement_F64; 326 } 327 328 public static Element ELEMENT(RenderScript rs) { 329 if(rs.mElement_ELEMENT == null) { 330 rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT); 331 } 332 return rs.mElement_ELEMENT; 333 } 334 335 public static Element TYPE(RenderScript rs) { 336 if(rs.mElement_TYPE == null) { 337 rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE); 338 } 339 return rs.mElement_TYPE; 340 } 341 342 public static Element ALLOCATION(RenderScript rs) { 343 if(rs.mElement_ALLOCATION == null) { 344 rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION); 345 } 346 return rs.mElement_ALLOCATION; 347 } 348 349 public static Element SAMPLER(RenderScript rs) { 350 if(rs.mElement_SAMPLER == null) { 351 rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER); 352 } 353 return rs.mElement_SAMPLER; 354 } 355 356 public static Element SCRIPT(RenderScript rs) { 357 if(rs.mElement_SCRIPT == null) { 358 rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT); 359 } 360 return rs.mElement_SCRIPT; 361 } 362 363 public static Element MESH(RenderScript rs) { 364 if(rs.mElement_MESH == null) { 365 rs.mElement_MESH = createUser(rs, DataType.RS_MESH); 366 } 367 return rs.mElement_MESH; 368 } 369 370 public static Element PROGRAM_FRAGMENT(RenderScript rs) { 371 if(rs.mElement_PROGRAM_FRAGMENT == null) { 372 rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT); 373 } 374 return rs.mElement_PROGRAM_FRAGMENT; 375 } 376 377 public static Element PROGRAM_VERTEX(RenderScript rs) { 378 if(rs.mElement_PROGRAM_VERTEX == null) { 379 rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX); 380 } 381 return rs.mElement_PROGRAM_VERTEX; 382 } 383 384 public static Element PROGRAM_RASTER(RenderScript rs) { 385 if(rs.mElement_PROGRAM_RASTER == null) { 386 rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER); 387 } 388 return rs.mElement_PROGRAM_RASTER; 389 } 390 391 public static Element PROGRAM_STORE(RenderScript rs) { 392 if(rs.mElement_PROGRAM_STORE == null) { 393 rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE); 394 } 395 return rs.mElement_PROGRAM_STORE; 396 } 397 398 399 public static Element A_8(RenderScript rs) { 400 if(rs.mElement_A_8 == null) { 401 rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A); 402 } 403 return rs.mElement_A_8; 404 } 405 406 public static Element RGB_565(RenderScript rs) { 407 if(rs.mElement_RGB_565 == null) { 408 rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB); 409 } 410 return rs.mElement_RGB_565; 411 } 412 413 public static Element RGB_888(RenderScript rs) { 414 if(rs.mElement_RGB_888 == null) { 415 rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB); 416 } 417 return rs.mElement_RGB_888; 418 } 419 420 public static Element RGBA_5551(RenderScript rs) { 421 if(rs.mElement_RGBA_5551 == null) { 422 rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA); 423 } 424 return rs.mElement_RGBA_5551; 425 } 426 427 public static Element RGBA_4444(RenderScript rs) { 428 if(rs.mElement_RGBA_4444 == null) { 429 rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA); 430 } 431 return rs.mElement_RGBA_4444; 432 } 433 434 public static Element RGBA_8888(RenderScript rs) { 435 if(rs.mElement_RGBA_8888 == null) { 436 rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA); 437 } 438 return rs.mElement_RGBA_8888; 439 } 440 441 public static Element F32_2(RenderScript rs) { 442 if(rs.mElement_FLOAT_2 == null) { 443 rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2); 444 } 445 return rs.mElement_FLOAT_2; 446 } 447 448 public static Element F32_3(RenderScript rs) { 449 if(rs.mElement_FLOAT_3 == null) { 450 rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3); 451 } 452 return rs.mElement_FLOAT_3; 453 } 454 455 public static Element F32_4(RenderScript rs) { 456 if(rs.mElement_FLOAT_4 == null) { 457 rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4); 458 } 459 return rs.mElement_FLOAT_4; 460 } 461 462 public static Element F64_2(RenderScript rs) { 463 if(rs.mElement_DOUBLE_2 == null) { 464 rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2); 465 } 466 return rs.mElement_DOUBLE_2; 467 } 468 469 public static Element F64_3(RenderScript rs) { 470 if(rs.mElement_DOUBLE_3 == null) { 471 rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3); 472 } 473 return rs.mElement_DOUBLE_3; 474 } 475 476 public static Element F64_4(RenderScript rs) { 477 if(rs.mElement_DOUBLE_4 == null) { 478 rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4); 479 } 480 return rs.mElement_DOUBLE_4; 481 } 482 483 public static Element U8_2(RenderScript rs) { 484 if(rs.mElement_UCHAR_2 == null) { 485 rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2); 486 } 487 return rs.mElement_UCHAR_2; 488 } 489 490 public static Element U8_3(RenderScript rs) { 491 if(rs.mElement_UCHAR_3 == null) { 492 rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3); 493 } 494 return rs.mElement_UCHAR_3; 495 } 496 497 public static Element U8_4(RenderScript rs) { 498 if(rs.mElement_UCHAR_4 == null) { 499 rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4); 500 } 501 return rs.mElement_UCHAR_4; 502 } 503 504 public static Element I8_2(RenderScript rs) { 505 if(rs.mElement_CHAR_2 == null) { 506 rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2); 507 } 508 return rs.mElement_CHAR_2; 509 } 510 511 public static Element I8_3(RenderScript rs) { 512 if(rs.mElement_CHAR_3 == null) { 513 rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3); 514 } 515 return rs.mElement_CHAR_3; 516 } 517 518 public static Element I8_4(RenderScript rs) { 519 if(rs.mElement_CHAR_4 == null) { 520 rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4); 521 } 522 return rs.mElement_CHAR_4; 523 } 524 525 public static Element U16_2(RenderScript rs) { 526 if(rs.mElement_USHORT_2 == null) { 527 rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2); 528 } 529 return rs.mElement_USHORT_2; 530 } 531 532 public static Element U16_3(RenderScript rs) { 533 if(rs.mElement_USHORT_3 == null) { 534 rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3); 535 } 536 return rs.mElement_USHORT_3; 537 } 538 539 public static Element U16_4(RenderScript rs) { 540 if(rs.mElement_USHORT_4 == null) { 541 rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4); 542 } 543 return rs.mElement_USHORT_4; 544 } 545 546 public static Element I16_2(RenderScript rs) { 547 if(rs.mElement_SHORT_2 == null) { 548 rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2); 549 } 550 return rs.mElement_SHORT_2; 551 } 552 553 public static Element I16_3(RenderScript rs) { 554 if(rs.mElement_SHORT_3 == null) { 555 rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3); 556 } 557 return rs.mElement_SHORT_3; 558 } 559 560 public static Element I16_4(RenderScript rs) { 561 if(rs.mElement_SHORT_4 == null) { 562 rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4); 563 } 564 return rs.mElement_SHORT_4; 565 } 566 567 public static Element U32_2(RenderScript rs) { 568 if(rs.mElement_UINT_2 == null) { 569 rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2); 570 } 571 return rs.mElement_UINT_2; 572 } 573 574 public static Element U32_3(RenderScript rs) { 575 if(rs.mElement_UINT_3 == null) { 576 rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3); 577 } 578 return rs.mElement_UINT_3; 579 } 580 581 public static Element U32_4(RenderScript rs) { 582 if(rs.mElement_UINT_4 == null) { 583 rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4); 584 } 585 return rs.mElement_UINT_4; 586 } 587 588 public static Element I32_2(RenderScript rs) { 589 if(rs.mElement_INT_2 == null) { 590 rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2); 591 } 592 return rs.mElement_INT_2; 593 } 594 595 public static Element I32_3(RenderScript rs) { 596 if(rs.mElement_INT_3 == null) { 597 rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3); 598 } 599 return rs.mElement_INT_3; 600 } 601 602 public static Element I32_4(RenderScript rs) { 603 if(rs.mElement_INT_4 == null) { 604 rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4); 605 } 606 return rs.mElement_INT_4; 607 } 608 609 public static Element U64_2(RenderScript rs) { 610 if(rs.mElement_ULONG_2 == null) { 611 rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2); 612 } 613 return rs.mElement_ULONG_2; 614 } 615 616 public static Element U64_3(RenderScript rs) { 617 if(rs.mElement_ULONG_3 == null) { 618 rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3); 619 } 620 return rs.mElement_ULONG_3; 621 } 622 623 public static Element U64_4(RenderScript rs) { 624 if(rs.mElement_ULONG_4 == null) { 625 rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4); 626 } 627 return rs.mElement_ULONG_4; 628 } 629 630 public static Element I64_2(RenderScript rs) { 631 if(rs.mElement_LONG_2 == null) { 632 rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2); 633 } 634 return rs.mElement_LONG_2; 635 } 636 637 public static Element I64_3(RenderScript rs) { 638 if(rs.mElement_LONG_3 == null) { 639 rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3); 640 } 641 return rs.mElement_LONG_3; 642 } 643 644 public static Element I64_4(RenderScript rs) { 645 if(rs.mElement_LONG_4 == null) { 646 rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4); 647 } 648 return rs.mElement_LONG_4; 649 } 650 651 public static Element MATRIX_4X4(RenderScript rs) { 652 if(rs.mElement_MATRIX_4X4 == null) { 653 rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4); 654 } 655 return rs.mElement_MATRIX_4X4; 656 } 657 public static Element MATRIX4X4(RenderScript rs) { 658 return MATRIX_4X4(rs); 659 } 660 661 public static Element MATRIX_3X3(RenderScript rs) { 662 if(rs.mElement_MATRIX_3X3 == null) { 663 rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3); 664 } 665 return rs.mElement_MATRIX_3X3; 666 } 667 668 public static Element MATRIX_2X2(RenderScript rs) { 669 if(rs.mElement_MATRIX_2X2 == null) { 670 rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2); 671 } 672 return rs.mElement_MATRIX_2X2; 673 } 674 675 Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) { 676 super(id, rs); 677 mSize = 0; 678 mElements = e; 679 mElementNames = n; 680 mArraySizes = as; 681 mOffsetInBytes = new int[mElements.length]; 682 for (int ct = 0; ct < mElements.length; ct++ ) { 683 mOffsetInBytes[ct] = mSize; 684 mSize += mElements[ct].mSize * mArraySizes[ct]; 685 } 686 } 687 688 Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) { 689 super(id, rs); 690 if ((dt != DataType.UNSIGNED_5_6_5) && 691 (dt != DataType.UNSIGNED_4_4_4_4) && 692 (dt != DataType.UNSIGNED_5_5_5_1)) { 693 mSize = dt.mSize * size; 694 } else { 695 mSize = dt.mSize; 696 } 697 mType = dt; 698 mKind = dk; 699 mNormalized = norm; 700 mVectorSize = size; 701 } 702 703 Element(int id, RenderScript rs) { 704 super(id, rs); 705 } 706 707 @Override 708 void updateFromNative() { 709 super.updateFromNative(); 710 711 // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements 712 int[] dataBuffer = new int[5]; 713 mRS.nElementGetNativeData(getID(), dataBuffer); 714 715 mNormalized = dataBuffer[2] == 1 ? true : false; 716 mVectorSize = dataBuffer[3]; 717 mSize = 0; 718 for (DataType dt: DataType.values()) { 719 if(dt.mID == dataBuffer[0]){ 720 mType = dt; 721 mSize = mType.mSize * mVectorSize; 722 } 723 } 724 for (DataKind dk: DataKind.values()) { 725 if(dk.mID == dataBuffer[1]){ 726 mKind = dk; 727 } 728 } 729 730 int numSubElements = dataBuffer[4]; 731 if(numSubElements > 0) { 732 mElements = new Element[numSubElements]; 733 mElementNames = new String[numSubElements]; 734 mArraySizes = new int[numSubElements]; 735 mOffsetInBytes = new int[numSubElements]; 736 737 int[] subElementIds = new int[numSubElements]; 738 mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes); 739 for(int i = 0; i < numSubElements; i ++) { 740 mElements[i] = new Element(subElementIds[i], mRS); 741 mElements[i].updateFromNative(); 742 mOffsetInBytes[i] = mSize; 743 mSize += mElements[i].mSize * mArraySizes[i]; 744 } 745 } 746 747 } 748 749 /** 750 * Create a custom Element of the specified DataType. The DataKind will be 751 * set to USER and the vector size to 1 indicating non-vector. 752 * 753 * @param rs The context associated with the new Element. 754 * @param dt The DataType for the new element. 755 * @return Element 756 */ 757 static Element createUser(RenderScript rs, DataType dt) { 758 DataKind dk = DataKind.USER; 759 boolean norm = false; 760 int vecSize = 1; 761 int id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize); 762 return new Element(id, rs, dt, dk, norm, vecSize); 763 } 764 765 /** 766 * Create a custom vector element of the specified DataType and vector size. 767 * DataKind will be set to USER. 768 * 769 * @param rs The context associated with the new Element. 770 * @param dt The DataType for the new element. 771 * @param size Vector size for the new Element. Range 2-4 inclusive 772 * supported. 773 * 774 * @return Element 775 */ 776 public static Element createVector(RenderScript rs, DataType dt, int size) { 777 if (size < 2 || size > 4) { 778 throw new RSIllegalArgumentException("Vector size out of range 2-4."); 779 } 780 DataKind dk = DataKind.USER; 781 boolean norm = false; 782 int id = rs.nElementCreate(dt.mID, dk.mID, norm, size); 783 return new Element(id, rs, dt, dk, norm, size); 784 } 785 786 /** 787 * Create a new pixel Element type. A matching DataType and DataKind must 788 * be provided. The DataType and DataKind must contain the same number of 789 * components. Vector size will be set to 1. 790 * 791 * @param rs The context associated with the new Element. 792 * @param dt The DataType for the new element. 793 * @param dk The DataKind to specify the mapping of each component in the 794 * DataType. 795 * 796 * @return Element 797 */ 798 public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) { 799 if (!(dk == DataKind.PIXEL_L || 800 dk == DataKind.PIXEL_A || 801 dk == DataKind.PIXEL_LA || 802 dk == DataKind.PIXEL_RGB || 803 dk == DataKind.PIXEL_RGBA || 804 dk == DataKind.PIXEL_DEPTH)) { 805 throw new RSIllegalArgumentException("Unsupported DataKind"); 806 } 807 if (!(dt == DataType.UNSIGNED_8 || 808 dt == DataType.UNSIGNED_16 || 809 dt == DataType.UNSIGNED_5_6_5 || 810 dt == DataType.UNSIGNED_4_4_4_4 || 811 dt == DataType.UNSIGNED_5_5_5_1)) { 812 throw new RSIllegalArgumentException("Unsupported DataType"); 813 } 814 if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) { 815 throw new RSIllegalArgumentException("Bad kind and type combo"); 816 } 817 if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) { 818 throw new RSIllegalArgumentException("Bad kind and type combo"); 819 } 820 if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) { 821 throw new RSIllegalArgumentException("Bad kind and type combo"); 822 } 823 if (dt == DataType.UNSIGNED_16 && 824 dk != DataKind.PIXEL_DEPTH) { 825 throw new RSIllegalArgumentException("Bad kind and type combo"); 826 } 827 828 int size = 1; 829 switch (dk) { 830 case PIXEL_LA: 831 size = 2; 832 break; 833 case PIXEL_RGB: 834 size = 3; 835 break; 836 case PIXEL_RGBA: 837 size = 4; 838 break; 839 case PIXEL_DEPTH: 840 size = 2; 841 break; 842 } 843 844 boolean norm = true; 845 int id = rs.nElementCreate(dt.mID, dk.mID, norm, size); 846 return new Element(id, rs, dt, dk, norm, size); 847 } 848 849 /** 850 * Check if the current Element is compatible with another Element. 851 * Primitive Elements are compatible if they share the same underlying 852 * size and type (i.e. U8 is compatible with A_8). User-defined Elements 853 * must be equal in order to be compatible. This requires strict name 854 * equivalence for all sub-Elements (in addition to structural equivalence). 855 * 856 * @param e The Element to check compatibility with. 857 * 858 * @return boolean true if the Elements are compatible, otherwise false. 859 */ 860 public boolean isCompatible(Element e) { 861 // Try strict BaseObj equality to start with. 862 if (this.equals(e)) { 863 return true; 864 } 865 866 // Ignore mKind because it is allowed to be different (user vs. pixel). 867 // We also ignore mNormalized because it can be different. The mType 868 // field must be non-null since we require name equivalence for 869 // user-created Elements. 870 return ((mSize == e.mSize) && 871 (mType != null) && 872 (mType == e.mType) && 873 (mVectorSize == e.mVectorSize)); 874 } 875 876 /** 877 * Builder class for producing complex elements with matching field and name 878 * pairs. The builder starts empty. The order in which elements are added 879 * is retained for the layout in memory. 880 * 881 */ 882 public static class Builder { 883 RenderScript mRS; 884 Element[] mElements; 885 String[] mElementNames; 886 int[] mArraySizes; 887 int mCount; 888 889 /** 890 * Create a builder object. 891 * 892 * @param rs 893 */ 894 public Builder(RenderScript rs) { 895 mRS = rs; 896 mCount = 0; 897 mElements = new Element[8]; 898 mElementNames = new String[8]; 899 mArraySizes = new int[8]; 900 } 901 902 /** 903 * Add an array of elements to this element. 904 * 905 * @param element 906 * @param name 907 * @param arraySize 908 */ 909 public Builder add(Element element, String name, int arraySize) { 910 if (arraySize < 1) { 911 throw new RSIllegalArgumentException("Array size cannot be less than 1."); 912 } 913 if(mCount == mElements.length) { 914 Element[] e = new Element[mCount + 8]; 915 String[] s = new String[mCount + 8]; 916 int[] as = new int[mCount + 8]; 917 System.arraycopy(mElements, 0, e, 0, mCount); 918 System.arraycopy(mElementNames, 0, s, 0, mCount); 919 System.arraycopy(mArraySizes, 0, as, 0, mCount); 920 mElements = e; 921 mElementNames = s; 922 mArraySizes = as; 923 } 924 mElements[mCount] = element; 925 mElementNames[mCount] = name; 926 mArraySizes[mCount] = arraySize; 927 mCount++; 928 return this; 929 } 930 931 /** 932 * Add a single element to this Element. 933 * 934 * @param element 935 * @param name 936 */ 937 public Builder add(Element element, String name) { 938 return add(element, name, 1); 939 } 940 941 /** 942 * Create the element from this builder. 943 * 944 * 945 * @return Element 946 */ 947 public Element create() { 948 mRS.validate(); 949 Element[] ein = new Element[mCount]; 950 String[] sin = new String[mCount]; 951 int[] asin = new int[mCount]; 952 java.lang.System.arraycopy(mElements, 0, ein, 0, mCount); 953 java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount); 954 java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount); 955 956 int[] ids = new int[ein.length]; 957 for (int ct = 0; ct < ein.length; ct++ ) { 958 ids[ct] = ein[ct].getID(); 959 } 960 int id = mRS.nElementCreate2(ids, sin, asin); 961 return new Element(id, mRS, ein, sin, asin); 962 } 963 } 964} 965 966