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