Script.java revision 8919a441f977cb787d244aa42cc2d4dda1cbfa11
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 android.util.SparseArray; 20 21/** 22 * The parent class for all executable scripts. This should not be used by 23 * applications. 24 **/ 25public class Script extends BaseObj { 26 /** 27 * Determine if Incremental Intrinsic Support is needed 28 * 29 */ 30 private boolean mUseIncSupp; 31 protected void setIncSupp(boolean useInc) { 32 mUseIncSupp = useInc; 33 } 34 protected boolean isIncSupp() { 35 return mUseIncSupp; 36 } 37 /** 38 * An allocation for the compat context will be created when needed 39 * e.g. foreach(ain, aout), setVar(ain); 40 * 41 */ 42 long getDummyAlloc(Allocation ain) { 43 long dInElement = 0; 44 long dInType = 0; 45 long dummyAlloc = 0; 46 if (ain != null) { 47 dInElement = ain.getType().getElement().getDummyElement(mRS); 48 dInType = ain.getType().getDummyType(mRS, dInElement); 49 dummyAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType); 50 ain.setIncAllocID(dummyAlloc); 51 } 52 53 return dummyAlloc; 54 } 55 /** 56 * KernelID is an identifier for a Script + root function pair. It is used 57 * as an identifier for ScriptGroup creation. 58 * 59 * This class should not be directly created. Instead use the method in the 60 * reflected or intrinsic code "getKernelID_funcname()". 61 * 62 */ 63 public static final class KernelID extends BaseObj { 64 android.renderscript.Script.KernelID mN; 65 Script mScript; 66 int mSlot; 67 int mSig; 68 KernelID(long id, RenderScript rs, Script s, int slot, int sig) { 69 super(id, rs); 70 mScript = s; 71 mSlot = slot; 72 mSig = sig; 73 } 74 } 75 76 private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>(); 77 /** 78 * Only to be used by generated reflected classes. 79 * 80 * 81 * @param slot 82 * @param sig 83 * @param ein 84 * @param eout 85 * 86 * @return KernelID 87 */ 88 protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) { 89 KernelID k = mKIDs.get(slot); 90 if (k != null) { 91 return k; 92 } 93 94 long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp); 95 if (id == 0) { 96 throw new RSDriverException("Failed to create KernelID"); 97 } 98 99 k = new KernelID(id, mRS, this, slot, sig); 100 101 mKIDs.put(slot, k); 102 return k; 103 } 104 105 /** 106 * InvokeID is an identifier for a invoke function. It is used 107 * as an identifier for ScriptGroup creation. 108 * 109 * This class should not be directly created. Instead use the method in the 110 * reflected or intrinsic code "getInvokeID_funcname()". 111 * 112 * @hide 113 */ 114 public static final class InvokeID extends BaseObj { 115 Script mScript; 116 int mSlot; 117 InvokeID(long id, RenderScript rs, Script s, int slot) { 118 super(id, rs); 119 mScript = s; 120 mSlot = slot; 121 } 122 } 123 124 private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>(); 125 /** 126 * Only to be used by generated reflected classes. 127 */ 128 protected InvokeID createInvokeID(int slot) { 129 InvokeID i = mIIDs.get(slot); 130 if (i != null) { 131 return i; 132 } 133 134 long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot); 135 if (id == 0) { 136 throw new RSDriverException("Failed to create KernelID"); 137 } 138 139 i = new InvokeID(id, mRS, this, slot); 140 mIIDs.put(slot, i); 141 return i; 142 } 143 144 /** 145 * FieldID is an identifier for a Script + exported field pair. It is used 146 * as an identifier for ScriptGroup creation. 147 * 148 * This class should not be directly created. Instead use the method in the 149 * reflected or intrinsic code "getFieldID_funcname()". 150 * 151 */ 152 public static final class FieldID extends BaseObj { 153 android.renderscript.Script.FieldID mN; 154 Script mScript; 155 int mSlot; 156 FieldID(long id, RenderScript rs, Script s, int slot) { 157 super(id, rs); 158 mScript = s; 159 mSlot = slot; 160 } 161 } 162 163 private final SparseArray<FieldID> mFIDs = new SparseArray(); 164 /** 165 * Only to be used by generated reflected classes. 166 * 167 * @param slot 168 * @param e 169 * 170 * @return FieldID 171 */ 172 protected FieldID createFieldID(int slot, Element e) { 173 FieldID f = mFIDs.get(slot); 174 if (f != null) { 175 return f; 176 } 177 178 long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp); 179 if (id == 0) { 180 throw new RSDriverException("Failed to create FieldID"); 181 } 182 183 f = new FieldID(id, mRS, this, slot); 184 mFIDs.put(slot, f); 185 return f; 186 } 187 188 /** 189 * Only intended for use by generated reflected code. 190 * 191 * @param slot 192 */ 193 protected void invoke(int slot) { 194 mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp); 195 } 196 197 /** 198 * Only intended for use by generated reflected code. 199 * 200 * @param slot 201 * @param v 202 */ 203 protected void invoke(int slot, FieldPacker v) { 204 if (v != null) { 205 mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp); 206 } else { 207 mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp); 208 } 209 } 210 211 /** 212 * Only intended for use by generated reflected code. 213 * 214 * @param va 215 * @param slot 216 */ 217 public void bindAllocation(Allocation va, int slot) { 218 mRS.validate(); 219 if (va != null) { 220 mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp); 221 } else { 222 mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp); 223 } 224 } 225 226 public void setTimeZone(String timeZone) { 227 mRS.validate(); 228 try { 229 mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp); 230 } catch (java.io.UnsupportedEncodingException e) { 231 throw new RuntimeException(e); 232 } 233 } 234 235 236 /** 237 * Only intended for use by generated reflected code. 238 * 239 * @param slot 240 * @param ain 241 * @param aout 242 * @param v 243 */ 244 protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) { 245 if (ain == null && aout == null) { 246 throw new RSIllegalArgumentException( 247 "At least one of ain or aout is required to be non-null."); 248 } 249 long in_id = 0; 250 long out_id = 0; 251 if (ain != null) { 252 in_id = ain.getID(mRS); 253 } 254 if (aout != null) { 255 out_id = aout.getID(mRS); 256 } 257 258 byte[] params = null; 259 if (v != null) { 260 params = v.getData(); 261 } 262 263 if (mUseIncSupp) { 264 long ainInc = getDummyAlloc(ain); 265 long aoutInc = getDummyAlloc(aout); 266 mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp); 267 } else { 268 mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp); 269 } 270 } 271 272 /** 273 * Only intended for use by generated reflected code. 274 * 275 * @param slot 276 * @param ain 277 * @param aout 278 * @param v 279 * @param sc 280 */ 281 protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) { 282 if (ain == null && aout == null) { 283 throw new RSIllegalArgumentException( 284 "At least one of ain or aout is required to be non-null."); 285 } 286 287 if (sc == null) { 288 forEach(slot, ain, aout, v); 289 return; 290 } 291 long in_id = 0; 292 long out_id = 0; 293 if (ain != null) { 294 in_id = ain.getID(mRS); 295 } 296 if (aout != null) { 297 out_id = aout.getID(mRS); 298 } 299 300 byte[] params = null; 301 if (v != null) { 302 params = v.getData(); 303 } 304 if (mUseIncSupp) { 305 long ainInc = getDummyAlloc(ain); 306 long aoutInc = getDummyAlloc(aout); 307 mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp); 308 } else { 309 mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp); 310 } 311 } 312 313 Script(long id, RenderScript rs) { 314 super(id, rs); 315 mUseIncSupp = false; 316 } 317 318 /** 319 * Only intended for use by generated reflected code. 320 * 321 * @param index 322 * @param v 323 */ 324 public void setVar(int index, float v) { 325 mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp); 326 } 327 328 /** 329 * Only intended for use by generated reflected code. 330 * 331 * @param index 332 * @param v 333 */ 334 public void setVar(int index, double v) { 335 mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp); 336 } 337 338 /** 339 * Only intended for use by generated reflected code. 340 * 341 * @param index 342 * @param v 343 */ 344 public void setVar(int index, int v) { 345 mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp); 346 } 347 348 /** 349 * Only intended for use by generated reflected code. 350 * 351 * @param index 352 * @param v 353 */ 354 public void setVar(int index, long v) { 355 mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp); 356 } 357 358 /** 359 * Only intended for use by generated reflected code. 360 * 361 * @param index 362 * @param v 363 */ 364 public void setVar(int index, boolean v) { 365 mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp); 366 } 367 368 /** 369 * Only intended for use by generated reflected code. 370 * 371 * @param index 372 * @param o 373 */ 374 public void setVar(int index, BaseObj o) { 375 if (mUseIncSupp) { 376 long oInc = getDummyAlloc((Allocation)o); 377 mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp); 378 } else { 379 mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp); 380 } 381 } 382 383 /** 384 * Only intended for use by generated reflected code. 385 * 386 * @param index 387 * @param v 388 */ 389 public void setVar(int index, FieldPacker v) { 390 mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp); 391 } 392 393 /** 394 * Only intended for use by generated reflected code. 395 * 396 * @param index 397 * @param v 398 * @param e 399 * @param dims 400 */ 401 public void setVar(int index, FieldPacker v, Element e, int[] dims) { 402 if (mUseIncSupp) { 403 long dElement = e.getDummyElement(mRS); 404 mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp); 405 } else { 406 mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp); 407 } 408 } 409 410 /** 411 * Only intended for use by generated reflected code. 412 * 413 */ 414 public static class Builder { 415 RenderScript mRS; 416 417 Builder(RenderScript rs) { 418 mRS = rs; 419 } 420 } 421 422 423 /** 424 * Only intended for use by generated reflected code. 425 * 426 */ 427 public static class FieldBase { 428 protected Element mElement; 429 protected Allocation mAllocation; 430 431 protected void init(RenderScript rs, int dimx) { 432 mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT); 433 } 434 435 protected void init(RenderScript rs, int dimx, int usages) { 436 mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages); 437 } 438 439 protected FieldBase() { 440 } 441 442 public Element getElement() { 443 return mElement; 444 } 445 446 public Type getType() { 447 return mAllocation.getType(); 448 } 449 450 public Allocation getAllocation() { 451 return mAllocation; 452 } 453 454 //@Override 455 public void updateAllocation() { 456 } 457 } 458 459 460 /** 461 * Class used to specify clipping for a kernel launch. 462 * 463 */ 464 public static final class LaunchOptions { 465 private int xstart = 0; 466 private int ystart = 0; 467 private int xend = 0; 468 private int yend = 0; 469 private int zstart = 0; 470 private int zend = 0; 471 private int strategy; 472 473 /** 474 * Set the X range. If the end value is set to 0 the X dimension is not 475 * clipped. 476 * 477 * @param xstartArg Must be >= 0 478 * @param xendArg Must be >= xstartArg 479 * 480 * @return LaunchOptions 481 */ 482 public LaunchOptions setX(int xstartArg, int xendArg) { 483 if (xstartArg < 0 || xendArg <= xstartArg) { 484 throw new RSIllegalArgumentException("Invalid dimensions"); 485 } 486 xstart = xstartArg; 487 xend = xendArg; 488 return this; 489 } 490 491 /** 492 * Set the Y range. If the end value is set to 0 the Y dimension is not 493 * clipped. 494 * 495 * @param ystartArg Must be >= 0 496 * @param yendArg Must be >= ystartArg 497 * 498 * @return LaunchOptions 499 */ 500 public LaunchOptions setY(int ystartArg, int yendArg) { 501 if (ystartArg < 0 || yendArg <= ystartArg) { 502 throw new RSIllegalArgumentException("Invalid dimensions"); 503 } 504 ystart = ystartArg; 505 yend = yendArg; 506 return this; 507 } 508 509 /** 510 * Set the Z range. If the end value is set to 0 the Z dimension is not 511 * clipped. 512 * 513 * @param zstartArg Must be >= 0 514 * @param zendArg Must be >= zstartArg 515 * 516 * @return LaunchOptions 517 */ 518 public LaunchOptions setZ(int zstartArg, int zendArg) { 519 if (zstartArg < 0 || zendArg <= zstartArg) { 520 throw new RSIllegalArgumentException("Invalid dimensions"); 521 } 522 zstart = zstartArg; 523 zend = zendArg; 524 return this; 525 } 526 527 528 /** 529 * Returns the current X start 530 * 531 * @return int current value 532 */ 533 public int getXStart() { 534 return xstart; 535 } 536 /** 537 * Returns the current X end 538 * 539 * @return int current value 540 */ 541 public int getXEnd() { 542 return xend; 543 } 544 /** 545 * Returns the current Y start 546 * 547 * @return int current value 548 */ 549 public int getYStart() { 550 return ystart; 551 } 552 /** 553 * Returns the current Y end 554 * 555 * @return int current value 556 */ 557 public int getYEnd() { 558 return yend; 559 } 560 /** 561 * Returns the current Z start 562 * 563 * @return int current value 564 */ 565 public int getZStart() { 566 return zstart; 567 } 568 /** 569 * Returns the current Z end 570 * 571 * @return int current value 572 */ 573 public int getZEnd() { 574 return zend; 575 } 576 577 } 578} 579