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