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