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