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