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 17 package androidx.renderscript; 18 19 import android.util.SparseArray; 20 21 /** 22 * The parent class for all executable scripts. This should not be used by 23 * applications. 24 * 25 * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a 26 * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration 27 * guide</a> for the proposed alternatives. 28 **/ 29 @Deprecated 30 public class Script extends BaseObj { 31 /** 32 * Determine if Incremental Intrinsic Support is needed 33 * 34 */ 35 private boolean mUseIncSupp; setIncSupp(boolean useInc)36 protected void setIncSupp(boolean useInc) { 37 mUseIncSupp = useInc; 38 } isIncSupp()39 protected boolean isIncSupp() { 40 return mUseIncSupp; 41 } 42 /** 43 * An allocation for the compat context will be created when needed 44 * e.g. foreach(ain, aout), setVar(ain); 45 * 46 */ getDummyAlloc(Allocation ain)47 long getDummyAlloc(Allocation ain) { 48 long dInElement = 0; 49 long dInType = 0; 50 long placeholderAlloc = 0; 51 if (ain != null) { 52 Type inType = ain.getType(); 53 dInElement = inType.getElement().getDummyElement(mRS); 54 dInType = inType.getDummyType(mRS, dInElement); 55 int xBytesSize = inType.getX() * inType.getElement().getBytesSize(); 56 placeholderAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType, xBytesSize); 57 ain.setIncAllocID(placeholderAlloc); 58 } 59 60 return placeholderAlloc; 61 } 62 /** 63 * KernelID is an identifier for a Script + root function pair. It is used 64 * as an identifier for ScriptGroup creation. 65 * 66 * This class should not be directly created. Instead use the method in the 67 * reflected or intrinsic code "getKernelID_funcname()". 68 * 69 */ 70 public static final class KernelID extends BaseObj { 71 android.renderscript.Script.KernelID mN; 72 Script mScript; 73 int mSlot; 74 int mSig; KernelID(long id, RenderScript rs, Script s, int slot, int sig)75 KernelID(long id, RenderScript rs, Script s, int slot, int sig) { 76 super(id, rs); 77 mScript = s; 78 mSlot = slot; 79 mSig = sig; 80 } 81 } 82 83 private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>(); 84 /** 85 * Only to be used by generated reflected classes. 86 * 87 * 88 * @param slot 89 * @param sig 90 * @param ein 91 * @param eout 92 * 93 * @return KernelID 94 */ createKernelID(int slot, int sig, Element ein, Element eout)95 protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) { 96 KernelID k = mKIDs.get(slot); 97 if (k != null) { 98 return k; 99 } 100 101 long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp); 102 if (id == 0) { 103 throw new RSDriverException("Failed to create KernelID"); 104 } 105 106 k = new KernelID(id, mRS, this, slot, sig); 107 108 mKIDs.put(slot, k); 109 return k; 110 } 111 112 /** 113 * InvokeID is an identifier for a invoke function. It is used 114 * as an identifier for ScriptGroup creation. 115 * 116 * This class should not be directly created. Instead use the method in the 117 * reflected or intrinsic code "getInvokeID_funcname()". 118 * 119 */ 120 public static final class InvokeID extends BaseObj { 121 Script mScript; 122 int mSlot; InvokeID(long id, RenderScript rs, Script s, int slot)123 InvokeID(long id, RenderScript rs, Script s, int slot) { 124 super(id, rs); 125 mScript = s; 126 mSlot = slot; 127 } 128 } 129 130 private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>(); 131 /** 132 * Only to be used by generated reflected classes. 133 */ createInvokeID(int slot)134 protected InvokeID createInvokeID(int slot) { 135 InvokeID i = mIIDs.get(slot); 136 if (i != null) { 137 return i; 138 } 139 140 long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot); 141 if (id == 0) { 142 throw new RSDriverException("Failed to create KernelID"); 143 } 144 145 i = new InvokeID(id, mRS, this, slot); 146 mIIDs.put(slot, i); 147 return i; 148 } 149 150 /** 151 * FieldID is an identifier for a Script + exported field pair. It is used 152 * as an identifier for ScriptGroup creation. 153 * 154 * This class should not be directly created. Instead use the method in the 155 * reflected or intrinsic code "getFieldID_funcname()". 156 * 157 */ 158 public static final class FieldID extends BaseObj { 159 android.renderscript.Script.FieldID mN; 160 Script mScript; 161 int mSlot; FieldID(long id, RenderScript rs, Script s, int slot)162 FieldID(long id, RenderScript rs, Script s, int slot) { 163 super(id, rs); 164 mScript = s; 165 mSlot = slot; 166 } 167 } 168 169 private final SparseArray<FieldID> mFIDs = new SparseArray(); 170 /** 171 * Only to be used by generated reflected classes. 172 * 173 * @param slot 174 * @param e 175 * 176 * @return FieldID 177 */ createFieldID(int slot, Element e)178 protected FieldID createFieldID(int slot, Element e) { 179 FieldID f = mFIDs.get(slot); 180 if (f != null) { 181 return f; 182 } 183 184 long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp); 185 if (id == 0) { 186 throw new RSDriverException("Failed to create FieldID"); 187 } 188 189 f = new FieldID(id, mRS, this, slot); 190 mFIDs.put(slot, f); 191 return f; 192 } 193 194 /** 195 * Only intended for use by generated reflected code. 196 * 197 * @param slot 198 */ invoke(int slot)199 protected void invoke(int slot) { 200 mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp); 201 } 202 203 /** 204 * Only intended for use by generated reflected code. 205 * 206 * @param slot 207 * @param v 208 */ invoke(int slot, FieldPacker v)209 protected void invoke(int slot, FieldPacker v) { 210 if (v != null) { 211 mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp); 212 } else { 213 mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp); 214 } 215 } 216 217 /** 218 * Only intended for use by generated reflected code. 219 * 220 * @param va 221 * @param slot 222 */ bindAllocation(Allocation va, int slot)223 public void bindAllocation(Allocation va, int slot) { 224 mRS.validate(); 225 if (va != null) { 226 mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp); 227 } else { 228 mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp); 229 } 230 } 231 setTimeZone(String timeZone)232 public void setTimeZone(String timeZone) { 233 mRS.validate(); 234 try { 235 mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp); 236 } catch (java.io.UnsupportedEncodingException e) { 237 throw new RuntimeException(e); 238 } 239 } 240 241 242 /** 243 * Only intended for use by generated reflected code. 244 * 245 * @param slot 246 * @param ain 247 * @param aout 248 * @param v 249 */ forEach(int slot, Allocation ain, Allocation aout, FieldPacker v)250 protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) { 251 if (ain == null && aout == null) { 252 throw new RSIllegalArgumentException( 253 "At least one of ain or aout is required to be non-null."); 254 } 255 long in_id = 0; 256 long out_id = 0; 257 if (ain != null) { 258 in_id = ain.getID(mRS); 259 } 260 if (aout != null) { 261 out_id = aout.getID(mRS); 262 } 263 264 byte[] params = null; 265 if (v != null) { 266 params = v.getData(); 267 } 268 269 if (mUseIncSupp) { 270 long ainInc = getDummyAlloc(ain); 271 long aoutInc = getDummyAlloc(aout); 272 mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp); 273 } else { 274 mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp); 275 } 276 } 277 278 /** 279 * Only intended for use by generated reflected code. 280 * 281 * @param slot 282 * @param ain 283 * @param aout 284 * @param v 285 * @param sc 286 */ forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc)287 protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) { 288 if (ain == null && aout == null) { 289 throw new RSIllegalArgumentException( 290 "At least one of ain or aout is required to be non-null."); 291 } 292 293 if (sc == null) { 294 forEach(slot, ain, aout, v); 295 return; 296 } 297 long in_id = 0; 298 long out_id = 0; 299 if (ain != null) { 300 in_id = ain.getID(mRS); 301 } 302 if (aout != null) { 303 out_id = aout.getID(mRS); 304 } 305 306 byte[] params = null; 307 if (v != null) { 308 params = v.getData(); 309 } 310 if (mUseIncSupp) { 311 long ainInc = getDummyAlloc(ain); 312 long aoutInc = getDummyAlloc(aout); 313 mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp); 314 } else { 315 mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp); 316 } 317 } 318 Script(long id, RenderScript rs)319 Script(long id, RenderScript rs) { 320 super(id, rs); 321 mUseIncSupp = false; 322 } 323 324 /** 325 * Only intended for use by generated reflected code. 326 * 327 * @hide 328 */ forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v)329 protected void forEach(int slot, Allocation[] ains, Allocation aout, 330 FieldPacker v) { 331 forEach(slot, ains, aout, v, null); 332 } 333 334 /** 335 * Only intended for use by generated reflected code. 336 * 337 * @hide 338 */ forEach(int slot, Allocation[] ains, Allocation aout, FieldPacker v, LaunchOptions sc)339 protected void forEach(int slot, Allocation[] ains, Allocation aout, 340 FieldPacker v, LaunchOptions sc) { 341 // TODO: Is this necessary if nScriptForEach calls validate as well? 342 mRS.validate(); 343 if (ains != null) { 344 for (Allocation ain : ains) { 345 mRS.validateObject(ain); 346 } 347 } 348 mRS.validateObject(aout); 349 350 if (ains == null && aout == null) { 351 throw new RSIllegalArgumentException( 352 "At least one of ain or aout is required to be non-null."); 353 } 354 355 long[] in_ids; 356 if (ains != null) { 357 in_ids = new long[ains.length]; 358 for (int index = 0; index < ains.length; ++index) { 359 in_ids[index] = ains[index].getID(mRS); 360 } 361 } else { 362 in_ids = null; 363 } 364 365 long out_id = 0; 366 if (aout != null) { 367 out_id = aout.getID(mRS); 368 } 369 370 byte[] params = null; 371 if (v != null) { 372 params = v.getData(); 373 } 374 375 int[] limits = null; 376 if (sc != null) { 377 limits = new int[6]; 378 379 limits[0] = sc.xstart; 380 limits[1] = sc.xend; 381 limits[2] = sc.ystart; 382 limits[3] = sc.yend; 383 limits[4] = sc.zstart; 384 limits[5] = sc.zend; 385 } 386 387 mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits); 388 } 389 390 /** 391 * Only intended for use by generated reflected code. (General reduction) 392 * 393 * @hide 394 */ reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc)395 protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) { 396 mRS.validate(); 397 if (ains == null || ains.length < 1) { 398 throw new RSIllegalArgumentException( 399 "At least one input is required."); 400 } 401 if (aout == null) { 402 throw new RSIllegalArgumentException( 403 "aout is required to be non-null."); 404 } 405 for (Allocation ain : ains) { 406 mRS.validateObject(ain); 407 } 408 409 long[] in_ids = new long[ains.length]; 410 for (int index = 0; index < ains.length; ++index) { 411 in_ids[index] = ains[index].getID(mRS); 412 } 413 long out_id = aout.getID(mRS); 414 415 int[] limits = null; 416 if (sc != null) { 417 limits = new int[6]; 418 419 limits[0] = sc.xstart; 420 limits[1] = sc.xend; 421 limits[2] = sc.ystart; 422 limits[3] = sc.yend; 423 limits[4] = sc.zstart; 424 limits[5] = sc.zend; 425 } 426 427 mRS.nScriptReduce(getID(mRS), slot, in_ids, out_id, limits); 428 } 429 430 /** 431 * Only intended for use by generated reflected code. 432 * 433 * @param index 434 * @param v 435 */ setVar(int index, float v)436 public void setVar(int index, float v) { 437 mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp); 438 } 439 440 /** 441 * Only intended for use by generated reflected code. 442 * 443 * @param index 444 * @param v 445 */ setVar(int index, double v)446 public void setVar(int index, double v) { 447 mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp); 448 } 449 450 /** 451 * Only intended for use by generated reflected code. 452 * 453 * @param index 454 * @param v 455 */ setVar(int index, int v)456 public void setVar(int index, int v) { 457 mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp); 458 } 459 460 /** 461 * Only intended for use by generated reflected code. 462 * 463 * @param index 464 * @param v 465 */ setVar(int index, long v)466 public void setVar(int index, long v) { 467 mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp); 468 } 469 470 /** 471 * Only intended for use by generated reflected code. 472 * 473 * @param index 474 * @param v 475 */ setVar(int index, boolean v)476 public void setVar(int index, boolean v) { 477 mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp); 478 } 479 480 /** 481 * Only intended for use by generated reflected code. 482 * 483 * @param index 484 * @param o 485 */ setVar(int index, BaseObj o)486 public void setVar(int index, BaseObj o) { 487 if (mUseIncSupp) { 488 long oInc = getDummyAlloc((Allocation)o); 489 mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp); 490 } else { 491 mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp); 492 } 493 } 494 495 /** 496 * Only intended for use by generated reflected code. 497 * 498 * @param index 499 * @param v 500 */ setVar(int index, FieldPacker v)501 public void setVar(int index, FieldPacker v) { 502 mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp); 503 } 504 505 /** 506 * Only intended for use by generated reflected code. 507 * 508 * @param index 509 * @param v 510 * @param e 511 * @param dims 512 */ setVar(int index, FieldPacker v, Element e, int[] dims)513 public void setVar(int index, FieldPacker v, Element e, int[] dims) { 514 if (mUseIncSupp) { 515 long dElement = e.getDummyElement(mRS); 516 mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp); 517 } else { 518 mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp); 519 } 520 } 521 522 /** 523 * Only intended for use by generated reflected code. 524 * 525 */ 526 public static class Builder { 527 RenderScript mRS; 528 Builder(RenderScript rs)529 Builder(RenderScript rs) { 530 mRS = rs; 531 } 532 } 533 534 535 /** 536 * Only intended for use by generated reflected code. 537 * 538 */ 539 public static class FieldBase { 540 protected Element mElement; 541 protected Allocation mAllocation; 542 init(RenderScript rs, int dimx)543 protected void init(RenderScript rs, int dimx) { 544 mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT); 545 } 546 init(RenderScript rs, int dimx, int usages)547 protected void init(RenderScript rs, int dimx, int usages) { 548 mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages); 549 } 550 FieldBase()551 protected FieldBase() { 552 } 553 getElement()554 public Element getElement() { 555 return mElement; 556 } 557 getType()558 public Type getType() { 559 return mAllocation.getType(); 560 } 561 getAllocation()562 public Allocation getAllocation() { 563 return mAllocation; 564 } 565 566 //@Override updateAllocation()567 public void updateAllocation() { 568 } 569 } 570 571 572 /** 573 * Class for specifying the specifics about how a kernel will be 574 * launched. 575 * 576 * This class can specify a potential range of cells on which to 577 * run a kernel. If no set is called for a dimension then this 578 * class will have no impact on that dimension when the kernel 579 * is executed. 580 * 581 * The forEach kernel launch will operate over the intersection of 582 * the dimensions. 583 * 584 * Example: 585 * LaunchOptions with setX(5, 15) 586 * Allocation with dimension X=10, Y=10 587 * The resulting forEach run would execute over: 588 * x = 5 to 9 (inclusive) and 589 * y = 0 to 9 (inclusive). 590 * 591 */ 592 public static final class LaunchOptions { 593 private int xstart = 0; 594 private int ystart = 0; 595 private int xend = 0; 596 private int yend = 0; 597 private int zstart = 0; 598 private int zend = 0; 599 private int strategy; 600 601 /** 602 * Set the X range. xstartArg is the lowest coordinate of the range, 603 * and xendArg-1 is the highest coordinate of the range. 604 * 605 * @param xstartArg Must be >= 0 606 * @param xendArg Must be > xstartArg 607 * 608 * @return LaunchOptions 609 */ setX(int xstartArg, int xendArg)610 public LaunchOptions setX(int xstartArg, int xendArg) { 611 if (xstartArg < 0 || xendArg <= xstartArg) { 612 throw new RSIllegalArgumentException("Invalid dimensions"); 613 } 614 xstart = xstartArg; 615 xend = xendArg; 616 return this; 617 } 618 619 /** 620 * Set the Y range. ystartArg is the lowest coordinate of the range, 621 * and yendArg-1 is the highest coordinate of the range. 622 * 623 * @param ystartArg Must be >= 0 624 * @param yendArg Must be > ystartArg 625 * 626 * @return LaunchOptions 627 */ setY(int ystartArg, int yendArg)628 public LaunchOptions setY(int ystartArg, int yendArg) { 629 if (ystartArg < 0 || yendArg <= ystartArg) { 630 throw new RSIllegalArgumentException("Invalid dimensions"); 631 } 632 ystart = ystartArg; 633 yend = yendArg; 634 return this; 635 } 636 637 /** 638 * Set the Z range. zstartArg is the lowest coordinate of the range, 639 * and zendArg-1 is the highest coordinate of the range. 640 * 641 * @param zstartArg Must be >= 0 642 * @param zendArg Must be > zstartArg 643 * 644 * @return LaunchOptions 645 */ setZ(int zstartArg, int zendArg)646 public LaunchOptions setZ(int zstartArg, int zendArg) { 647 if (zstartArg < 0 || zendArg <= zstartArg) { 648 throw new RSIllegalArgumentException("Invalid dimensions"); 649 } 650 zstart = zstartArg; 651 zend = zendArg; 652 return this; 653 } 654 655 656 /** 657 * Returns the current X start 658 * 659 * @return int current value 660 */ getXStart()661 public int getXStart() { 662 return xstart; 663 } 664 /** 665 * Returns the current X end 666 * 667 * @return int current value 668 */ getXEnd()669 public int getXEnd() { 670 return xend; 671 } 672 /** 673 * Returns the current Y start 674 * 675 * @return int current value 676 */ getYStart()677 public int getYStart() { 678 return ystart; 679 } 680 /** 681 * Returns the current Y end 682 * 683 * @return int current value 684 */ getYEnd()685 public int getYEnd() { 686 return yend; 687 } 688 /** 689 * Returns the current Z start 690 * 691 * @return int current value 692 */ getZStart()693 public int getZStart() { 694 return zstart; 695 } 696 /** 697 * Returns the current Z end 698 * 699 * @return int current value 700 */ getZEnd()701 public int getZEnd() { 702 return zend; 703 } 704 705 } 706 } 707