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