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