Home | History | Annotate | Download | only in renderscript
      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