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
17package android.renderscript;
18
19import java.io.File;
20import java.lang.reflect.Field;
21
22import android.content.Context;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageManager;
25import android.content.res.AssetManager;
26import android.graphics.Bitmap;
27import android.graphics.BitmapFactory;
28import android.graphics.SurfaceTexture;
29import android.os.Process;
30import android.util.Log;
31import android.view.Surface;
32
33
34
35/**
36 * Renderscript base master class.  An instance of this class creates native
37 * worker threads for processing commands from this object.  This base class
38 * does not provide any extended capabilities beyond simple data processing.
39 * For extended capabilities use derived classes such as RenderScriptGL.
40 *
41 * <div class="special reference">
42 * <h3>Developer Guides</h3>
43 * <p>For more information about creating an application that uses Renderscript, read the
44 * <a href="{@docRoot}guide/topics/renderscript/index.html">Renderscript</a> developer guide.</p>
45 * </div>
46 **/
47public class RenderScript {
48    static final String LOG_TAG = "RenderScript_jni";
49    static final boolean DEBUG  = false;
50    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
51    static final boolean LOG_ENABLED = false;
52
53    private Context mApplicationContext;
54
55    /*
56     * We use a class initializer to allow the native code to cache some
57     * field offsets.
58     */
59    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
60    static boolean sInitialized;
61    native static void _nInit();
62
63
64    static {
65        sInitialized = false;
66        try {
67            System.loadLibrary("rs_jni");
68            _nInit();
69            sInitialized = true;
70        } catch (UnsatisfiedLinkError e) {
71            Log.e(LOG_TAG, "Error loading RS jni library: " + e);
72            throw new RSRuntimeException("Error loading RS jni library: " + e);
73        }
74    }
75
76    // Non-threadsafe functions.
77    native int  nDeviceCreate();
78    native void nDeviceDestroy(int dev);
79    native void nDeviceSetConfig(int dev, int param, int value);
80    native int nContextGetUserMessage(int con, int[] data);
81    native String nContextGetErrorMessage(int con);
82    native int  nContextPeekMessage(int con, int[] subID);
83    native void nContextInitToClient(int con);
84    native void nContextDeinitToClient(int con);
85
86    /**
87     * Name of the file that holds the object cache.
88     */
89    private static final String CACHE_PATH = "com.android.renderscript.cache";
90    static String mCachePath;
91
92     /**
93     * Sets the directory to use as a persistent storage for the
94     * renderscript object file cache.
95     *
96     * @hide
97     * @param cacheDir A directory the current process can write to
98     */
99    public static void setupDiskCache(File cacheDir) {
100        File f = new File(cacheDir, CACHE_PATH);
101        mCachePath = f.getAbsolutePath();
102        f.mkdirs();
103    }
104
105
106    // Methods below are wrapped to protect the non-threadsafe
107    // lockless fifo.
108    native int  rsnContextCreateGL(int dev, int ver, int sdkVer,
109                 int colorMin, int colorPref,
110                 int alphaMin, int alphaPref,
111                 int depthMin, int depthPref,
112                 int stencilMin, int stencilPref,
113                 int samplesMin, int samplesPref, float samplesQ, int dpi);
114    synchronized int nContextCreateGL(int dev, int ver, int sdkVer,
115                 int colorMin, int colorPref,
116                 int alphaMin, int alphaPref,
117                 int depthMin, int depthPref,
118                 int stencilMin, int stencilPref,
119                 int samplesMin, int samplesPref, float samplesQ, int dpi) {
120        return rsnContextCreateGL(dev, ver, sdkVer, colorMin, colorPref,
121                                  alphaMin, alphaPref, depthMin, depthPref,
122                                  stencilMin, stencilPref,
123                                  samplesMin, samplesPref, samplesQ, dpi);
124    }
125    native int  rsnContextCreate(int dev, int ver, int sdkVer);
126    synchronized int nContextCreate(int dev, int ver, int sdkVer) {
127        return rsnContextCreate(dev, ver, sdkVer);
128    }
129    native void rsnContextDestroy(int con);
130    synchronized void nContextDestroy() {
131        validate();
132        rsnContextDestroy(mContext);
133    }
134    native void rsnContextSetSurface(int con, int w, int h, Surface sur);
135    synchronized void nContextSetSurface(int w, int h, Surface sur) {
136        validate();
137        rsnContextSetSurface(mContext, w, h, sur);
138    }
139    native void rsnContextSetSurfaceTexture(int con, int w, int h, SurfaceTexture sur);
140    synchronized void nContextSetSurfaceTexture(int w, int h, SurfaceTexture sur) {
141        validate();
142        rsnContextSetSurfaceTexture(mContext, w, h, sur);
143    }
144    native void rsnContextSetPriority(int con, int p);
145    synchronized void nContextSetPriority(int p) {
146        validate();
147        rsnContextSetPriority(mContext, p);
148    }
149    native void rsnContextDump(int con, int bits);
150    synchronized void nContextDump(int bits) {
151        validate();
152        rsnContextDump(mContext, bits);
153    }
154    native void rsnContextFinish(int con);
155    synchronized void nContextFinish() {
156        validate();
157        rsnContextFinish(mContext);
158    }
159
160    native void rsnContextBindRootScript(int con, int script);
161    synchronized void nContextBindRootScript(int script) {
162        validate();
163        rsnContextBindRootScript(mContext, script);
164    }
165    native void rsnContextBindSampler(int con, int sampler, int slot);
166    synchronized void nContextBindSampler(int sampler, int slot) {
167        validate();
168        rsnContextBindSampler(mContext, sampler, slot);
169    }
170    native void rsnContextBindProgramStore(int con, int pfs);
171    synchronized void nContextBindProgramStore(int pfs) {
172        validate();
173        rsnContextBindProgramStore(mContext, pfs);
174    }
175    native void rsnContextBindProgramFragment(int con, int pf);
176    synchronized void nContextBindProgramFragment(int pf) {
177        validate();
178        rsnContextBindProgramFragment(mContext, pf);
179    }
180    native void rsnContextBindProgramVertex(int con, int pv);
181    synchronized void nContextBindProgramVertex(int pv) {
182        validate();
183        rsnContextBindProgramVertex(mContext, pv);
184    }
185    native void rsnContextBindProgramRaster(int con, int pr);
186    synchronized void nContextBindProgramRaster(int pr) {
187        validate();
188        rsnContextBindProgramRaster(mContext, pr);
189    }
190    native void rsnContextPause(int con);
191    synchronized void nContextPause() {
192        validate();
193        rsnContextPause(mContext);
194    }
195    native void rsnContextResume(int con);
196    synchronized void nContextResume() {
197        validate();
198        rsnContextResume(mContext);
199    }
200
201    native void rsnAssignName(int con, int obj, byte[] name);
202    synchronized void nAssignName(int obj, byte[] name) {
203        validate();
204        rsnAssignName(mContext, obj, name);
205    }
206    native String rsnGetName(int con, int obj);
207    synchronized String nGetName(int obj) {
208        validate();
209        return rsnGetName(mContext, obj);
210    }
211    native void rsnObjDestroy(int con, int id);
212    synchronized void nObjDestroy(int id) {
213        // There is a race condition here.  The calling code may be run
214        // by the gc while teardown is occuring.  This protects againts
215        // deleting dead objects.
216        if (mContext != 0) {
217            rsnObjDestroy(mContext, id);
218        }
219    }
220
221    native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
222    synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
223        validate();
224        return rsnElementCreate(mContext, type, kind, norm, vecSize);
225    }
226    native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
227    synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
228        validate();
229        return rsnElementCreate2(mContext, elements, names, arraySizes);
230    }
231    native void rsnElementGetNativeData(int con, int id, int[] elementData);
232    synchronized void nElementGetNativeData(int id, int[] elementData) {
233        validate();
234        rsnElementGetNativeData(mContext, id, elementData);
235    }
236    native void rsnElementGetSubElements(int con, int id,
237                                         int[] IDs, String[] names, int[] arraySizes);
238    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
239        validate();
240        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
241    }
242
243    native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
244    synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces) {
245        validate();
246        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces);
247    }
248    native void rsnTypeGetNativeData(int con, int id, int[] typeData);
249    synchronized void nTypeGetNativeData(int id, int[] typeData) {
250        validate();
251        rsnTypeGetNativeData(mContext, id, typeData);
252    }
253
254    native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
255    synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
256        validate();
257        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
258    }
259    native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
260    synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
261        validate();
262        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
263    }
264    native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
265    synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
266        validate();
267        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
268    }
269    native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
270    synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
271        validate();
272        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
273    }
274    native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
275    synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
276        validate();
277        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
278    }
279
280    native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
281    synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
282        validate();
283        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
284    }
285
286
287    native void rsnAllocationSyncAll(int con, int alloc, int src);
288    synchronized void nAllocationSyncAll(int alloc, int src) {
289        validate();
290        rsnAllocationSyncAll(mContext, alloc, src);
291    }
292    native int rsnAllocationGetSurfaceTextureID(int con, int alloc);
293    synchronized int nAllocationGetSurfaceTextureID(int alloc) {
294        validate();
295        return rsnAllocationGetSurfaceTextureID(mContext, alloc);
296    }
297    native void rsnAllocationGetSurfaceTextureID2(int con, int alloc, SurfaceTexture st);
298    synchronized void nAllocationGetSurfaceTextureID2(int alloc, SurfaceTexture st) {
299        validate();
300        rsnAllocationGetSurfaceTextureID2(mContext, alloc, st);
301    }
302    native void rsnAllocationSetSurface(int con, int alloc, Surface sur);
303    synchronized void nAllocationSetSurface(int alloc, Surface sur) {
304        validate();
305        rsnAllocationSetSurface(mContext, alloc, sur);
306    }
307    native void rsnAllocationIoSend(int con, int alloc);
308    synchronized void nAllocationIoSend(int alloc) {
309        validate();
310        rsnAllocationIoSend(mContext, alloc);
311    }
312    native void rsnAllocationIoReceive(int con, int alloc);
313    synchronized void nAllocationIoReceive(int alloc) {
314        validate();
315        rsnAllocationIoReceive(mContext, alloc);
316    }
317
318
319    native void rsnAllocationGenerateMipmaps(int con, int alloc);
320    synchronized void nAllocationGenerateMipmaps(int alloc) {
321        validate();
322        rsnAllocationGenerateMipmaps(mContext, alloc);
323    }
324    native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
325    synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
326        validate();
327        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
328    }
329
330
331    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
332    synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
333        validate();
334        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
335    }
336    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
337    synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
338        validate();
339        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
340    }
341    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
342    synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
343        validate();
344        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
345    }
346    native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
347    synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
348        validate();
349        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
350    }
351
352    native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
353    synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
354        validate();
355        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
356    }
357
358    native void rsnAllocationData2D(int con,
359                                    int dstAlloc, int dstXoff, int dstYoff,
360                                    int dstMip, int dstFace,
361                                    int width, int height,
362                                    int srcAlloc, int srcXoff, int srcYoff,
363                                    int srcMip, int srcFace);
364    synchronized void nAllocationData2D(int dstAlloc, int dstXoff, int dstYoff,
365                                        int dstMip, int dstFace,
366                                        int width, int height,
367                                        int srcAlloc, int srcXoff, int srcYoff,
368                                        int srcMip, int srcFace) {
369        validate();
370        rsnAllocationData2D(mContext,
371                            dstAlloc, dstXoff, dstYoff,
372                            dstMip, dstFace,
373                            width, height,
374                            srcAlloc, srcXoff, srcYoff,
375                            srcMip, srcFace);
376    }
377
378    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
379    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
380        validate();
381        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
382    }
383    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
384    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
385        validate();
386        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
387    }
388    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
389    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
390        validate();
391        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
392    }
393    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
394    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
395        validate();
396        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
397    }
398    native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
399    synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
400        validate();
401        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
402    }
403
404    native void rsnAllocationRead(int con, int id, byte[] d);
405    synchronized void nAllocationRead(int id, byte[] d) {
406        validate();
407        rsnAllocationRead(mContext, id, d);
408    }
409    native void rsnAllocationRead(int con, int id, short[] d);
410    synchronized void nAllocationRead(int id, short[] d) {
411        validate();
412        rsnAllocationRead(mContext, id, d);
413    }
414    native void rsnAllocationRead(int con, int id, int[] d);
415    synchronized void nAllocationRead(int id, int[] d) {
416        validate();
417        rsnAllocationRead(mContext, id, d);
418    }
419    native void rsnAllocationRead(int con, int id, float[] d);
420    synchronized void nAllocationRead(int id, float[] d) {
421        validate();
422        rsnAllocationRead(mContext, id, d);
423    }
424    native int  rsnAllocationGetType(int con, int id);
425    synchronized int nAllocationGetType(int id) {
426        validate();
427        return rsnAllocationGetType(mContext, id);
428    }
429
430    native void rsnAllocationResize1D(int con, int id, int dimX);
431    synchronized void nAllocationResize1D(int id, int dimX) {
432        validate();
433        rsnAllocationResize1D(mContext, id, dimX);
434    }
435    native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
436    synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
437        validate();
438        rsnAllocationResize2D(mContext, id, dimX, dimY);
439    }
440
441    native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
442    synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
443        validate();
444        return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
445    }
446    native int  rsnFileA3DCreateFromFile(int con, String path);
447    synchronized int nFileA3DCreateFromFile(String path) {
448        validate();
449        return rsnFileA3DCreateFromFile(mContext, path);
450    }
451    native int  rsnFileA3DCreateFromAsset(int con, AssetManager mgr, String path);
452    synchronized int nFileA3DCreateFromAsset(AssetManager mgr, String path) {
453        validate();
454        return rsnFileA3DCreateFromAsset(mContext, mgr, path);
455    }
456    native int  rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
457    synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
458        validate();
459        return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
460    }
461    native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
462    synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
463        validate();
464        rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
465    }
466    native int  rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
467    synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
468        validate();
469        return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
470    }
471
472    native int  rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
473    synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
474        validate();
475        return rsnFontCreateFromFile(mContext, fileName, size, dpi);
476    }
477    native int  rsnFontCreateFromAssetStream(int con, String name, float size, int dpi, int assetStream);
478    synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
479        validate();
480        return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
481    }
482    native int  rsnFontCreateFromAsset(int con, AssetManager mgr, String path, float size, int dpi);
483    synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
484        validate();
485        return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
486    }
487
488
489    native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
490    synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
491        validate();
492        rsnScriptBindAllocation(mContext, script, alloc, slot);
493    }
494    native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
495    synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
496        validate();
497        rsnScriptSetTimeZone(mContext, script, timeZone);
498    }
499    native void rsnScriptInvoke(int con, int id, int slot);
500    synchronized void nScriptInvoke(int id, int slot) {
501        validate();
502        rsnScriptInvoke(mContext, id, slot);
503    }
504    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
505    native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
506    synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
507        validate();
508        if (params == null) {
509            rsnScriptForEach(mContext, id, slot, ain, aout);
510        } else {
511            rsnScriptForEach(mContext, id, slot, ain, aout, params);
512        }
513    }
514    native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
515    synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
516        validate();
517        rsnScriptInvokeV(mContext, id, slot, params);
518    }
519    native void rsnScriptSetVarI(int con, int id, int slot, int val);
520    synchronized void nScriptSetVarI(int id, int slot, int val) {
521        validate();
522        rsnScriptSetVarI(mContext, id, slot, val);
523    }
524    native void rsnScriptSetVarJ(int con, int id, int slot, long val);
525    synchronized void nScriptSetVarJ(int id, int slot, long val) {
526        validate();
527        rsnScriptSetVarJ(mContext, id, slot, val);
528    }
529    native void rsnScriptSetVarF(int con, int id, int slot, float val);
530    synchronized void nScriptSetVarF(int id, int slot, float val) {
531        validate();
532        rsnScriptSetVarF(mContext, id, slot, val);
533    }
534    native void rsnScriptSetVarD(int con, int id, int slot, double val);
535    synchronized void nScriptSetVarD(int id, int slot, double val) {
536        validate();
537        rsnScriptSetVarD(mContext, id, slot, val);
538    }
539    native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
540    synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
541        validate();
542        rsnScriptSetVarV(mContext, id, slot, val);
543    }
544    native void rsnScriptSetVarVE(int con, int id, int slot, byte[] val,
545                                  int e, int[] dims);
546    synchronized void nScriptSetVarVE(int id, int slot, byte[] val,
547                                      int e, int[] dims) {
548        validate();
549        rsnScriptSetVarVE(mContext, id, slot, val, e, dims);
550    }
551    native void rsnScriptSetVarObj(int con, int id, int slot, int val);
552    synchronized void nScriptSetVarObj(int id, int slot, int val) {
553        validate();
554        rsnScriptSetVarObj(mContext, id, slot, val);
555    }
556
557    native int  rsnScriptCCreate(int con, String resName, String cacheDir,
558                                 byte[] script, int length);
559    synchronized int nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
560        validate();
561        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
562    }
563
564    native int  rsnScriptIntrinsicCreate(int con, int id, int eid);
565    synchronized int nScriptIntrinsicCreate(int id, int eid) {
566        validate();
567        return rsnScriptIntrinsicCreate(mContext, id, eid);
568    }
569
570    native int  rsnScriptKernelIDCreate(int con, int sid, int slot, int sig);
571    synchronized int nScriptKernelIDCreate(int sid, int slot, int sig) {
572        validate();
573        return rsnScriptKernelIDCreate(mContext, sid, slot, sig);
574    }
575
576    native int  rsnScriptFieldIDCreate(int con, int sid, int slot);
577    synchronized int nScriptFieldIDCreate(int sid, int slot) {
578        validate();
579        return rsnScriptFieldIDCreate(mContext, sid, slot);
580    }
581
582    native int  rsnScriptGroupCreate(int con, int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types);
583    synchronized int nScriptGroupCreate(int[] kernels, int[] src, int[] dstk, int[] dstf, int[] types) {
584        validate();
585        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
586    }
587
588    native void rsnScriptGroupSetInput(int con, int group, int kernel, int alloc);
589    synchronized void nScriptGroupSetInput(int group, int kernel, int alloc) {
590        validate();
591        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
592    }
593
594    native void rsnScriptGroupSetOutput(int con, int group, int kernel, int alloc);
595    synchronized void nScriptGroupSetOutput(int group, int kernel, int alloc) {
596        validate();
597        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
598    }
599
600    native void rsnScriptGroupExecute(int con, int group);
601    synchronized void nScriptGroupExecute(int group) {
602        validate();
603        rsnScriptGroupExecute(mContext, group);
604    }
605
606    native int  rsnSamplerCreate(int con, int magFilter, int minFilter,
607                                 int wrapS, int wrapT, int wrapR, float aniso);
608    synchronized int nSamplerCreate(int magFilter, int minFilter,
609                                 int wrapS, int wrapT, int wrapR, float aniso) {
610        validate();
611        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
612    }
613
614    native int  rsnProgramStoreCreate(int con, boolean r, boolean g, boolean b, boolean a,
615                                      boolean depthMask, boolean dither,
616                                      int srcMode, int dstMode, int depthFunc);
617    synchronized int nProgramStoreCreate(boolean r, boolean g, boolean b, boolean a,
618                                         boolean depthMask, boolean dither,
619                                         int srcMode, int dstMode, int depthFunc) {
620        validate();
621        return rsnProgramStoreCreate(mContext, r, g, b, a, depthMask, dither, srcMode,
622                                     dstMode, depthFunc);
623    }
624
625    native int  rsnProgramRasterCreate(int con, boolean pointSprite, int cullMode);
626    synchronized int nProgramRasterCreate(boolean pointSprite, int cullMode) {
627        validate();
628        return rsnProgramRasterCreate(mContext, pointSprite, cullMode);
629    }
630
631    native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
632    synchronized void nProgramBindConstants(int pv, int slot, int mID) {
633        validate();
634        rsnProgramBindConstants(mContext, pv, slot, mID);
635    }
636    native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
637    synchronized void nProgramBindTexture(int vpf, int slot, int a) {
638        validate();
639        rsnProgramBindTexture(mContext, vpf, slot, a);
640    }
641    native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
642    synchronized void nProgramBindSampler(int vpf, int slot, int s) {
643        validate();
644        rsnProgramBindSampler(mContext, vpf, slot, s);
645    }
646    native int  rsnProgramFragmentCreate(int con, String shader, String[] texNames, int[] params);
647    synchronized int nProgramFragmentCreate(String shader, String[] texNames, int[] params) {
648        validate();
649        return rsnProgramFragmentCreate(mContext, shader, texNames, params);
650    }
651    native int  rsnProgramVertexCreate(int con, String shader, String[] texNames, int[] params);
652    synchronized int nProgramVertexCreate(String shader, String[] texNames, int[] params) {
653        validate();
654        return rsnProgramVertexCreate(mContext, shader, texNames, params);
655    }
656
657    native int  rsnMeshCreate(int con, int[] vtx, int[] idx, int[] prim);
658    synchronized int nMeshCreate(int[] vtx, int[] idx, int[] prim) {
659        validate();
660        return rsnMeshCreate(mContext, vtx, idx, prim);
661    }
662    native int  rsnMeshGetVertexBufferCount(int con, int id);
663    synchronized int nMeshGetVertexBufferCount(int id) {
664        validate();
665        return rsnMeshGetVertexBufferCount(mContext, id);
666    }
667    native int  rsnMeshGetIndexCount(int con, int id);
668    synchronized int nMeshGetIndexCount(int id) {
669        validate();
670        return rsnMeshGetIndexCount(mContext, id);
671    }
672    native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
673    synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
674        validate();
675        rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
676    }
677    native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
678    synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
679        validate();
680        rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
681    }
682
683    native int  rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
684    synchronized int nPathCreate(int prim, boolean isStatic, int vtx, int loop, float q) {
685        validate();
686        return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
687    }
688
689    int     mDev;
690    int     mContext;
691    @SuppressWarnings({"FieldCanBeLocal"})
692    MessageThread mMessageThread;
693
694    Element mElement_U8;
695    Element mElement_I8;
696    Element mElement_U16;
697    Element mElement_I16;
698    Element mElement_U32;
699    Element mElement_I32;
700    Element mElement_U64;
701    Element mElement_I64;
702    Element mElement_F32;
703    Element mElement_F64;
704    Element mElement_BOOLEAN;
705
706    Element mElement_ELEMENT;
707    Element mElement_TYPE;
708    Element mElement_ALLOCATION;
709    Element mElement_SAMPLER;
710    Element mElement_SCRIPT;
711    Element mElement_MESH;
712    Element mElement_PROGRAM_FRAGMENT;
713    Element mElement_PROGRAM_VERTEX;
714    Element mElement_PROGRAM_RASTER;
715    Element mElement_PROGRAM_STORE;
716    Element mElement_FONT;
717
718    Element mElement_A_8;
719    Element mElement_RGB_565;
720    Element mElement_RGB_888;
721    Element mElement_RGBA_5551;
722    Element mElement_RGBA_4444;
723    Element mElement_RGBA_8888;
724
725    Element mElement_FLOAT_2;
726    Element mElement_FLOAT_3;
727    Element mElement_FLOAT_4;
728
729    Element mElement_DOUBLE_2;
730    Element mElement_DOUBLE_3;
731    Element mElement_DOUBLE_4;
732
733    Element mElement_UCHAR_2;
734    Element mElement_UCHAR_3;
735    Element mElement_UCHAR_4;
736
737    Element mElement_CHAR_2;
738    Element mElement_CHAR_3;
739    Element mElement_CHAR_4;
740
741    Element mElement_USHORT_2;
742    Element mElement_USHORT_3;
743    Element mElement_USHORT_4;
744
745    Element mElement_SHORT_2;
746    Element mElement_SHORT_3;
747    Element mElement_SHORT_4;
748
749    Element mElement_UINT_2;
750    Element mElement_UINT_3;
751    Element mElement_UINT_4;
752
753    Element mElement_INT_2;
754    Element mElement_INT_3;
755    Element mElement_INT_4;
756
757    Element mElement_ULONG_2;
758    Element mElement_ULONG_3;
759    Element mElement_ULONG_4;
760
761    Element mElement_LONG_2;
762    Element mElement_LONG_3;
763    Element mElement_LONG_4;
764
765    Element mElement_MATRIX_4X4;
766    Element mElement_MATRIX_3X3;
767    Element mElement_MATRIX_2X2;
768
769    Sampler mSampler_CLAMP_NEAREST;
770    Sampler mSampler_CLAMP_LINEAR;
771    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
772    Sampler mSampler_WRAP_NEAREST;
773    Sampler mSampler_WRAP_LINEAR;
774    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
775
776    ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
777    ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
778    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
779    ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
780
781    ProgramRaster mProgramRaster_CULL_BACK;
782    ProgramRaster mProgramRaster_CULL_FRONT;
783    ProgramRaster mProgramRaster_CULL_NONE;
784
785    ///////////////////////////////////////////////////////////////////////////////////
786    //
787
788    /**
789     * Base class application should derive from for handling RS messages
790     * coming from their scripts.  When a script calls sendToClient the data
791     * fields will be filled in and then the run method called by a message
792     * handling thread.  This will occur some time after sendToClient completes
793     * in the script.
794     *
795     */
796    public static class RSMessageHandler implements Runnable {
797        protected int[] mData;
798        protected int mID;
799        protected int mLength;
800        public void run() {
801        }
802    }
803    /**
804     * If an application is expecting messages it should set this field to an
805     * instance of RSMessage.  This instance will receive all the user messages
806     * sent from sendToClient by scripts from this context.
807     *
808     */
809    RSMessageHandler mMessageCallback = null;
810
811    public void setMessageHandler(RSMessageHandler msg) {
812        mMessageCallback = msg;
813    }
814    public RSMessageHandler getMessageHandler() {
815        return mMessageCallback;
816    }
817
818    /**
819     * Runtime error base class.  An application should derive from this class
820     * if it wishes to install an error handler.  When errors occur at runtime
821     * the fields in this class will be filled and the run method called.
822     *
823     */
824    public static class RSErrorHandler implements Runnable {
825        protected String mErrorMessage;
826        protected int mErrorNum;
827        public void run() {
828        }
829    }
830
831    /**
832     * Application Error handler.  All runtime errors will be dispatched to the
833     * instance of RSAsyncError set here.  If this field is null a
834     * RSRuntimeException will instead be thrown with details about the error.
835     * This will cause program termaination.
836     *
837     */
838    RSErrorHandler mErrorCallback = null;
839
840    public void setErrorHandler(RSErrorHandler msg) {
841        mErrorCallback = msg;
842    }
843    public RSErrorHandler getErrorHandler() {
844        return mErrorCallback;
845    }
846
847    /**
848     * RenderScript worker threads priority enumeration.  The default value is
849     * NORMAL.  Applications wishing to do background processing such as
850     * wallpapers should set their priority to LOW to avoid starving forground
851     * processes.
852     */
853    public enum Priority {
854        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
855        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
856
857        int mID;
858        Priority(int id) {
859            mID = id;
860        }
861    }
862
863    void validate() {
864        if (mContext == 0) {
865            throw new RSInvalidStateException("Calling RS with no Context active.");
866        }
867    }
868
869
870    /**
871     * Change the priority of the worker threads for this context.
872     *
873     * @param p New priority to be set.
874     */
875    public void setPriority(Priority p) {
876        validate();
877        nContextSetPriority(p.mID);
878    }
879
880    static class MessageThread extends Thread {
881        RenderScript mRS;
882        boolean mRun = true;
883        int[] mAuxData = new int[2];
884
885        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
886        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
887        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
888        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
889        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
890
891        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
892
893        MessageThread(RenderScript rs) {
894            super("RSMessageThread");
895            mRS = rs;
896
897        }
898
899        public void run() {
900            // This function is a temporary solution.  The final solution will
901            // used typed allocations where the message id is the type indicator.
902            int[] rbuf = new int[16];
903            mRS.nContextInitToClient(mRS.mContext);
904            while(mRun) {
905                rbuf[0] = 0;
906                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
907                int size = mAuxData[1];
908                int subID = mAuxData[0];
909
910                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
911                    if ((size>>2) >= rbuf.length) {
912                        rbuf = new int[(size + 3) >> 2];
913                    }
914                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
915                        RS_MESSAGE_TO_CLIENT_USER) {
916                        throw new RSDriverException("Error processing message from Renderscript.");
917                    }
918
919                    if(mRS.mMessageCallback != null) {
920                        mRS.mMessageCallback.mData = rbuf;
921                        mRS.mMessageCallback.mID = subID;
922                        mRS.mMessageCallback.mLength = size;
923                        mRS.mMessageCallback.run();
924                    } else {
925                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
926                    }
927                    continue;
928                }
929
930                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
931                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
932
933                    if (subID >= RS_ERROR_FATAL_UNKNOWN) {
934                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
935                    }
936
937                    if(mRS.mErrorCallback != null) {
938                        mRS.mErrorCallback.mErrorMessage = e;
939                        mRS.mErrorCallback.mErrorNum = subID;
940                        mRS.mErrorCallback.run();
941                    } else {
942                        // Do not throw here. In these cases, we do not have
943                        // a fatal error.
944                    }
945                    continue;
946                }
947
948                // 2: teardown.
949                // But we want to avoid starving other threads during
950                // teardown by yielding until the next line in the destructor
951                // can execute to set mRun = false
952                try {
953                    sleep(1, 0);
954                } catch(InterruptedException e) {
955                }
956            }
957            Log.d(LOG_TAG, "MessageThread exiting.");
958        }
959    }
960
961    RenderScript(Context ctx) {
962        if (ctx != null) {
963            mApplicationContext = ctx.getApplicationContext();
964        }
965    }
966
967    /**
968     * Gets the application context associated with the RenderScript context.
969     *
970     * @return The application context.
971     */
972    public final Context getApplicationContext() {
973        return mApplicationContext;
974    }
975
976    /**
977     * Create a basic RenderScript context.
978     *
979     * @hide
980     * @param ctx The context.
981     * @return RenderScript
982     */
983    public static RenderScript create(Context ctx, int sdkVersion) {
984        RenderScript rs = new RenderScript(ctx);
985
986        rs.mDev = rs.nDeviceCreate();
987        rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion);
988        if (rs.mContext == 0) {
989            throw new RSDriverException("Failed to create RS context.");
990        }
991        rs.mMessageThread = new MessageThread(rs);
992        rs.mMessageThread.start();
993        return rs;
994    }
995
996    /**
997     * Create a basic RenderScript context.
998     *
999     * @param ctx The context.
1000     * @return RenderScript
1001     */
1002    public static RenderScript create(Context ctx) {
1003        int v = ctx.getApplicationInfo().targetSdkVersion;
1004        return create(ctx, v);
1005    }
1006
1007    /**
1008     * Print the currently available debugging information about the state of
1009     * the RS context to the log.
1010     *
1011     */
1012    public void contextDump() {
1013        validate();
1014        nContextDump(0);
1015    }
1016
1017    /**
1018     * Wait for any commands in the fifo between the java bindings and native to
1019     * be processed.
1020     *
1021     */
1022    public void finish() {
1023        nContextFinish();
1024    }
1025
1026    /**
1027     * Destroy this renderscript context.  Once this function is called its no
1028     * longer legal to use this or any objects created by this context.
1029     *
1030     */
1031    public void destroy() {
1032        validate();
1033        nContextDeinitToClient(mContext);
1034        mMessageThread.mRun = false;
1035        try {
1036            mMessageThread.join();
1037        } catch(InterruptedException e) {
1038        }
1039
1040        nContextDestroy();
1041        mContext = 0;
1042
1043        nDeviceDestroy(mDev);
1044        mDev = 0;
1045    }
1046
1047    boolean isAlive() {
1048        return mContext != 0;
1049    }
1050
1051    int safeID(BaseObj o) {
1052        if(o != null) {
1053            return o.getID(this);
1054        }
1055        return 0;
1056    }
1057}
1058