diff options
Diffstat (limited to 'graphics')
28 files changed, 4653 insertions, 30 deletions
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index c8bed24..f60a7be 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -18,6 +18,7 @@ package android.graphics; import android.content.res.AssetManager; import android.content.res.Resources; +import android.os.MemoryFile; import android.util.DisplayMetrics; import android.util.TypedValue; @@ -72,7 +73,7 @@ public class BitmapFactory { public Bitmap.Config inPreferredConfig; /** - * If dither is true, the decoder will atttempt to dither the decoded + * If dither is true, the decoder will attempt to dither the decoded * image. */ public boolean inDither; @@ -336,19 +337,26 @@ public class BitmapFactory { */ public static Bitmap decodeResource(Resources res, int id, Options opts) { Bitmap bm = null; - + InputStream is = null; + try { final TypedValue value = new TypedValue(); - final InputStream is = res.openRawResource(id, value); + is = res.openRawResource(id, value); bm = decodeResourceStream(res, value, is, null, opts); - is.close(); - } catch (java.io.IOException e) { + } catch (Exception e) { /* do nothing. If the exception happened on open, bm will be null. If it happened on close, bm is still valid. */ + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + // Ignore + } } + return bm; } @@ -451,6 +459,10 @@ public class BitmapFactory { bm = nativeDecodeStream(is, tempStorage, outPadding, opts); } + return finishDecode(bm, outPadding, opts); + } + + private static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) { if (bm == null || opts == null) { return bm; } @@ -486,7 +498,7 @@ public class BitmapFactory { return bm; } - + /** * Decode an input stream into a bitmap. If the input stream is null, or * cannot be used to decode a bitmap, the function returns null. @@ -506,7 +518,7 @@ public class BitmapFactory { /** * Decode a bitmap from the file descriptor. If the bitmap cannot be decoded * return null. The position within the descriptor will not be changed when - * this returns, so the descriptor can be used again as is. + * this returns, so the descriptor can be used again as-is. * * @param fd The file descriptor containing the bitmap data to decode * @param outPadding If not null, return the padding rect for the bitmap if @@ -518,7 +530,20 @@ public class BitmapFactory { * @return the decoded bitmap, or null */ public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) { - return nativeDecodeFileDescriptor(fd, outPadding, opts); + try { + if (MemoryFile.isMemoryFile(fd)) { + int mappedlength = MemoryFile.getMappedSize(fd); + MemoryFile file = new MemoryFile(fd, mappedlength, "r"); + InputStream is = file.getInputStream(); + Bitmap bm = decodeStream(is, outPadding, opts); + return finishDecode(bm, outPadding, opts); + } + } catch (IOException ex) { + // invalid filedescriptor, no need to call nativeDecodeFileDescriptor() + return null; + } + Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts); + return finishDecode(bm, outPadding, opts); } /** @@ -530,7 +555,7 @@ public class BitmapFactory { * @return the decoded bitmap, or null */ public static Bitmap decodeFileDescriptor(FileDescriptor fd) { - return nativeDecodeFileDescriptor(fd, null, null); + return decodeFileDescriptor(fd, null, null); } private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage, diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 3fc391c..5cefaa3 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -16,6 +16,8 @@ package android.graphics; +import android.util.MathUtils; + import java.util.HashMap; import java.util.Locale; @@ -105,6 +107,92 @@ public class Color { } /** + * Returns the hue component of a color int. + * + * @return A value between 0.0f and 1.0f + * + * @hide Pending API council + */ + public static float hue(int color) { + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + + int V = Math.max(b, Math.max(r, g)); + int temp = Math.min(b, Math.min(r, g)); + + float H; + + if (V == temp) { + H = 0; + } else { + final float vtemp = (float) (V - temp); + final float cr = (V - r) / vtemp; + final float cg = (V - g) / vtemp; + final float cb = (V - b) / vtemp; + + if (r == V) { + H = cb - cg; + } else if (g == V) { + H = 2 + cr - cb; + } else { + H = 4 + cg - cr; + } + + H /= 6.f; + if (H < 0) { + H++; + } + } + + return H; + } + + /** + * Returns the saturation component of a color int. + * + * @return A value between 0.0f and 1.0f + * + * @hide Pending API council + */ + public static float saturation(int color) { + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + + + int V = Math.max(b, Math.max(r, g)); + int temp = Math.min(b, Math.min(r, g)); + + float S; + + if (V == temp) { + S = 0; + } else { + S = (V - temp) / (float) V; + } + + return S; + } + + /** + * Returns the brightness component of a color int. + * + * @return A value between 0.0f and 1.0f + * + * @hide Pending API council + */ + public static float brightness(int color) { + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + + int V = Math.max(b, Math.max(r, g)); + + return (V / 255.f); + } + + /** * Parse the color string, and return the corresponding color-int. * If the string cannot be parsed, throws an IllegalArgumentException * exception. Supported formats are: @@ -134,6 +222,87 @@ public class Color { } /** + * Convert HSB components to an ARGB color. Alpha set to 0xFF. + * hsv[0] is Hue [0 .. 1) + * hsv[1] is Saturation [0...1] + * hsv[2] is Value [0...1] + * If hsv values are out of range, they are pinned. + * @param hsb 3 element array which holds the input HSB components. + * @return the resulting argb color + * + * @hide Pending API council + */ + public static int HSBtoColor(float[] hsb) { + return HSBtoColor(hsb[0], hsb[1], hsb[2]); + } + + /** + * Convert HSB components to an ARGB color. Alpha set to 0xFF. + * hsv[0] is Hue [0 .. 1) + * hsv[1] is Saturation [0...1] + * hsv[2] is Value [0...1] + * If hsv values are out of range, they are pinned. + * @param h Hue component + * @param s Saturation component + * @param b Brightness component + * @return the resulting argb color + * + * @hide Pending API council + */ + public static int HSBtoColor(float h, float s, float b) { + h = MathUtils.constrain(h, 0.0f, 1.0f); + s = MathUtils.constrain(s, 0.0f, 1.0f); + b = MathUtils.constrain(b, 0.0f, 1.0f); + + float red = 0.0f; + float green = 0.0f; + float blue = 0.0f; + + final float hf = (h - (int) h) * 6.0f; + final int ihf = (int) hf; + final float f = hf - ihf; + final float pv = b * (1.0f - s); + final float qv = b * (1.0f - s * f); + final float tv = b * (1.0f - s * (1.0f - f)); + + switch (ihf) { + case 0: // Red is the dominant color + red = b; + green = tv; + blue = pv; + break; + case 1: // Green is the dominant color + red = qv; + green = b; + blue = pv; + break; + case 2: + red = pv; + green = b; + blue = tv; + break; + case 3: // Blue is the dominant color + red = pv; + green = qv; + blue = b; + break; + case 4: + red = tv; + green = pv; + blue = b; + break; + case 5: // Red is the dominant color + red = b; + green = pv; + blue = qv; + break; + } + + return 0xFF000000 | (((int) (red * 255.0f)) << 16) | + (((int) (green * 255.0f)) << 8) | ((int) (blue * 255.0f)); + } + + /** * Convert RGB components to HSV. * hsv[0] is Hue [0 .. 360) * hsv[1] is Saturation [0...1] @@ -193,25 +362,24 @@ public class Color { return nativeHSVToColor(alpha, hsv); } - private static native void nativeRGBToHSV(int red, int greed, int blue, - float hsv[]); + private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native int nativeHSVToColor(int alpha, float hsv[]); private static final HashMap<String, Integer> sColorNameMap; static { - sColorNameMap = new HashMap(); - sColorNameMap.put("black", Integer.valueOf(BLACK)); - sColorNameMap.put("darkgray", Integer.valueOf(DKGRAY)); - sColorNameMap.put("gray", Integer.valueOf(GRAY)); - sColorNameMap.put("lightgray", Integer.valueOf(LTGRAY)); - sColorNameMap.put("white", Integer.valueOf(WHITE)); - sColorNameMap.put("red", Integer.valueOf(RED)); - sColorNameMap.put("green", Integer.valueOf(GREEN)); - sColorNameMap.put("blue", Integer.valueOf(BLUE)); - sColorNameMap.put("yellow", Integer.valueOf(YELLOW)); - sColorNameMap.put("cyan", Integer.valueOf(CYAN)); - sColorNameMap.put("magenta", Integer.valueOf(MAGENTA)); + sColorNameMap = new HashMap<String, Integer>(); + sColorNameMap.put("black", BLACK); + sColorNameMap.put("darkgray", DKGRAY); + sColorNameMap.put("gray", GRAY); + sColorNameMap.put("lightgray", LTGRAY); + sColorNameMap.put("white", WHITE); + sColorNameMap.put("red", RED); + sColorNameMap.put("green", GREEN); + sColorNameMap.put("blue", BLUE); + sColorNameMap.put("yellow", YELLOW); + sColorNameMap.put("cyan", CYAN); + sColorNameMap.put("magenta", MAGENTA); } } diff --git a/graphics/java/android/graphics/DashPathEffect.java b/graphics/java/android/graphics/DashPathEffect.java index 3deca4a..4f16dc4 100644 --- a/graphics/java/android/graphics/DashPathEffect.java +++ b/graphics/java/android/graphics/DashPathEffect.java @@ -23,13 +23,13 @@ public class DashPathEffect extends PathEffect { * the even indices specifying the "on" intervals, and the odd indices * specifying the "off" intervals. phase is an offset into the intervals * array (mod the sum of all of the intervals). The intervals array - * controlls the width of the dashes. The paint's strokeWidth controlls the - * height of the dashes. + * controls the length of the dashes. The paint's strokeWidth controls the + * thickness of the dashes. * Note: this patheffect only affects drawing with the paint's style is set * to STROKE or STROKE_AND_FILL. It is ignored if the drawing is done with * style == FILL. * @param intervals array of ON and OFF distances - * @param phase offset before the first ON interval is drawn + * @param phase offset into the intervals array */ public DashPathEffect(float intervals[], float phase) { if (intervals.length < 2) { diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index e40e84a..9bcab72 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -172,4 +172,14 @@ public class Typeface { private static native int nativeGetStyle(int native_instance); private static native int nativeCreateFromAsset(AssetManager mgr, String path); private static native int nativeCreateFromFile(String path); + + /** + * Set the global gamma coefficients for black and white text. This call is + * usually a no-op in shipping products, and only exists for testing during + * development. + * + * @param blackGamma gamma coefficient for black text + * @param whiteGamma gamma coefficient for white text + */ + public static native void setGammaForText(float blackGamma, float whiteGamma); } diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index eade73a..1755d4f 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -76,6 +76,7 @@ public class BitmapDrawable extends Drawable { * @deprecated Use {@link #BitmapDrawable(Resources)} to ensure * that the drawable has correctly set its target density. */ + @Deprecated public BitmapDrawable() { mBitmapState = new BitmapState((Bitmap) null); } @@ -97,6 +98,7 @@ public class BitmapDrawable extends Drawable { * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure * that the drawable has correctly set its target density. */ + @Deprecated public BitmapDrawable(Bitmap bitmap) { this(new BitmapState(bitmap)); } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 0a0e4eb..21b5e39 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -102,7 +102,7 @@ public abstract class Drawable { private int[] mStateSet = StateSet.WILD_CARD; private int mLevel = 0; private int mChangingConfigurations = 0; - private Rect mBounds = ZERO_BOUNDS_RECT; + private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect() /*package*/ Callback mCallback = null; private boolean mVisible = true; @@ -654,7 +654,7 @@ public abstract class Drawable { * Create a drawable from an inputstream */ public static Drawable createFromStream(InputStream is, String srcName) { - return createFromResourceStream(null, null, is, srcName); + return createFromResourceStream(null, null, is, srcName, null); } /** @@ -663,6 +663,15 @@ public abstract class Drawable { */ public static Drawable createFromResourceStream(Resources res, TypedValue value, InputStream is, String srcName) { + return createFromResourceStream(res, value, is, srcName, null); + } + + /** + * Create a drawable from an inputstream, using the given resources and + * value to determine density information. + */ + public static Drawable createFromResourceStream(Resources res, TypedValue value, + InputStream is, String srcName, BitmapFactory.Options opts) { if (is == null) { return null; @@ -683,7 +692,7 @@ public abstract class Drawable { // an application in compatibility mode, without scaling those down // to the compatibility density only to have them scaled back up when // drawn to the screen. - BitmapFactory.Options opts = new BitmapFactory.Options(); + if (opts == null) opts = new BitmapFactory.Options(); opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE; Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts); if (bm != null) { diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index dc80cf5..6b50406 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -237,7 +237,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { final int N = mDrawableContainerState.getChildCount(); final Drawable[] drawables = mDrawableContainerState.getChildren(); for (int i = 0; i < N; i++) { - drawables[i].mutate(); + if (drawables[i] != null) drawables[i].mutate(); } mMutated = true; } diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index d5c8a08..1b1ea94 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -56,6 +56,7 @@ public class NinePatchDrawable extends Drawable { * @deprecated Use {@link #NinePatchDrawable(Resources, Bitmap, byte[], Rect, String)} * to ensure that the drawable has correctly set its target density. */ + @Deprecated public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) { this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding)); } @@ -78,6 +79,7 @@ public class NinePatchDrawable extends Drawable { * @deprecated Use {@link #NinePatchDrawable(Resources, NinePatch)} * to ensure that the drawable has correctly set its target density. */ + @Deprecated public NinePatchDrawable(NinePatch patch) { this(new NinePatchState(patch, null)); } @@ -192,6 +194,14 @@ public class NinePatchDrawable extends Drawable { } @Override + public void setFilterBitmap(boolean filter) { + // at the moment, we see no quality improvement, but a big slowdown + // with filtering, so ignore this call for now + // + //getPaint().setFilterBitmap(filter); + } + + @Override public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException { super.inflate(r, parser, attrs); @@ -245,6 +255,8 @@ public class NinePatchDrawable extends Drawable { public Paint getPaint() { if (mPaint == null) { mPaint = new Paint(); + // dithering helps a lot, and is pretty cheap, so default on + mPaint.setDither(true); } return mPaint; } diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java index d22a4ba..a8274b1 100644 --- a/graphics/java/android/graphics/drawable/StateListDrawable.java +++ b/graphics/java/android/graphics/drawable/StateListDrawable.java @@ -105,6 +105,8 @@ public class StateListDrawable extends DrawableContainer { mStateListState.setConstantSize(a.getBoolean( com.android.internal.R.styleable.StateListDrawable_constantSize, false)); + setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither, false)); + a.recycle(); int type; diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java new file mode 100644 index 0000000..7749ad3 --- /dev/null +++ b/graphics/java/android/renderscript/Allocation.java @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.io.IOException; +import java.io.InputStream; + +import android.content.res.Resources; +import android.content.res.AssetManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; +import android.util.TypedValue; + +/** + * @hide + * + **/ +public class Allocation extends BaseObj { + Type mType; + + Allocation(int id, RenderScript rs, Type t) { + super(rs); + mID = id; + mType = t; + } + + public void uploadToTexture(int baseMipLevel) { + mRS.nAllocationUploadToTexture(mID, baseMipLevel); + } + + public void uploadToBufferObject() { + mRS.nAllocationUploadToBufferObject(mID); + } + + public void data(int[] d) { + int size; + if(mType != null && mType.mElement != null) { + size = mType.mElement.mSize; + for(int ct=0; ct < mType.mValues.length; ct++) { + if(mType.mValues[ct] != 0) { + size *= mType.mValues[ct]; + } + } + if((d.length * 4) < size) { + throw new IllegalArgumentException("Array too small for allocation type."); + } + Log.e("rs", "Alloc data size=" + size); + mRS.nAllocationData(mID, d, size); + return; + } + mRS.nAllocationData(mID, d, d.length * 4); + } + + public void data(float[] d) { + int size; + if(mType != null && mType.mElement != null) { + size = mType.mElement.mSize; + for(int ct=0; ct < mType.mValues.length; ct++) { + if(mType.mValues[ct] != 0) { + size *= mType.mValues[ct]; + } + } + if((d.length * 4) < size) { + throw new IllegalArgumentException("Array too small for allocation type."); + } + Log.e("rs", "Alloc data size=" + size); + mRS.nAllocationData(mID, d, size); + return; + } + mRS.nAllocationData(mID, d, d.length * 4); + } + + public void subData1D(int off, int count, int[] d) { + mRS.nAllocationSubData1D(mID, off, count, d, count * 4); + } + + public void subData1D(int off, int count, float[] d) { + mRS.nAllocationSubData1D(mID, off, count, d, d.length * 4); + } + + public void subData2D(int xoff, int yoff, int w, int h, int[] d) { + mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4); + } + + public void subData2D(int xoff, int yoff, int w, int h, float[] d) { + mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4); + } + + public void readData(int[] d) { + mRS.nAllocationRead(mID, d); + } + + public void readData(float[] d) { + mRS.nAllocationRead(mID, d); + } + + public void data(Object o) { + mRS.nAllocationSubDataFromObject(mID, mType, 0, o); + } + + public void subData(int offset, Object o) { + mRS.nAllocationSubDataFromObject(mID, mType, offset, o); + } + + public class Adapter1D extends BaseObj { + Adapter1D(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void setConstraint(Dimension dim, int value) { + mRS.nAdapter1DSetConstraint(mID, dim.mID, value); + } + + public void data(int[] d) { + mRS.nAdapter1DData(mID, d); + } + + public void data(float[] d) { + mRS.nAdapter1DData(mID, d); + } + + public void subData(int off, int count, int[] d) { + mRS.nAdapter1DSubData(mID, off, count, d); + } + + public void subData(int off, int count, float[] d) { + mRS.nAdapter1DSubData(mID, off, count, d); + } + } + + public Adapter1D createAdapter1D() { + int id = mRS.nAdapter1DCreate(); + if (id != 0) { + mRS.nAdapter1DBindAllocation(id, mID); + } + return new Adapter1D(id, mRS); + } + + + public class Adapter2D extends BaseObj { + Adapter2D(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void setConstraint(Dimension dim, int value) { + mRS.nAdapter2DSetConstraint(mID, dim.mID, value); + } + + public void data(int[] d) { + mRS.nAdapter2DData(mID, d); + } + + public void data(float[] d) { + mRS.nAdapter2DData(mID, d); + } + + public void subData(int xoff, int yoff, int w, int h, int[] d) { + mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); + } + + public void subData(int xoff, int yoff, int w, int h, float[] d) { + mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); + } + } + + public Adapter2D createAdapter2D() { + int id = mRS.nAdapter2DCreate(); + if (id != 0) { + mRS.nAdapter2DBindAllocation(id, mID); + } + return new Adapter2D(id, mRS); + } + + + // creation + + private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); + static { + mBitmapOptions.inScaled = false; + } + + static public Allocation createTyped(RenderScript rs, Type type) + throws IllegalArgumentException { + + if(type.mID == 0) { + throw new IllegalStateException("Bad Type"); + } + int id = rs.nAllocationCreateTyped(type.mID); + return new Allocation(id, rs, type); + } + + static public Allocation createSized(RenderScript rs, Element e, int count) + throws IllegalArgumentException { + + int id = rs.nAllocationCreateSized(e.mID, count); + if(id == 0) { + throw new IllegalStateException("Bad element."); + } + return new Allocation(id, rs, null); + } + + static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) + throws IllegalArgumentException { + + int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b); + return new Allocation(id, rs, null); + } + + static public Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) + throws IllegalArgumentException { + + int id = rs.nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b); + return new Allocation(id, rs, null); + } + + static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips) + throws IllegalArgumentException { + + InputStream is = null; + try { + final TypedValue value = new TypedValue(); + is = res.openRawResource(id, value); + + int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); + int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips, + asset); + + return new Allocation(allocationId, rs, null); + } catch (Exception e) { + // Ignore + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + // Ignore + } + } + } + + return null; + } + + static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips) + throws IllegalArgumentException { + + Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions); + return createFromBitmapBoxed(rs, b, dstFmt, genMips); + } +} + + diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java new file mode 100644 index 0000000..c25f16a --- /dev/null +++ b/graphics/java/android/renderscript/BaseObj.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import android.util.Log; + +/** + * @hide + * + **/ +class BaseObj { + + BaseObj(RenderScript rs) { + mRS = rs; + mID = 0; + mDestroyed = false; + } + + public int getID() { + return mID; + } + + int mID; + boolean mDestroyed; + String mName; + RenderScript mRS; + + public void setName(String s) throws IllegalStateException, IllegalArgumentException + { + if(s.length() < 1) { + throw new IllegalArgumentException("setName does not accept a zero length string."); + } + if(mName != null) { + throw new IllegalArgumentException("setName object already has a name."); + } + + try { + byte[] bytes = s.getBytes("UTF-8"); + mRS.nAssignName(mID, bytes); + mName = s; + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + protected void finalize() throws Throwable + { + if (!mDestroyed) { + if(mID != 0) { + mRS.nObjDestroyOOB(mID); + } + mID = 0; + mDestroyed = true; + Log.v(RenderScript.LOG_TAG, + getClass() + " auto finalizing object without having released the RS reference."); + } + super.finalize(); + } + + public void destroy() { + if(mDestroyed) { + throw new IllegalStateException("Object already destroyed."); + } + mDestroyed = true; + mRS.nObjDestroy(mID); + } + +} + diff --git a/graphics/java/android/renderscript/Dimension.java b/graphics/java/android/renderscript/Dimension.java new file mode 100644 index 0000000..f29057d --- /dev/null +++ b/graphics/java/android/renderscript/Dimension.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +/** + * @hide + **/ +public enum Dimension { + X (0), + Y (1), + Z (2), + LOD (3), + FACE (4), + ARRAY_0 (100); + + int mID; + Dimension(int id) { + mID = id; + } +} + diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java new file mode 100644 index 0000000..04c36fd --- /dev/null +++ b/graphics/java/android/renderscript/Element.java @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.reflect.Field; + +/** + * @hide + * + **/ +public class Element extends BaseObj { + int mSize; + Entry[] mEntries; + + static class Entry { + Element mElement; + Element.DataType mType; + Element.DataKind mKind; + boolean mIsNormalized; + int mBits; + String mName; + + Entry(Element e, int bits) { + mElement = e; + int mBits = bits; + } + + Entry(DataType dt, DataKind dk, boolean isNorm, int bits, String name) { + mType = dt; + mKind = dk; + mIsNormalized = isNorm; + mBits = bits; + mName = name; + } + } + + public static final Element USER_U8 = new Element(); + public static final Element USER_I8 = new Element(); + public static final Element USER_U16 = new Element(); + public static final Element USER_I16 = new Element(); + public static final Element USER_U32 = new Element(); + public static final Element USER_I32 = new Element(); + public static final Element USER_FLOAT = new Element(); + + public static final Element A_8 = new Element(); + public static final Element RGB_565 = new Element(); + public static final Element RGB_888 = new Element(); + public static final Element RGBA_5551 = new Element(); + public static final Element RGBA_4444 = new Element(); + public static final Element RGBA_8888 = new Element(); + + public static final Element INDEX_16 = new Element(); + public static final Element XY_F32 = new Element(); + public static final Element XYZ_F32 = new Element(); + public static final Element ST_XY_F32 = new Element(); + public static final Element ST_XYZ_F32 = new Element(); + public static final Element NORM_XYZ_F32 = new Element(); + public static final Element NORM_ST_XYZ_F32 = new Element(); + + static void initPredefined(RenderScript rs) { + USER_U8.mEntries = new Entry[1]; + USER_U8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 8, null); + USER_U8.init(rs); + + USER_I8.mEntries = new Entry[1]; + USER_I8.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 8, null); + USER_I8.init(rs); + + USER_U16.mEntries = new Entry[1]; + USER_U16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 16, null); + USER_U16.init(rs); + + USER_I16.mEntries = new Entry[1]; + USER_I16.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 16, null); + USER_I16.init(rs); + + USER_U32.mEntries = new Entry[1]; + USER_U32.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.USER, false, 32, null); + USER_U32.init(rs); + + USER_I32.mEntries = new Entry[1]; + USER_I32.mEntries[0] = new Entry(DataType.SIGNED, DataKind.USER, false, 32, null); + USER_I32.init(rs); + + USER_FLOAT.mEntries = new Entry[1]; + USER_FLOAT.mEntries[0] = new Entry(DataType.FLOAT, DataKind.USER, false, 32, null); + USER_FLOAT.init(rs); + + A_8.mEntries = new Entry[1]; + A_8.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); + A_8.init(rs); + + RGB_565.mEntries = new Entry[3]; + RGB_565.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); + RGB_565.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 6, "g"); + RGB_565.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); + RGB_565.init(rs); + + RGB_888.mEntries = new Entry[3]; + RGB_888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); + RGB_888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); + RGB_888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); + RGB_888.init(rs); + + RGBA_5551.mEntries = new Entry[4]; + RGBA_5551.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 5, "r"); + RGBA_5551.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 5, "g"); + RGBA_5551.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 5, "b"); + RGBA_5551.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 1, "a"); + RGBA_5551.init(rs); + + RGBA_4444.mEntries = new Entry[4]; + RGBA_4444.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 4, "r"); + RGBA_4444.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 4, "g"); + RGBA_4444.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 4, "b"); + RGBA_4444.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 4, "a"); + RGBA_4444.init(rs); + + RGBA_8888.mEntries = new Entry[4]; + RGBA_8888.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.RED, true, 8, "r"); + RGBA_8888.mEntries[1] = new Entry(DataType.UNSIGNED, DataKind.GREEN, true, 8, "g"); + RGBA_8888.mEntries[2] = new Entry(DataType.UNSIGNED, DataKind.BLUE, true, 8, "b"); + RGBA_8888.mEntries[3] = new Entry(DataType.UNSIGNED, DataKind.ALPHA, true, 8, "a"); + RGBA_8888.init(rs); + + INDEX_16.mEntries = new Entry[1]; + INDEX_16.mEntries[0] = new Entry(DataType.UNSIGNED, DataKind.INDEX, false, 16, "index"); + INDEX_16.init(rs); + + XY_F32.mEntries = new Entry[2]; + XY_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + XY_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + XY_F32.init(rs); + + XYZ_F32.mEntries = new Entry[3]; + XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); + XYZ_F32.init(rs); + + ST_XY_F32.mEntries = new Entry[4]; + ST_XY_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); + ST_XY_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); + ST_XY_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + ST_XY_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + ST_XY_F32.init(rs); + + ST_XYZ_F32.mEntries = new Entry[5]; + ST_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); + ST_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); + ST_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + ST_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + ST_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); + ST_XYZ_F32.init(rs); + + NORM_XYZ_F32.mEntries = new Entry[6]; + NORM_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.NX, false, 32, "nx"); + NORM_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.NY, false, 32, "ny"); + NORM_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.NZ, false, 32, "nz"); + NORM_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + NORM_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + NORM_XYZ_F32.mEntries[5] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); + NORM_XYZ_F32.init(rs); + + NORM_ST_XYZ_F32.mEntries = new Entry[8]; + NORM_ST_XYZ_F32.mEntries[0] = new Entry(DataType.FLOAT, DataKind.NX, false, 32, "nx"); + NORM_ST_XYZ_F32.mEntries[1] = new Entry(DataType.FLOAT, DataKind.NY, false, 32, "ny"); + NORM_ST_XYZ_F32.mEntries[2] = new Entry(DataType.FLOAT, DataKind.NZ, false, 32, "nz"); + NORM_ST_XYZ_F32.mEntries[3] = new Entry(DataType.FLOAT, DataKind.S, false, 32, "s"); + NORM_ST_XYZ_F32.mEntries[4] = new Entry(DataType.FLOAT, DataKind.T, false, 32, "t"); + NORM_ST_XYZ_F32.mEntries[5] = new Entry(DataType.FLOAT, DataKind.X, false, 32, "x"); + NORM_ST_XYZ_F32.mEntries[6] = new Entry(DataType.FLOAT, DataKind.Y, false, 32, "y"); + NORM_ST_XYZ_F32.mEntries[7] = new Entry(DataType.FLOAT, DataKind.Z, false, 32, "z"); + NORM_ST_XYZ_F32.init(rs); + + rs.nInitElements(A_8.mID, RGBA_4444.mID, RGBA_8888.mID, RGB_565.mID); + } + + + public enum DataType { + FLOAT (0), + UNSIGNED (1), + SIGNED (2); + + int mID; + DataType(int id) { + mID = id; + } + } + + public enum DataKind { + USER (0), + RED (1), + GREEN (2), + BLUE (3), + ALPHA (4), + LUMINANCE (5), + INTENSITY (6), + X (7), + Y (8), + Z (9), + W (10), + S (11), + T (12), + Q (13), + R (14), + NX (15), + NY (16), + NZ (17), + INDEX (18), + POINT_SIZE(19); + + int mID; + DataKind(int id) { + mID = id; + } + } + + Element() { + super(null); + mID = 0; + mSize = 0; + } + + public void destroy() throws IllegalStateException { + super.destroy(); + } + + public static Element createFromClass(RenderScript rs, Class c) { + Field[] fields = c.getFields(); + Builder b = new Builder(rs); + + for(Field f: fields) { + Class fc = f.getType(); + if(fc == int.class) { + b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 32, f.getName()); + } else if(fc == short.class) { + b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 16, f.getName()); + } else if(fc == byte.class) { + b.add(Element.DataType.SIGNED, Element.DataKind.USER, false, 8, f.getName()); + } else if(fc == float.class) { + b.add(Element.DataType.FLOAT, Element.DataKind.USER, false, 32, f.getName()); + } else { + throw new IllegalArgumentException("Unkown field type"); + } + } + return b.create(); + } + + static synchronized void internalCreate(RenderScript rs, Element e) { + rs.nElementBegin(); + int bits = 0; + for (int ct=0; ct < e.mEntries.length; ct++) { + Entry en = e.mEntries[ct]; + if(en.mElement != null) { + //rs.nElementAdd(en.mElement.mID); + } else { + int norm = 0; + if (en.mIsNormalized) { + norm = 1; + } + rs.nElementAdd(en.mKind.mID, en.mType.mID, norm, en.mBits, en.mName); + bits += en.mBits; + } + } + e.mID = rs.nElementCreate(); + e.mSize = (bits + 7) >> 3; + } + + void init(RenderScript rs) { + mRS = rs; + internalCreate(mRS, this); + } + + + public static class Builder { + RenderScript mRS; + Entry[] mEntries; + int mEntryCount; + + public Builder(RenderScript rs) { + mRS = rs; + mEntryCount = 0; + mEntries = new Entry[8]; + } + + void addEntry(Entry e) { + if(mEntries.length >= mEntryCount) { + Entry[] en = new Entry[mEntryCount + 8]; + System.arraycopy(mEntries, 0, en, 0, mEntries.length); + mEntries = en; + } + mEntries[mEntryCount] = e; + mEntryCount++; + } + + public Builder add(Element e) throws IllegalArgumentException { + Entry en = new Entry(e, e.mSize * 8); + addEntry(en); + return this; + } + + public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits, String name) { + Entry en = new Entry(dt, dk, isNormalized, bits, name); + addEntry(en); + return this; + } + + public Builder add(Element.DataType dt, Element.DataKind dk, boolean isNormalized, int bits) { + add(dt, dk, isNormalized, bits, null); + return this; + } + + public Builder addFloat(Element.DataKind dk) { + add(DataType.FLOAT, dk, false, 32, null); + return this; + } + + public Builder addFloat(Element.DataKind dk, String name) { + add(DataType.FLOAT, dk, false, 32, name); + return this; + } + + public Builder addFloatXY() { + add(DataType.FLOAT, DataKind.X, false, 32, null); + add(DataType.FLOAT, DataKind.Y, false, 32, null); + return this; + } + + public Builder addFloatXY(String prefix) { + add(DataType.FLOAT, DataKind.X, false, 32, prefix + "x"); + add(DataType.FLOAT, DataKind.Y, false, 32, prefix + "y"); + return this; + } + + public Builder addFloatXYZ() { + add(DataType.FLOAT, DataKind.X, false, 32, null); + add(DataType.FLOAT, DataKind.Y, false, 32, null); + add(DataType.FLOAT, DataKind.Z, false, 32, null); + return this; + } + + public Builder addFloatXYZ(String prefix) { + add(DataType.FLOAT, DataKind.X, false, 32, prefix + "x"); + add(DataType.FLOAT, DataKind.Y, false, 32, prefix + "y"); + add(DataType.FLOAT, DataKind.Z, false, 32, prefix + "z"); + return this; + } + + public Builder addFloatST() { + add(DataType.FLOAT, DataKind.S, false, 32, null); + add(DataType.FLOAT, DataKind.T, false, 32, null); + return this; + } + + public Builder addFloatST(String prefix) { + add(DataType.FLOAT, DataKind.S, false, 32, prefix + "s"); + add(DataType.FLOAT, DataKind.T, false, 32, prefix + "t"); + return this; + } + + public Builder addFloatNorm() { + add(DataType.FLOAT, DataKind.NX, false, 32, null); + add(DataType.FLOAT, DataKind.NY, false, 32, null); + add(DataType.FLOAT, DataKind.NZ, false, 32, null); + return this; + } + + public Builder addFloatNorm(String prefix) { + add(DataType.FLOAT, DataKind.NX, false, 32, prefix + "nx"); + add(DataType.FLOAT, DataKind.NY, false, 32, prefix + "ny"); + add(DataType.FLOAT, DataKind.NZ, false, 32, prefix + "nz"); + return this; + } + + public Builder addFloatPointSize() { + add(DataType.FLOAT, DataKind.POINT_SIZE, false, 32, null); + return this; + } + + public Builder addFloatPointSize(String prefix) { + add(DataType.FLOAT, DataKind.POINT_SIZE, false, 32, prefix + "pointSize"); + return this; + } + + public Builder addFloatRGB() { + add(DataType.FLOAT, DataKind.RED, false, 32, null); + add(DataType.FLOAT, DataKind.GREEN, false, 32, null); + add(DataType.FLOAT, DataKind.BLUE, false, 32, null); + return this; + } + + public Builder addFloatRGB(String prefix) { + add(DataType.FLOAT, DataKind.RED, false, 32, prefix + "r"); + add(DataType.FLOAT, DataKind.GREEN, false, 32, prefix + "g"); + add(DataType.FLOAT, DataKind.BLUE, false, 32, prefix + "b"); + return this; + } + + public Builder addFloatRGBA() { + add(DataType.FLOAT, DataKind.RED, false, 32, null); + add(DataType.FLOAT, DataKind.GREEN, false, 32, null); + add(DataType.FLOAT, DataKind.BLUE, false, 32, null); + add(DataType.FLOAT, DataKind.ALPHA, false, 32, null); + return this; + } + + public Builder addFloatRGBA(String prefix) { + add(DataType.FLOAT, DataKind.RED, false, 32, prefix + "r"); + add(DataType.FLOAT, DataKind.GREEN, false, 32, prefix + "g"); + add(DataType.FLOAT, DataKind.BLUE, false, 32, prefix + "b"); + add(DataType.FLOAT, DataKind.ALPHA, false, 32, prefix + "a"); + return this; + } + + public Builder addUNorm8RGBA() { + add(DataType.UNSIGNED, DataKind.RED, true, 8, null); + add(DataType.UNSIGNED, DataKind.GREEN, true, 8, null); + add(DataType.UNSIGNED, DataKind.BLUE, true, 8, null); + add(DataType.UNSIGNED, DataKind.ALPHA, true, 8, null); + return this; + } + + public Builder addUNorm8RGBA(String prefix) { + add(DataType.UNSIGNED, DataKind.RED, true, 8, prefix + "r"); + add(DataType.UNSIGNED, DataKind.GREEN, true, 8, prefix + "g"); + add(DataType.UNSIGNED, DataKind.BLUE, true, 8, prefix + "b"); + add(DataType.UNSIGNED, DataKind.ALPHA, true, 8, prefix + "a"); + return this; + } + + public Element create() { + Element e = new Element(); + e.mEntries = new Entry[mEntryCount]; + java.lang.System.arraycopy(mEntries, 0, e.mEntries, 0, mEntryCount); + e.init(mRS); + return e; + } + } + +} + diff --git a/graphics/java/android/renderscript/Light.java b/graphics/java/android/renderscript/Light.java new file mode 100644 index 0000000..115ae03 --- /dev/null +++ b/graphics/java/android/renderscript/Light.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import android.util.Config; +import android.util.Log; + +/** + * @hide + * + **/ +public class Light extends BaseObj { + Light(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void setColor(float r, float g, float b) { + mRS.nLightSetColor(mID, r, g, b); + } + + public void setPosition(float x, float y, float z) { + mRS.nLightSetPosition(mID, x, y, z); + } + + public static class Builder { + RenderScript mRS; + boolean mIsMono; + boolean mIsLocal; + + public Builder(RenderScript rs) { + mRS = rs; + mIsMono = false; + mIsLocal = false; + } + + public void lightSetIsMono(boolean isMono) { + mIsMono = isMono; + } + + public void lightSetIsLocal(boolean isLocal) { + mIsLocal = isLocal; + } + + static synchronized Light internalCreate(RenderScript rs, Builder b) { + rs.nSamplerBegin(); + rs.nLightSetIsMono(b.mIsMono); + rs.nLightSetIsLocal(b.mIsLocal); + int id = rs.nLightCreate(); + return new Light(id, rs); + } + + public Light create() { + return internalCreate(mRS, this); + } + } + +} + diff --git a/graphics/java/android/renderscript/Matrix.java b/graphics/java/android/renderscript/Matrix.java new file mode 100644 index 0000000..a266d6b --- /dev/null +++ b/graphics/java/android/renderscript/Matrix.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.Math; +import android.util.Log; + + +/** + * @hide + * + **/ +public class Matrix { + + public Matrix() { + mMat = new float[16]; + loadIdentity(); + } + + public float get(int i, int j) { + return mMat[i*4 + j]; + } + + public void set(int i, int j, float v) { + mMat[i*4 + j] = v; + } + + public void loadIdentity() { + mMat[0] = 1; + mMat[1] = 0; + mMat[2] = 0; + mMat[3] = 0; + + mMat[4] = 0; + mMat[5] = 1; + mMat[6] = 0; + mMat[7] = 0; + + mMat[8] = 0; + mMat[9] = 0; + mMat[10] = 1; + mMat[11] = 0; + + mMat[12] = 0; + mMat[13] = 0; + mMat[14] = 0; + mMat[15] = 1; + } + + public void load(Matrix src) { + mMat = src.mMat; + } + + public void loadRotate(float rot, float x, float y, float z) { + float c, s; + mMat[3] = 0; + mMat[7] = 0; + mMat[11]= 0; + mMat[12]= 0; + mMat[13]= 0; + mMat[14]= 0; + mMat[15]= 1; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + + float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z); + if (!(len != 1)) { + float recipLen = 1.f / len; + x *= recipLen; + y *= recipLen; + z *= recipLen; + } + float nc = 1.0f - c; + float xy = x * y; + float yz = y * z; + float zx = z * x; + float xs = x * s; + float ys = y * s; + float zs = z * s; + mMat[ 0] = x*x*nc + c; + mMat[ 4] = xy*nc - zs; + mMat[ 8] = zx*nc + ys; + mMat[ 1] = xy*nc + zs; + mMat[ 5] = y*y*nc + c; + mMat[ 9] = yz*nc - xs; + mMat[ 2] = zx*nc - ys; + mMat[ 6] = yz*nc + xs; + mMat[10] = z*z*nc + c; + } + + public void loadScale(float x, float y, float z) { + loadIdentity(); + mMat[0] = x; + mMat[5] = y; + mMat[10] = z; + } + + public void loadTranslate(float x, float y, float z) { + loadIdentity(); + mMat[12] = x; + mMat[13] = y; + mMat[14] = z; + } + + public void loadMultiply(Matrix lhs, Matrix rhs) { + for (int i=0 ; i<4 ; i++) { + float ri0 = 0; + float ri1 = 0; + float ri2 = 0; + float ri3 = 0; + for (int j=0 ; j<4 ; j++) { + float rhs_ij = rhs.get(i,j); + ri0 += lhs.get(j,0) * rhs_ij; + ri1 += lhs.get(j,1) * rhs_ij; + ri2 += lhs.get(j,2) * rhs_ij; + ri3 += lhs.get(j,3) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + set(i,2, ri2); + set(i,3, ri3); + } + } + + public void loadOrtho(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + mMat[0] = 2 / (r - l); + mMat[5] = 2 / (t - b); + mMat[10]= -2 / (f - n); + mMat[12]= -(r + l) / (r - l); + mMat[13]= -(t + b) / (t - b); + mMat[14]= -(f + n) / (f - n); + } + + public void loadFrustum(float l, float r, float b, float t, float n, float f) { + loadIdentity(); + mMat[0] = 2 * n / (r - l); + mMat[5] = 2 * n / (t - b); + mMat[8] = (r + l) / (r - l); + mMat[9] = (t + b) / (t - b); + mMat[10]= -(f + n) / (f - n); + mMat[11]= -1; + mMat[14]= -2*f*n / (f - n); + mMat[15]= 0; + } + + public void multiply(Matrix rhs) { + Matrix tmp = new Matrix(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + public void rotate(float rot, float x, float y, float z) { + Matrix tmp = new Matrix(); + tmp.loadRotate(rot, x, y, z); + multiply(tmp); + } + public void scale(float x, float y, float z) { + Matrix tmp = new Matrix(); + tmp.loadScale(x, y, z); + multiply(tmp); + } + public void translate(float x, float y, float z) { + Matrix tmp = new Matrix(); + tmp.loadTranslate(x, y, z); + multiply(tmp); + } + + + + float[] mMat; + +} + + + + + diff --git a/graphics/java/android/renderscript/Primitive.java b/graphics/java/android/renderscript/Primitive.java new file mode 100644 index 0000000..7925cac --- /dev/null +++ b/graphics/java/android/renderscript/Primitive.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +/** + * @hide + **/ +public enum Primitive { + POINT (0), + LINE (1), + LINE_STRIP (2), + TRIANGLE (3), + TRIANGLE_STRIP (4), + TRIANGLE_FAN (5); + + int mID; + Primitive(int id) { + mID = id; + } +} + + + diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java new file mode 100644 index 0000000..392d93d --- /dev/null +++ b/graphics/java/android/renderscript/ProgramFragment.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import android.util.Config; +import android.util.Log; + + +/** + * @hide + * + **/ +public class ProgramFragment extends BaseObj { + public static final int MAX_SLOT = 2; + + public enum EnvMode { + REPLACE (0), + MODULATE (1), + DECAL (2); + + int mID; + EnvMode(int id) { + mID = id; + } + } + + + ProgramFragment(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void bindTexture(Allocation va, int slot) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_SLOT)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mRS.nProgramFragmentBindTexture(mID, slot, va.mID); + } + + public void bindSampler(Sampler vs, int slot) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_SLOT)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mRS.nProgramFragmentBindSampler(mID, slot, vs.mID); + } + + + public static class Builder { + RenderScript mRS; + Element mIn; + Element mOut; + boolean mPointSpriteEnable; + + private class Slot { + Type mType; + EnvMode mEnv; + boolean mTexEnable; + + Slot() { + mTexEnable = false; + } + } + Slot[] mSlots; + + public Builder(RenderScript rs, Element in, Element out) { + mRS = rs; + mIn = in; + mOut = out; + mSlots = new Slot[MAX_SLOT]; + mPointSpriteEnable = false; + for(int ct=0; ct < MAX_SLOT; ct++) { + mSlots[ct] = new Slot(); + } + } + + public void setType(int slot, Type t) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_SLOT)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mSlots[slot].mType = t; + } + + public void setTexEnable(boolean enable, int slot) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_SLOT)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mSlots[slot].mTexEnable = enable; + } + + public void setTexEnvMode(EnvMode env, int slot) + throws IllegalArgumentException { + if((slot < 0) || (slot >= MAX_SLOT)) { + throw new IllegalArgumentException("Slot ID out of range."); + } + + mSlots[slot].mEnv = env; + } + + public void setPointSpriteTexCoordinateReplacement(boolean enable) { + mPointSpriteEnable = enable; + } + + static synchronized ProgramFragment internalCreate(RenderScript rs, Builder b) { + int inID = 0; + int outID = 0; + if (b.mIn != null) { + inID = b.mIn.mID; + } + if (b.mOut != null) { + outID = b.mOut.mID; + } + rs.nProgramFragmentBegin(inID, outID, b.mPointSpriteEnable); + for(int ct=0; ct < MAX_SLOT; ct++) { + if(b.mSlots[ct].mTexEnable) { + Slot s = b.mSlots[ct]; + int typeID = 0; + if(s.mType != null) { + typeID = s.mType.mID; + } + rs.nProgramFragmentSetSlot(ct, true, s.mEnv.mID, typeID); + } + } + + int id = rs.nProgramFragmentCreate(); + return new ProgramFragment(id, rs); + } + + public ProgramFragment create() { + return internalCreate(mRS, this); + } + } +} + + + diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java new file mode 100644 index 0000000..b7d987e --- /dev/null +++ b/graphics/java/android/renderscript/ProgramStore.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import android.util.Config; +import android.util.Log; + + +/** + * @hide + * + **/ +public class ProgramStore extends BaseObj { + public enum DepthFunc { + ALWAYS (0), + LESS (1), + LEQUAL (2), + GREATER (3), + GEQUAL (4), + EQUAL (5), + NOTEQUAL (6); + + int mID; + DepthFunc(int id) { + mID = id; + } + } + + public enum BlendSrcFunc { + ZERO (0), + ONE (1), + DST_COLOR (2), + ONE_MINUS_DST_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPA (7), + SRC_ALPHA_SATURATE (8); + + int mID; + BlendSrcFunc(int id) { + mID = id; + } + } + + public enum BlendDstFunc { + ZERO (0), + ONE (1), + SRC_COLOR (2), + ONE_MINUS_SRC_COLOR (3), + SRC_ALPHA (4), + ONE_MINUS_SRC_ALPHA (5), + DST_ALPHA (6), + ONE_MINUS_DST_ALPA (7); + + int mID; + BlendDstFunc(int id) { + mID = id; + } + } + + + ProgramStore(int id, RenderScript rs) { + super(rs); + mID = id; + } + + + + public static class Builder { + RenderScript mRS; + Element mIn; + Element mOut; + DepthFunc mDepthFunc; + boolean mDepthMask; + boolean mColorMaskR; + boolean mColorMaskG; + boolean mColorMaskB; + boolean mColorMaskA; + BlendSrcFunc mBlendSrc; + BlendDstFunc mBlendDst; + boolean mDither; + + + + public Builder(RenderScript rs, Element in, Element out) { + mRS = rs; + mIn = in; + mOut = out; + mDepthFunc = DepthFunc.ALWAYS; + mDepthMask = false; + mColorMaskR = true; + mColorMaskG = true; + mColorMaskB = true; + mColorMaskA = true; + mBlendSrc = BlendSrcFunc.ONE; + mBlendDst = BlendDstFunc.ZERO; + + + } + + public void setDepthFunc(DepthFunc func) { + mDepthFunc = func; + } + + public void setDepthMask(boolean enable) { + mDepthMask = enable; + } + + public void setColorMask(boolean r, boolean g, boolean b, boolean a) { + mColorMaskR = r; + mColorMaskG = g; + mColorMaskB = b; + mColorMaskA = a; + } + + public void setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) { + mBlendSrc = src; + mBlendDst = dst; + } + + public void setDitherEnable(boolean enable) { + mDither = enable; + } + + static synchronized ProgramStore internalCreate(RenderScript rs, Builder b) { + int inID = 0; + int outID = 0; + if (b.mIn != null) { + inID = b.mIn.mID; + } + if (b.mOut != null) { + outID = b.mOut.mID; + } + rs.nProgramFragmentStoreBegin(inID, outID); + rs.nProgramFragmentStoreDepthFunc(b.mDepthFunc.mID); + rs.nProgramFragmentStoreDepthMask(b.mDepthMask); + rs.nProgramFragmentStoreColorMask(b.mColorMaskR, + b.mColorMaskG, + b.mColorMaskB, + b.mColorMaskA); + rs.nProgramFragmentStoreBlendFunc(b.mBlendSrc.mID, b.mBlendDst.mID); + rs.nProgramFragmentStoreDither(b.mDither); + + int id = rs.nProgramFragmentStoreCreate(); + return new ProgramStore(id, rs); + } + + public ProgramStore create() { + return internalCreate(mRS, this); + } + } + +} + + + + diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java new file mode 100644 index 0000000..2a11bfb --- /dev/null +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import android.util.Config; +import android.util.Log; + + +/** + * @hide + * + **/ +public class ProgramVertex extends BaseObj { + public static final int MAX_LIGHT = 8; + + ProgramVertex(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void bindAllocation(MatrixAllocation va) { + mRS.nProgramVertexBindAllocation(mID, va.mAlloc.mID); + } + + + public static class Builder { + RenderScript mRS; + Element mIn; + Element mOut; + Light[] mLights; + int mLightCount; + boolean mTextureMatrixEnable; + + + public Builder(RenderScript rs, Element in, Element out) { + mRS = rs; + mIn = in; + mOut = out; + mLights = new Light[MAX_LIGHT]; + mLightCount = 0; + } + + public void setTextureMatrixEnable(boolean enable) { + mTextureMatrixEnable = enable; + } + + public void addLight(Light l) throws IllegalStateException { + if(mLightCount >= MAX_LIGHT) { + throw new IllegalArgumentException("Max light count exceeded."); + } + mLights[mLightCount] = l; + mLightCount++; + } + + + + static synchronized ProgramVertex internalCreate(RenderScript rs, Builder b) { + int inID = 0; + int outID = 0; + if (b.mIn != null) { + inID = b.mIn.mID; + } + if (b.mOut != null) { + outID = b.mOut.mID; + } + rs.nProgramVertexBegin(inID, outID); + for(int ct=0; ct < b.mLightCount; ct++) { + rs.nProgramVertexAddLight(b.mLights[ct].mID); + } + rs.nProgramVertexSetTextureMatrixEnable(b.mTextureMatrixEnable); + int id = rs.nProgramVertexCreate(); + return new ProgramVertex(id, rs); + } + + public ProgramVertex create() { + return internalCreate(mRS, this); + } + } + + + + public static class MatrixAllocation { + static final int MODELVIEW_OFFSET = 0; + static final int PROJECTION_OFFSET = 16; + static final int TEXTURE_OFFSET = 32; + + Matrix mModel; + Matrix mProjection; + Matrix mTexture; + + public Allocation mAlloc; + + public MatrixAllocation(RenderScript rs) { + mModel = new Matrix(); + mProjection = new Matrix(); + mTexture = new Matrix(); + + mAlloc = Allocation.createSized(rs, Element.USER_FLOAT, 48); + mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat); + mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat); + } + + public void destroy() { + mAlloc.destroy(); + mAlloc = null; + } + + public void loadModelview(Matrix m) { + mModel = m; + mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat); + } + + public void loadProjection(Matrix m) { + mProjection = m; + mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat); + } + + public void loadTexture(Matrix m) { + mTexture = m; + mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat); + } + + public void setupOrthoWindow(int w, int h) { + mProjection.loadOrtho(0,w, h,0, -1,1); + mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + } + + public void setupOrthoNormalized(int w, int h) { + // range -1,1 in the narrow axis. + if(w > h) { + float aspect = ((float)w) / h; + mProjection.loadOrtho(-aspect,aspect, -1,1, -1,1); + } else { + float aspect = ((float)h) / w; + mProjection.loadOrtho(-1,1, -aspect,aspect, -1,1); + } + mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + } + + public void setupProjectionNormalized(int w, int h) { + // range -1,1 in the narrow axis at z = 0. + Matrix m1 = new Matrix(); + Matrix m2 = new Matrix(); + + if(w > h) { + float aspect = ((float)w) / h; + m1.loadFrustum(-aspect,aspect, -1,1, 1,100); + } else { + float aspect = ((float)h) / w; + m1.loadFrustum(-1,1, -aspect,aspect, 1,100); + } + + m2.loadRotate(180, 0, 1, 0); + m1.loadMultiply(m1, m2); + + m2.loadScale(-2, 2, 1); + m1.loadMultiply(m1, m2); + + m2.loadTranslate(0, 0, 2); + m1.loadMultiply(m1, m2); + + mProjection = m1; + mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + } + + } + +} + diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java new file mode 100644 index 0000000..a3f1ded --- /dev/null +++ b/graphics/java/android/renderscript/RSSurfaceView.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +/** + * @hide + * + **/ +public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private SurfaceHolder mSurfaceHolder; + + /** + * Standard View constructor. In order to render something, you + * must call {@link #setRenderer} to register a renderer. + */ + public RSSurfaceView(Context context) { + super(context); + init(); + Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + /** + * Standard View constructor. In order to render something, you + * must call {@link #setRenderer} to register a renderer. + */ + public RSSurfaceView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + Log.v(RenderScript.LOG_TAG, "RSSurfaceView"); + } + + private void init() { + // Install a SurfaceHolder.Callback so we get notified when the + // underlying surface is created and destroyed + SurfaceHolder holder = getHolder(); + holder.addCallback(this); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceCreated(SurfaceHolder holder) { + Log.v(RenderScript.LOG_TAG, "surfaceCreated"); + mSurfaceHolder = holder; + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceDestroyed(SurfaceHolder holder) { + // Surface will be destroyed when we return + Log.v(RenderScript.LOG_TAG, "surfaceDestroyed"); + } + + /** + * This method is part of the SurfaceHolder.Callback interface, and is + * not normally called or subclassed by clients of RSSurfaceView. + */ + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + Log.v(RenderScript.LOG_TAG, "surfaceChanged"); + } + + /** + * Inform the view that the activity is paused. The owner of this view must + * call this method when the activity is paused. Calling this method will + * pause the rendering thread. + * Must not be called before a renderer has been set. + */ + public void onPause() { + Log.v(RenderScript.LOG_TAG, "onPause"); + } + + /** + * Inform the view that the activity is resumed. The owner of this view must + * call this method when the activity is resumed. Calling this method will + * recreate the OpenGL display and resume the rendering + * thread. + * Must not be called before a renderer has been set. + */ + public void onResume() { + Log.v(RenderScript.LOG_TAG, "onResume"); + } + + /** + * Queue a runnable to be run on the GL rendering thread. This can be used + * to communicate with the Renderer on the rendering thread. + * Must not be called before a renderer has been set. + * @param r the runnable to be run on the GL rendering thread. + */ + public void queueEvent(Runnable r) { + Log.v(RenderScript.LOG_TAG, "queueEvent"); + } + + /** + * This method is used as part of the View class and is not normally + * called or subclassed by clients of RSSurfaceView. + * Must not be called before a renderer has been set. + */ + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + } + + // ---------------------------------------------------------------------- + + public RenderScript createRenderScript(boolean useDepth) { + Surface sur = null; + while ((sur == null) || (mSurfaceHolder == null)) { + sur = getHolder().getSurface(); + } + RenderScript rs = new RenderScript(sur, useDepth); + return rs; + } + +} + diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java new file mode 100644 index 0000000..6f5b67e --- /dev/null +++ b/graphics/java/android/renderscript/RenderScript.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.reflect.Field; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Config; +import android.util.Log; +import android.view.Surface; + + +/** + * @hide + * + **/ +public class RenderScript { + static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + @SuppressWarnings({"UnusedDeclaration", "deprecation"}) + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + + + /* + * We use a class initializer to allow the native code to cache some + * field offsets. + */ + @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) + private static boolean sInitialized; + native private static void _nInit(); + + + static { + sInitialized = false; + try { + System.loadLibrary("rs_jni"); + _nInit(); + sInitialized = true; + } catch (UnsatisfiedLinkError e) { + Log.d(LOG_TAG, "RenderScript JNI library not found!"); + } + } + + native void nInitElements(int a8, int rgba4444, int rgba8888, int rgb565); + + native int nDeviceCreate(); + native void nDeviceDestroy(int dev); + native int nContextCreate(int dev, Surface sur, int ver, boolean useDepth); + native void nContextDestroy(int con); + + //void rsContextBindSampler (uint32_t slot, RsSampler sampler); + //void rsContextBindRootScript (RsScript sampler); + native void nContextBindRootScript(int script); + native void nContextBindSampler(int sampler, int slot); + native void nContextBindProgramFragmentStore(int pfs); + native void nContextBindProgramFragment(int pf); + native void nContextBindProgramVertex(int pf); + native void nContextAddDefineI32(String name, int value); + native void nContextAddDefineF(String name, float value); + + native void nAssignName(int obj, byte[] name); + native void nObjDestroy(int id); + native void nObjDestroyOOB(int id); + native int nFileOpen(byte[] name); + + native void nElementBegin(); + native void nElementAdd(int kind, int type, int norm, int bits, String s); + native int nElementCreate(); + + native void nTypeBegin(int elementID); + native void nTypeAdd(int dim, int val); + native int nTypeCreate(); + native void nTypeFinalDestroy(Type t); + native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs); + + native int nAllocationCreateTyped(int type); + native int nAllocationCreateSized(int elem, int count); + native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp); + native int nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp); + native int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream); + + native void nAllocationUploadToTexture(int alloc, int baseMioLevel); + native void nAllocationUploadToBufferObject(int alloc); + native void nAllocationData(int id, int[] d, int sizeBytes); + native void nAllocationData(int id, float[] d, int sizeBytes); + native void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes); + native void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes); + native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes); + native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes); + native void nAllocationRead(int id, int[] d); + native void nAllocationRead(int id, float[] d); + native void nAllocationSubDataFromObject(int id, Type t, int offset, Object o); + + native void nTriangleMeshBegin(int vertex, int index); + native void nTriangleMeshAddVertex_XY (float x, float y); + native void nTriangleMeshAddVertex_XYZ (float x, float y, float z); + native void nTriangleMeshAddVertex_XY_ST (float x, float y, float s, float t); + native void nTriangleMeshAddVertex_XYZ_ST (float x, float y, float z, float s, float t); + native void nTriangleMeshAddVertex_XYZ_ST_NORM (float x, float y, float z, float s, float t, float nx, float ny, float nz); + native void nTriangleMeshAddTriangle(int i1, int i2, int i3); + native int nTriangleMeshCreate(); + + native void nAdapter1DBindAllocation(int ad, int alloc); + native void nAdapter1DSetConstraint(int ad, int dim, int value); + native void nAdapter1DData(int ad, int[] d); + native void nAdapter1DData(int ad, float[] d); + native void nAdapter1DSubData(int ad, int off, int count, int[] d); + native void nAdapter1DSubData(int ad, int off, int count, float[] d); + native int nAdapter1DCreate(); + + native void nAdapter2DBindAllocation(int ad, int alloc); + native void nAdapter2DSetConstraint(int ad, int dim, int value); + native void nAdapter2DData(int ad, int[] d); + native void nAdapter2DData(int ad, float[] d); + native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, int[] d); + native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, float[] d); + native int nAdapter2DCreate(); + + native void nScriptBindAllocation(int script, int alloc, int slot); + native void nScriptSetClearColor(int script, float r, float g, float b, float a); + native void nScriptSetClearDepth(int script, float depth); + native void nScriptSetClearStencil(int script, int stencil); + native void nScriptSetTimeZone(int script, byte[] timeZone); + native void nScriptSetType(int type, boolean writable, String name, int slot); + native void nScriptSetRoot(boolean isRoot); + + native void nScriptCBegin(); + native void nScriptCSetScript(byte[] script, int offset, int length); + native int nScriptCCreate(); + native void nScriptCAddDefineI32(String name, int value); + native void nScriptCAddDefineF(String name, float value); + + native void nSamplerBegin(); + native void nSamplerSet(int param, int value); + native int nSamplerCreate(); + + native void nProgramFragmentStoreBegin(int in, int out); + native void nProgramFragmentStoreDepthFunc(int func); + native void nProgramFragmentStoreDepthMask(boolean enable); + native void nProgramFragmentStoreColorMask(boolean r, boolean g, boolean b, boolean a); + native void nProgramFragmentStoreBlendFunc(int src, int dst); + native void nProgramFragmentStoreDither(boolean enable); + native int nProgramFragmentStoreCreate(); + + native void nProgramFragmentBegin(int in, int out, boolean pointSpriteEnable); + native void nProgramFragmentBindTexture(int vpf, int slot, int a); + native void nProgramFragmentBindSampler(int vpf, int slot, int s); + native void nProgramFragmentSetSlot(int slot, boolean enable, int env, int vt); + native int nProgramFragmentCreate(); + + native void nProgramVertexBindAllocation(int pv, int mID); + native void nProgramVertexBegin(int inID, int outID); + native void nProgramVertexSetTextureMatrixEnable(boolean enable); + native void nProgramVertexAddLight(int id); + native int nProgramVertexCreate(); + + native void nLightBegin(); + native void nLightSetIsMono(boolean isMono); + native void nLightSetIsLocal(boolean isLocal); + native int nLightCreate(); + native void nLightSetColor(int l, float r, float g, float b); + native void nLightSetPosition(int l, float x, float y, float z); + + native int nSimpleMeshCreate(int batchID, int idxID, int[] vtxID, int prim); + native void nSimpleMeshBindVertex(int id, int alloc, int slot); + native void nSimpleMeshBindIndex(int id, int alloc); + + native void nAnimationBegin(int attribCount, int keyframeCount); + native void nAnimationAdd(float time, float[] attribs); + native int nAnimationCreate(); + + private int mDev; + private int mContext; + @SuppressWarnings({"FieldCanBeLocal"}) + private Surface mSurface; + + private static boolean mElementsInitialized = false; + + /////////////////////////////////////////////////////////////////////////////////// + // + + public RenderScript(Surface sur, boolean useDepth) { + mSurface = sur; + mDev = nDeviceCreate(); + mContext = nContextCreate(mDev, mSurface, 0, useDepth); + + // TODO: This should be protected by a lock + if(!mElementsInitialized) { + Element.initPredefined(this); + mElementsInitialized = true; + } + } + + public void destroy() { + nContextDestroy(mContext); + mContext = 0; + + nDeviceDestroy(mDev); + mDev = 0; + } + + ////////////////////////////////////////////////////////////////////////////////// + // Triangle Mesh + + public class TriangleMesh extends BaseObj { + TriangleMesh(int id) { + super(RenderScript.this); + mID = id; + } + } + + public void triangleMeshBegin(Element vertex, Element index) { + nTriangleMeshBegin(vertex.mID, index.mID); + } + + public void triangleMeshAddVertex_XY(float x, float y) { + nTriangleMeshAddVertex_XY(x, y); + } + + public void triangleMeshAddVertex_XYZ(float x, float y, float z) { + nTriangleMeshAddVertex_XYZ(x, y, z); + } + + public void triangleMeshAddVertex_XY_ST(float x, float y, float s, float t) { + nTriangleMeshAddVertex_XY_ST(x, y, s, t); + } + + public void triangleMeshAddVertex_XYZ_ST(float x, float y, float z, float s, float t) { + nTriangleMeshAddVertex_XYZ_ST(x, y, z, s, t); + } + + public void triangleMeshAddVertex_XYZ_ST_NORM(float x, float y, float z, float s, float t, float nx, float ny, float nz) { + nTriangleMeshAddVertex_XYZ_ST_NORM(x, y, z, s, t, nx, ny, nz); + } + + public void triangleMeshAddTriangle(int i1, int i2, int i3) { + nTriangleMeshAddTriangle(i1, i2, i3); + } + + public TriangleMesh triangleMeshCreate() { + int id = nTriangleMeshCreate(); + return new TriangleMesh(id); + } + + ////////////////////////////////////////////////////////////////////////////////// + // File + + public class File extends BaseObj { + File(int id) { + super(RenderScript.this); + mID = id; + } + } + + public File fileOpen(String s) throws IllegalStateException, IllegalArgumentException + { + if(s.length() < 1) { + throw new IllegalArgumentException("fileOpen does not accept a zero length string."); + } + + try { + byte[] bytes = s.getBytes("UTF-8"); + int id = nFileOpen(bytes); + return new File(id); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + + /////////////////////////////////////////////////////////////////////////////////// + // Root state + + public void contextBindRootScript(Script s) { + int id = 0; + if(s != null) { + id = s.mID; + } + nContextBindRootScript(id); + } + + //public void contextBindSampler(Sampler s, int slot) { + //nContextBindSampler(s.mID); + //} + + public void contextBindProgramFragmentStore(ProgramStore pfs) { + nContextBindProgramFragmentStore(pfs.mID); + } + + public void contextBindProgramFragment(ProgramFragment pf) { + nContextBindProgramFragment(pf.mID); + } + + public void contextBindProgramVertex(ProgramVertex pf) { + nContextBindProgramVertex(pf.mID); + } + +} + + diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java new file mode 100644 index 0000000..5e0b110 --- /dev/null +++ b/graphics/java/android/renderscript/Sampler.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + + +import java.io.IOException; +import java.io.InputStream; + +import android.content.res.Resources; +import android.os.Bundle; +import android.util.Config; +import android.util.Log; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +/** + * @hide + * + **/ +public class Sampler extends BaseObj { + public enum Value { + NEAREST (0), + LINEAR (1), + LINEAR_MIP_LINEAR (2), + WRAP (3), + CLAMP (4); + + int mID; + Value(int id) { + mID = id; + } + } + + Sampler(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public static class Builder { + RenderScript mRS; + Value mMin; + Value mMag; + Value mWrapS; + Value mWrapT; + Value mWrapR; + + public Builder(RenderScript rs) { + mRS = rs; + mMin = Value.NEAREST; + mMag = Value.NEAREST; + mWrapS = Value.WRAP; + mWrapT = Value.WRAP; + mWrapR = Value.WRAP; + } + + public void setMin(Value v) { + mMin = v; + } + + public void setMag(Value v) { + mMag = v; + } + + public void setWrapS(Value v) { + mWrapS = v; + } + + public void setWrapT(Value v) { + mWrapT = v; + } + + public void setWrapR(Value v) { + mWrapR = v; + } + + static synchronized Sampler internalCreate(RenderScript rs, Builder b) { + rs.nSamplerBegin(); + rs.nSamplerSet(0, b.mMin.mID); + rs.nSamplerSet(1, b.mMag.mID); + rs.nSamplerSet(2, b.mWrapS.mID); + rs.nSamplerSet(3, b.mWrapT.mID); + rs.nSamplerSet(4, b.mWrapR.mID); + int id = rs.nSamplerCreate(); + return new Sampler(id, rs); + } + + public Sampler create() { + return internalCreate(mRS, this); + } + } + +} + diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java new file mode 100644 index 0000000..a402471 --- /dev/null +++ b/graphics/java/android/renderscript/Script.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +/** + * @hide + **/ +public class Script extends BaseObj { + public static final int MAX_SLOT = 16; + + boolean mIsRoot; + Type[] mTypes; + boolean[] mWritable; + + Script(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void bindAllocation(Allocation va, int slot) { + mRS.nScriptBindAllocation(mID, va.mID, slot); + } + + public void setClearColor(float r, float g, float b, float a) { + mRS.nScriptSetClearColor(mID, r, g, b, a); + } + + public void setClearDepth(float d) { + mRS.nScriptSetClearDepth(mID, d); + } + + public void setClearStencil(int stencil) { + mRS.nScriptSetClearStencil(mID, stencil); + } + + public void setTimeZone(String timeZone) { + try { + mRS.nScriptSetTimeZone(mID, timeZone.getBytes("UTF-8")); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static class Builder { + RenderScript mRS; + boolean mIsRoot = false; + Type[] mTypes; + String[] mNames; + boolean[] mWritable; + + Builder(RenderScript rs) { + mRS = rs; + mTypes = new Type[MAX_SLOT]; + mNames = new String[MAX_SLOT]; + mWritable = new boolean[MAX_SLOT]; + } + + public void setType(Type t, int slot) { + mTypes[slot] = t; + mNames[slot] = null; + } + + public void setType(Type t, String name, int slot) { + mTypes[slot] = t; + mNames[slot] = name; + } + + public void setType(boolean writable, int slot) { + mWritable[slot] = writable; + } + + void transferCreate() { + mRS.nScriptSetRoot(mIsRoot); + for(int ct=0; ct < mTypes.length; ct++) { + if(mTypes[ct] != null) { + mRS.nScriptSetType(mTypes[ct].mID, mWritable[ct], mNames[ct], ct); + } + } + } + + void transferObject(Script s) { + s.mIsRoot = mIsRoot; + s.mTypes = mTypes; + } + + public void setRoot(boolean r) { + mIsRoot = r; + } + + } + +} + diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java new file mode 100644 index 0000000..bb99e23 --- /dev/null +++ b/graphics/java/android/renderscript/ScriptC.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import android.content.res.Resources; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map.Entry; +import java.util.HashMap; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +/** + * @hide + **/ +public class ScriptC extends Script { + private static final String TAG = "ScriptC"; + + ScriptC(int id, RenderScript rs) { + super(id, rs); + } + + public static class Builder extends Script.Builder { + byte[] mProgram; + int mProgramLength; + HashMap<String,Integer> mIntDefines = new HashMap(); + HashMap<String,Float> mFloatDefines = new HashMap(); + + public Builder(RenderScript rs) { + super(rs); + } + + public void setScript(String s) { + try { + mProgram = s.getBytes("UTF-8"); + mProgramLength = mProgram.length; + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public void setScript(Resources resources, int id) { + InputStream is = resources.openRawResource(id); + try { + try { + setScript(is); + } finally { + is.close(); + } + } catch(IOException e) { + throw new Resources.NotFoundException(); + } + } + + public void setScript(InputStream is) throws IOException { + byte[] buf = new byte[1024]; + int currentPos = 0; + while(true) { + int bytesLeft = buf.length - currentPos; + if (bytesLeft == 0) { + byte[] buf2 = new byte[buf.length * 2]; + System.arraycopy(buf, 0, buf2, 0, buf.length); + buf = buf2; + bytesLeft = buf.length - currentPos; + } + int bytesRead = is.read(buf, currentPos, bytesLeft); + if (bytesRead <= 0) { + break; + } + currentPos += bytesRead; + } + mProgram = buf; + mProgramLength = currentPos; + } + + static synchronized ScriptC internalCreate(Builder b) { + b.mRS.nScriptCBegin(); + b.transferCreate(); + + for (Entry<String,Integer> e: b.mIntDefines.entrySet()) { + b.mRS.nScriptCAddDefineI32(e.getKey(), e.getValue().intValue()); + } + for (Entry<String,Float> e: b.mFloatDefines.entrySet()) { + b.mRS.nScriptCAddDefineF(e.getKey(), e.getValue().floatValue()); + } + + b.mRS.nScriptCSetScript(b.mProgram, 0, b.mProgramLength); + + int id = b.mRS.nScriptCCreate(); + ScriptC obj = new ScriptC(id, b.mRS); + b.transferObject(obj); + + return obj; + } + + public void addDefine(String name, int value) { + mIntDefines.put(name, value); + } + + public void addDefine(String name, float value) { + mFloatDefines.put(name, value); + } + + /** + * Takes the all public static final fields for a class, and adds defines + * for them, using the name of the field as the name of the define. + */ + public void addDefines(Class cl) { + addDefines(cl.getFields(), (Modifier.STATIC | Modifier.FINAL | Modifier.PUBLIC), null); + } + + /** + * Takes the all public fields for an object, and adds defines + * for them, using the name of the field as the name of the define. + */ + public void addDefines(Object o) { + addDefines(o.getClass().getFields(), Modifier.PUBLIC, o); + } + + void addDefines(Field[] fields, int mask, Object o) { + for (Field f: fields) { + try { + if ((f.getModifiers() & mask) == mask) { + Class t = f.getType(); + if (t == int.class) { + mIntDefines.put(f.getName(), f.getInt(o)); + } + else if (t == float.class) { + mFloatDefines.put(f.getName(), f.getFloat(o)); + } + } + } catch (IllegalAccessException ex) { + // TODO: Do we want this log? + Log.d(TAG, "addDefines skipping field " + f.getName()); + } + } + } + + public ScriptC create() { + return internalCreate(this); + } + } +} + diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java new file mode 100644 index 0000000..5d87654 --- /dev/null +++ b/graphics/java/android/renderscript/SimpleMesh.java @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import android.util.Config; +import android.util.Log; + +/** + * @hide + * + **/ +public class SimpleMesh extends BaseObj { + Type[] mVertexTypes; + Type mIndexType; + //Type mBatcheType; + Primitive mPrimitive; + + SimpleMesh(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void bindVertexAllocation(Allocation a, int slot) { + mRS.nSimpleMeshBindVertex(mID, a.mID, slot); + } + + public void bindIndexAllocation(Allocation a) { + mRS.nSimpleMeshBindIndex(mID, a.mID); + } + + public Allocation createVertexAllocation(int slot) { + return Allocation.createTyped(mRS, mVertexTypes[slot]); + } + + public Allocation createIndexAllocation() { + return Allocation.createTyped(mRS, mIndexType); + } + + public Type getVertexType(int slot) { + return mVertexTypes[slot]; + } + + public Type getIndexType() { + return mIndexType; + } + + public static class Builder { + RenderScript mRS; + + class Entry { + Type t; + Element e; + int size; + } + + int mVertexTypeCount; + Entry[] mVertexTypes; + Entry mIndexType; + //Entry mBatchType; + Primitive mPrimitive; + + + public Builder(RenderScript rs) { + mRS = rs; + mVertexTypeCount = 0; + mVertexTypes = new Entry[16]; + mIndexType = new Entry(); + } + + public int addVertexType(Type t) throws IllegalStateException { + if(mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + int addedIndex = mVertexTypeCount; + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].t = t; + mVertexTypeCount++; + return addedIndex; + } + + public int addVertexType(Element e, int size) throws IllegalStateException { + if(mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + int addedIndex = mVertexTypeCount; + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].e = e; + mVertexTypes[mVertexTypeCount].size = size; + mVertexTypeCount++; + return addedIndex; + } + + public void setIndexType(Type t) { + mIndexType.t = t; + mIndexType.e = null; + mIndexType.size = 0; + } + + public void setIndexType(Element e, int size) { + mIndexType.t = null; + mIndexType.e = e; + mIndexType.size = size; + } + + public void setPrimitive(Primitive p) { + mPrimitive = p; + } + + + Type newType(Element e, int size) { + Type.Builder tb = new Type.Builder(mRS, e); + tb.add(Dimension.X, size); + return tb.create(); + } + + static synchronized SimpleMesh internalCreate(RenderScript rs, Builder b) { + Type[] toDestroy = new Type[18]; + int toDestroyCount = 0; + + int indexID = 0; + if(b.mIndexType.t != null) { + indexID = b.mIndexType.t.mID; + } else if(b.mIndexType.size != 0) { + b.mIndexType.t = b.newType(b.mIndexType.e, b.mIndexType.size); + indexID = b.mIndexType.t.mID; + toDestroy[toDestroyCount++] = b.mIndexType.t; + } + + int[] IDs = new int[b.mVertexTypeCount]; + for(int ct=0; ct < b.mVertexTypeCount; ct++) { + if(b.mVertexTypes[ct].t != null) { + IDs[ct] = b.mVertexTypes[ct].t.mID; + } else { + b.mVertexTypes[ct].t = b.newType(b.mVertexTypes[ct].e, b.mVertexTypes[ct].size); + IDs[ct] = b.mVertexTypes[ct].t.mID; + toDestroy[toDestroyCount++] = b.mVertexTypes[ct].t; + } + } + + int id = rs.nSimpleMeshCreate(0, indexID, IDs, b.mPrimitive.mID); + for(int ct=0; ct < toDestroyCount; ct++) { + toDestroy[ct].destroy(); + } + + return new SimpleMesh(id, rs); + } + + public SimpleMesh create() { + Log.e("rs", "SimpleMesh create"); + SimpleMesh sm = internalCreate(mRS, this); + sm.mVertexTypes = new Type[mVertexTypeCount]; + for(int ct=0; ct < mVertexTypeCount; ct++) { + sm.mVertexTypes[ct] = mVertexTypes[ct].t; + } + sm.mIndexType = mIndexType.t; + sm.mPrimitive = mPrimitive; + return sm; + } + } + + public static class TriangleMeshBuilder { + float mVtxData[]; + int mVtxCount; + int mIndexData[]; + int mIndexCount; + RenderScript mRS; + Element mElement; + + int mVtxSize; + boolean mNorm; + boolean mTex; + + public TriangleMeshBuilder(RenderScript rs, int vtxSize, boolean norm, boolean tex) { + mRS = rs; + mVtxCount = 0; + mIndexCount = 0; + mVtxData = new float[128]; + mIndexData = new int[128]; + mVtxSize = vtxSize; + mNorm = norm; + mTex = tex; + + if(vtxSize < 2 || vtxSize > 3) { + throw new IllegalArgumentException("Vertex size out of range."); + } + } + + private void makeSpace(int count) { + if((mVtxCount + count) >= mVtxData.length) { + float t[] = new float[mVtxData.length * 2]; + System.arraycopy(mVtxData, 0, t, 0, mVtxData.length); + mVtxData = t; + } + } + + public void add_XY(float x, float y) { + if((mVtxSize != 2) || mNorm || mTex) { + throw new IllegalStateException("add mistmatch with declaired components."); + } + makeSpace(2); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + } + + public void add_XYZ(float x, float y, float z) { + if((mVtxSize != 3) || mNorm || mTex) { + throw new IllegalStateException("add mistmatch with declaired components."); + } + makeSpace(3); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = z; + } + + public void add_XY_ST(float x, float y, float s, float t) { + if((mVtxSize != 2) || mNorm || !mTex) { + throw new IllegalStateException("add mistmatch with declaired components."); + } + makeSpace(4); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = s; + mVtxData[mVtxCount++] = t; + } + + public void add_XYZ_ST(float x, float y, float z, float s, float t) { + if((mVtxSize != 3) || mNorm || !mTex) { + throw new IllegalStateException("add mistmatch with declaired components."); + } + makeSpace(5); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = z; + mVtxData[mVtxCount++] = s; + mVtxData[mVtxCount++] = t; + } + + public void add_XYZ_ST_NORM(float x, float y, float z, float s, float t, float nx, float ny, float nz) { + if((mVtxSize != 3) || !mNorm || !mTex) { + throw new IllegalStateException("add mistmatch with declaired components."); + } + makeSpace(8); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = z; + mVtxData[mVtxCount++] = s; + mVtxData[mVtxCount++] = t; + mVtxData[mVtxCount++] = nx; + mVtxData[mVtxCount++] = ny; + mVtxData[mVtxCount++] = nz; + } + + public void addTriangle(int idx1, int idx2, int idx3) { + if((mIndexCount + 3) >= mIndexData.length) { + int t[] = new int[mIndexData.length * 2]; + System.arraycopy(mIndexData, 0, t, 0, mIndexData.length); + mIndexData = t; + } + mIndexData[mIndexCount++] = idx1; + mIndexData[mIndexCount++] = idx2; + mIndexData[mIndexCount++] = idx3; + } + + public SimpleMesh create() { + Element.Builder b = new Element.Builder(mRS); + int floatCount = mVtxSize; + if(mVtxSize == 2) { + b.addFloatXY(); + } else { + b.addFloatXYZ(); + } + if(mTex) { + floatCount += 2; + b.addFloatST(); + } + if(mNorm) { + floatCount += 3; + b.addFloatNorm(); + } + mElement = b.create(); + + Builder smb = new Builder(mRS); + smb.addVertexType(mElement, mVtxCount / floatCount); + smb.setIndexType(Element.INDEX_16, mIndexCount); + smb.setPrimitive(Primitive.TRIANGLE); + SimpleMesh sm = smb.create(); + + Allocation vertexAlloc = sm.createVertexAllocation(0); + Allocation indexAlloc = sm.createIndexAllocation(); + sm.bindVertexAllocation(vertexAlloc, 0); + sm.bindIndexAllocation(indexAlloc); + + vertexAlloc.data(mVtxData); + vertexAlloc.uploadToBufferObject(); + + // This is safe because length is a pow2 + for(int ct=0; ct < (mIndexCount+1); ct += 2) { + mIndexData[ct >> 1] = mIndexData[ct] | (mIndexData[ct+1] << 16); + } + indexAlloc.data(mIndexData); + indexAlloc.uploadToBufferObject(); + + return sm; + } + } +} + diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java new file mode 100644 index 0000000..b6b7adf --- /dev/null +++ b/graphics/java/android/renderscript/Type.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.renderscript; + +import java.lang.reflect.Field; + +/** + * @hide + * + **/ +public class Type extends BaseObj { + Dimension[] mDimensions; + int[] mValues; + Element mElement; + private int mNativeCache; + Class mJavaClass; + + + Type(int id, RenderScript rs) { + super(rs); + mID = id; + mNativeCache = 0; + } + + protected void finalize() throws Throwable { + if(mNativeCache != 0) { + mRS.nTypeFinalDestroy(this); + mNativeCache = 0; + } + super.finalize(); + } + + public static Type createFromClass(RenderScript rs, Class c, int size) { + Element e = Element.createFromClass(rs, c); + Builder b = new Builder(rs, e); + b.add(Dimension.X, size); + Type t = b.create(); + e.destroy(); + + // native fields + { + Field[] fields = c.getFields(); + int[] arTypes = new int[fields.length]; + int[] arBits = new int[fields.length]; + + for(int ct=0; ct < fields.length; ct++) { + Field f = fields[ct]; + Class fc = f.getType(); + if(fc == int.class) { + arTypes[ct] = Element.DataType.SIGNED.mID; + arBits[ct] = 32; + } else if(fc == short.class) { + arTypes[ct] = Element.DataType.SIGNED.mID; + arBits[ct] = 16; + } else if(fc == byte.class) { + arTypes[ct] = Element.DataType.SIGNED.mID; + arBits[ct] = 8; + } else if(fc == float.class) { + arTypes[ct] = Element.DataType.FLOAT.mID; + arBits[ct] = 32; + } else { + throw new IllegalArgumentException("Unkown field type"); + } + } + rs.nTypeSetupFields(t, arTypes, arBits, fields); + } + t.mJavaClass = c; + return t; + } + + public static Type createFromClass(RenderScript rs, Class c, int size, String scriptName) { + Type t = createFromClass(rs, c, size); + t.setName(scriptName); + return t; + } + + + public static class Builder { + RenderScript mRS; + Entry[] mEntries; + int mEntryCount; + Element mElement; + + class Entry { + Dimension mDim; + int mValue; + } + + public Builder(RenderScript rs, Element e) { + mRS = rs; + mEntries = new Entry[4]; + mElement = e; + } + + public void add(Dimension d, int value) { + if(mEntries.length >= mEntryCount) { + Entry[] en = new Entry[mEntryCount + 8]; + System.arraycopy(mEntries, 0, en, 0, mEntries.length); + mEntries = en; + } + mEntries[mEntryCount] = new Entry(); + mEntries[mEntryCount].mDim = d; + mEntries[mEntryCount].mValue = value; + mEntryCount++; + } + + static synchronized Type internalCreate(RenderScript rs, Builder b) { + rs.nTypeBegin(b.mElement.mID); + for (int ct=0; ct < b.mEntryCount; ct++) { + Entry en = b.mEntries[ct]; + rs.nTypeAdd(en.mDim.mID, en.mValue); + } + int id = rs.nTypeCreate(); + return new Type(id, rs); + } + + public Type create() { + Type t = internalCreate(mRS, this); + t.mElement = mElement; + t.mDimensions = new Dimension[mEntryCount]; + t.mValues = new int[mEntryCount]; + for(int ct=0; ct < mEntryCount; ct++) { + t.mDimensions[ct] = mEntries[ct].mDim; + t.mValues[ct] = mEntries[ct].mValue; + } + return t; + } + } + +} diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk new file mode 100644 index 0000000..799fcbb --- /dev/null +++ b/graphics/jni/Android.mk @@ -0,0 +1,45 @@ + +# libRS needs libacc, which isn't 64-bit clean, and so can't be built +# for the simulator on gHardy, and therefore libRS needs to be excluded +# from the simulator as well, and so in turn librs_jni needs to be +# excluded. +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + android_renderscript_RenderScript.cpp + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + libacc \ + libnativehelper \ + libRS \ + libcutils \ + libskia \ + libutils \ + libui + +LOCAL_STATIC_LIBRARIES := + +rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRS,,) + +LOCAL_C_INCLUDES += \ + $(JNI_H_INCLUDE) \ + $(LOCAL_PATH)/../../libs/rs \ + $(rs_generated_include_dir) \ + $(call include-path-for, corecg graphics) + +LOCAL_CFLAGS += + +LOCAL_LDLIBS := -lpthread +LOCAL_ADDITIONAL_DEPENDENCIES := $(addprefix $(rs_generated_include_dir)/,rsgApiFuncDecl.h) +LOCAL_MODULE:= librs_jni +LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source) +LOCAL_MODULE_TAGS := optional +LOCAL_REQUIRED_MODULES := libRS + +include $(BUILD_SHARED_LIBRARY) + +endif #simulator diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp new file mode 100644 index 0000000..a94ccb1 --- /dev/null +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -0,0 +1,1384 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "libRS_jni" + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <math.h> +#include <utils/misc.h> + +#include <ui/Surface.h> + +#include <core/SkBitmap.h> +#include <core/SkPixelRef.h> +#include <core/SkStream.h> +#include <core/SkTemplates.h> +#include <images/SkImageDecoder.h> + +#include <utils/Asset.h> +#include <utils/ResourceTypes.h> + +#include "jni.h" +#include "JNIHelp.h" +#include "android_runtime/AndroidRuntime.h" + +#include <RenderScript.h> +#include <RenderScriptEnv.h> + +//#define LOG_API LOGE +#define LOG_API(...) + +using namespace android; + +// --------------------------------------------------------------------------- + +static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) +{ + jclass npeClazz = env->FindClass(exc); + env->ThrowNew(npeClazz, msg); +} + +static jfieldID gContextId = 0; +static jfieldID gNativeBitmapID = 0; +static jfieldID gTypeNativeCache = 0; + +static RsElement g_A_8 = NULL; +static RsElement g_RGBA_4444 = NULL; +static RsElement g_RGBA_8888 = NULL; +static RsElement g_RGB_565 = NULL; + +static void _nInit(JNIEnv *_env, jclass _this) +{ + gContextId = _env->GetFieldID(_this, "mContext", "I"); + + jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); + gNativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); + + jclass typeClass = _env->FindClass("android/renderscript/Type"); + gTypeNativeCache = _env->GetFieldID(typeClass, "mNativeCache", "I"); +} + +static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, jint rgba8888, jint rgb565) +{ + g_A_8 = reinterpret_cast<RsElement>(a8); + g_RGBA_4444 = reinterpret_cast<RsElement>(rgba4444); + g_RGBA_8888 = reinterpret_cast<RsElement>(rgba8888); + g_RGB_565 = reinterpret_cast<RsElement>(rgb565); +} + +// --------------------------------------------------------------------------- + +static void +nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAssignName, con(%p), obj(%p)", con, (void *)obj); + + jint len = _env->GetArrayLength(str); + jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); + rsAssignName(con, (void *)obj, (const char *)cptr, len); + _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); +} + +static void +nObjDestroy(JNIEnv *_env, jobject _this, jint obj) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nObjDestroy, con(%p) obj(%p)", con, (void *)obj); + rsObjDestroy(con, (void *)obj); +} + +static void +nObjDestroyOOB(JNIEnv *_env, jobject _this, jint obj) +{ + // This function only differs from nObjDestroy in that it calls the + // special Out Of Band version of ObjDestroy which is thread safe. + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nObjDestroyOOB, con(%p) obj(%p)", con, (void *)obj); + rsObjDestroyOOB(con, (void *)obj); +} + +static jint +nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nFileOpen, con(%p)", con); + + jint len = _env->GetArrayLength(str); + jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0); + jint ret = (jint)rsFileOpen(con, (const char *)cptr, len); + _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); + return ret; +} + +// --------------------------------------------------------------------------- + +static jint +nDeviceCreate(JNIEnv *_env, jobject _this) +{ + LOG_API("nDeviceCreate"); + return (jint)rsDeviceCreate(); +} + +static void +nDeviceDestroy(JNIEnv *_env, jobject _this, jint dev) +{ + LOG_API("nDeviceDestroy"); + return rsDeviceDestroy((RsDevice)dev); +} + +static jint +nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver, jboolean useDepth) +{ + LOG_API("nContextCreate"); + + if (wnd == NULL) { + not_valid_surface: + doThrow(_env, "java/lang/IllegalArgumentException", + "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface"); + return 0; + } + jclass surface_class = _env->FindClass("android/view/Surface"); + jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I"); + Surface * window = (Surface*)_env->GetIntField(wnd, surfaceFieldID); + if (window == NULL) + goto not_valid_surface; + + return (jint)rsContextCreate((RsDevice)dev, window, ver, useDepth); +} + +static void +nContextDestroy(JNIEnv *_env, jobject _this, jint con) +{ + LOG_API("nContextDestroy, con(%p)", (RsContext)con); + return rsContextDestroy((RsContext)con); +} + + +static void +nElementBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementBegin, con(%p)", con); + rsElementBegin(con); +} + + +static void +nElementAdd(JNIEnv *_env, jobject _this, jint kind, jint type, jint norm, jint bits, jstring name) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* n = NULL; + if (name) { + n = _env->GetStringUTFChars(name, NULL); + } + LOG_API("nElementAdd, con(%p), kind(%i), type(%i), norm(%i), bits(%i)", con, kind, type, norm, bits); + rsElementAdd(con, (RsDataKind)kind, (RsDataType)type, norm != 0, (size_t)bits, n); + if (n) { + _env->ReleaseStringUTFChars(name, n); + } +} + +static jint +nElementCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementCreate, con(%p)", con); + return (jint)rsElementCreate(con); +} + +// ----------------------------------- + +static void +nTypeBegin(JNIEnv *_env, jobject _this, jint eID) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeBegin, con(%p) e(%p)", con, (RsElement)eID); + rsTypeBegin(con, (RsElement)eID); +} + +static void +nTypeAdd(JNIEnv *_env, jobject _this, jint dim, jint val) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeAdd, con(%p) dim(%i), val(%i)", con, dim, val); + rsTypeAdd(con, (RsDimension)dim, val); +} + +static jint +nTypeCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeCreate, con(%p)", con); + return (jint)rsTypeCreate(con); +} + +static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) +{ + ((int32_t *)buffer)[0] = _env->GetIntField(_obj, _field); + return ((uint8_t *)buffer) + 4; +} + +static void * SF_LoadShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) +{ + ((int16_t *)buffer)[0] = _env->GetShortField(_obj, _field); + return ((uint8_t *)buffer) + 2; +} + +static void * SF_LoadByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) +{ + ((int8_t *)buffer)[0] = _env->GetByteField(_obj, _field); + return ((uint8_t *)buffer) + 1; +} + +static void * SF_LoadFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) +{ + ((float *)buffer)[0] = _env->GetFloatField(_obj, _field); + return ((uint8_t *)buffer) + 4; +} + +struct TypeFieldCache { + jfieldID field; + int bits; + void * (*ptr)(JNIEnv *, jobject, jfieldID, void *buffer); +}; + +struct TypeCache { + int fieldCount; + int size; + TypeFieldCache fields[1]; +}; + +//{"nTypeFinalDestroy", "(Landroid/renderscript/Type;)V", (void*)nTypeFinalDestroy }, +static void +nTypeFinalDestroy(JNIEnv *_env, jobject _this, jobject _type) +{ + TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache); + free(tc); +} + +// native void nTypeSetupFields(Type t, int[] types, int[] bits, Field[] IDs); +static void +nTypeSetupFields(JNIEnv *_env, jobject _this, jobject _type, jintArray _types, jintArray _bits, jobjectArray _IDs) +{ + int fieldCount = _env->GetArrayLength(_types); + size_t structSize = sizeof(TypeCache) + (sizeof(TypeFieldCache) * (fieldCount-1)); + TypeCache *tc = (TypeCache *)malloc(structSize); + memset(tc, 0, structSize); + + TypeFieldCache *tfc = &tc->fields[0]; + tc->fieldCount = fieldCount; + _env->SetIntField(_type, gTypeNativeCache, (jint)tc); + + jint *fType = _env->GetIntArrayElements(_types, NULL); + jint *fBits = _env->GetIntArrayElements(_bits, NULL); + for (int ct=0; ct < fieldCount; ct++) { + jobject field = _env->GetObjectArrayElement(_IDs, ct); + tfc[ct].field = _env->FromReflectedField(field); + tfc[ct].bits = fBits[ct]; + + switch(fType[ct]) { + case RS_TYPE_FLOAT: + tfc[ct].ptr = SF_LoadFloat; + break; + case RS_TYPE_UNSIGNED: + case RS_TYPE_SIGNED: + switch(tfc[ct].bits) { + case 32: tfc[ct].ptr = SF_LoadInt; break; + case 16: tfc[ct].ptr = SF_LoadShort; break; + case 8: tfc[ct].ptr = SF_LoadByte; break; + } + break; + } + tc->size += 4; + } + + _env->ReleaseIntArrayElements(_types, fType, JNI_ABORT); + _env->ReleaseIntArrayElements(_bits, fBits, JNI_ABORT); +} + + +// ----------------------------------- + +static jint +nAllocationCreateTyped(JNIEnv *_env, jobject _this, jint e) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationCreateTyped, con(%p), e(%p)", con, (RsElement)e); + return (jint) rsAllocationCreateTyped(con, (RsElement)e); +} + +static jint +nAllocationCreateSized(JNIEnv *_env, jobject _this, jint e, jint count) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationCreateSized, con(%p), e(%p), count(%i)", con, (RsElement)e, count); + return (jint) rsAllocationCreateSized(con, (RsElement)e, count); +} + +static void +nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationUploadToTexture, con(%p), a(%p), mip(%i)", con, (RsAllocation)a, mip); + rsAllocationUploadToTexture(con, (RsAllocation)a, mip); +} + +static void +nAllocationUploadToBufferObject(JNIEnv *_env, jobject _this, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationUploadToBufferObject, con(%p), a(%p)", con, (RsAllocation)a); + rsAllocationUploadToBufferObject(con, (RsAllocation)a); +} + +static RsElement SkBitmapToPredefined(SkBitmap::Config cfg) +{ + switch (cfg) { + case SkBitmap::kA8_Config: + return g_A_8; + case SkBitmap::kARGB_4444_Config: + return g_RGBA_4444; + case SkBitmap::kARGB_8888_Config: + return g_RGBA_8888; + case SkBitmap::kRGB_565_Config: + return g_RGB_565; + + default: + break; + } + // If we don't have a conversion mark it as a user type. + LOGE("Unsupported bitmap type"); + return NULL; +} + +static int +nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + SkBitmap::Config config = bitmap.getConfig(); + + RsElement e = SkBitmapToPredefined(config); + if (e) { + bitmap.lockPixels(); + const int w = bitmap.width(); + const int h = bitmap.height(); + const void* ptr = bitmap.getPixels(); + jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr); + bitmap.unlockPixels(); + return id; + } + return 0; +} + +static int +nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jint native_asset) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + + Asset* asset = reinterpret_cast<Asset*>(native_asset); + SkBitmap bitmap; + SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(), + &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode); + + SkBitmap::Config config = bitmap.getConfig(); + + RsElement e = SkBitmapToPredefined(config); + + if (e) { + bitmap.lockPixels(); + const int w = bitmap.width(); + const int h = bitmap.height(); + const void* ptr = bitmap.getPixels(); + jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr); + bitmap.unlockPixels(); + return id; + } + return 0; +} + +static int +nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + SkBitmap const * nativeBitmap = + (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID); + const SkBitmap& bitmap(*nativeBitmap); + SkBitmap::Config config = bitmap.getConfig(); + + RsElement e = SkBitmapToPredefined(config); + + if (e) { + bitmap.lockPixels(); + const int w = bitmap.width(); + const int h = bitmap.height(); + const void* ptr = bitmap.getPixels(); + jint id = (jint)rsAllocationCreateFromBitmapBoxed(con, w, h, (RsElement)dstFmt, e, genMips, ptr); + bitmap.unlockPixels(); + return id; + } + return 0; +} + + +static void +nAllocationData_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationData_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationData_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocationData(con, (RsAllocation)alloc, ptr, sizeBytes); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData1D_i(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jintArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData1D_f(JNIEnv *_env, jobject _this, jint alloc, jint offset, jint count, jfloatArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAllocation)alloc, offset, count, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocation1DSubData(con, (RsAllocation)alloc, offset, count, ptr, sizeBytes); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData2D_i(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jintArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes); + _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationSubData2D_f(JNIEnv *_env, jobject _this, jint alloc, jint xoff, jint yoff, jint w, jint h, jfloatArray data, int sizeBytes) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocation2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, w, h, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocation2DSubData(con, (RsAllocation)alloc, xoff, yoff, w, h, ptr, sizeBytes); + _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT); +} + +static void +nAllocationRead_i(JNIEnv *_env, jobject _this, jint alloc, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAllocationRead(con, (RsAllocation)alloc, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0); +} + +static void +nAllocationRead_f(JNIEnv *_env, jobject _this, jint alloc, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAllocationRead(con, (RsAllocation)alloc, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0); +} + + +//{"nAllocationDataFromObject", "(ILandroid/renderscript/Type;Ljava/lang/Object;)V", (void*)nAllocationDataFromObject }, +static void +nAllocationSubDataFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _type, jint offset, jobject _o) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationDataFromObject con(%p), alloc(%p)", con, (RsAllocation)alloc); + + const TypeCache *tc = (TypeCache *)_env->GetIntField(_type, gTypeNativeCache); + + void * bufAlloc = malloc(tc->size); + void * buf = bufAlloc; + for (int ct=0; ct < tc->fieldCount; ct++) { + const TypeFieldCache *tfc = &tc->fields[ct]; + buf = tfc->ptr(_env, _o, tfc->field, buf); + } + rsAllocation1DSubData(con, (RsAllocation)alloc, offset, 1, bufAlloc, tc->size); + const uint32_t * tmp = (const uint32_t *)bufAlloc; + free(bufAlloc); +} + +// ----------------------------------- + +static void +nTriangleMeshBegin(JNIEnv *_env, jobject _this, jint v, jint i) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshBegin, con(%p), vertex(%p), index(%p)", con, (RsElement)v, (RsElement)i); + rsTriangleMeshBegin(con, (RsElement)v, (RsElement)i); +} + +static void +nTriangleMeshAddVertex_XY(JNIEnv *_env, jobject _this, jfloat x, jfloat y) +{ + float v[] = {x, y}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XY, con(%p), x(%f), y(%f)", con, x, y); + rsTriangleMeshAddVertex(con, v); +} + +static void +nTriangleMeshAddVertex_XYZ(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z) +{ + float v[] = {x, y, z}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XYZ, con(%p), x(%f), y(%f), z(%f)", con, x, y, z); + rsTriangleMeshAddVertex(con, v); +} + +static void +nTriangleMeshAddVertex_XY_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat s, jfloat t) +{ + float v[] = {s, t, x, y}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XY_ST, con(%p), x(%f), y(%f), s(%f), t(%f)", con, x, y, s, t); + rsTriangleMeshAddVertex(con, v); +} + +static void +nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t) +{ + float v[] = {s, t, x, y, z}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t); + rsTriangleMeshAddVertex(con, v); +} + +static void +nTriangleMeshAddVertex_XYZ_ST_NORM(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t, jfloat nx, jfloat ny, jfloat nz) +{ + float v[] = {nx, ny, nz, s, t, x, y, z}; + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t); + rsTriangleMeshAddVertex(con, v); +} + +static void +nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshAddTriangle, con(%p), i1(%i), i2(%i), i3(%i)", con, i1, i2, i3); + rsTriangleMeshAddTriangle(con, i1, i2, i3); +} + +static jint +nTriangleMeshCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTriangleMeshCreate, con(%p)", con); + return (jint) rsTriangleMeshCreate(con); +} + +// ----------------------------------- + +static void +nAdapter1DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter1D)adapter, (RsAllocation)alloc); + rsAdapter1DBindAllocation(con, (RsAdapter1D)adapter, (RsAllocation)alloc); +} + +static void +nAdapter1DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter1D)adapter, dim, value); + rsAdapter1DSetConstraint(con, (RsAdapter1D)adapter, (RsDimension)dim, value); +} + +static void +nAdapter1DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter1DData(con, (RsAdapter1D)adapter, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DSubData_i, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter1D)adapter, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter1DData(con, (RsAdapter1D)adapter, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter1DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint offset, jint count, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter1DSubData_f, con(%p), adapter(%p), offset(%i), count(%i), len(%i)", con, (RsAdapter1D)adapter, offset, count, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter1DSubData(con, (RsAdapter1D)adapter, offset, count, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static jint +nAdapter1DCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter1DCreate, con(%p)", con); + return (jint)rsAdapter1DCreate(con); +} + +// ----------------------------------- + +static void +nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc); + rsAdapter2DBindAllocation(con, (RsAdapter2D)adapter, (RsAllocation)alloc); +} + +static void +nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value); + rsAdapter2DSetConstraint(con, (RsAdapter2D)adapter, (RsDimension)dim, value); +} + +static void +nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter2DData(con, (RsAdapter2D)adapter, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter2DData(con, (RsAdapter2D)adapter, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", + con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter2DSubData(con, (RsAdapter2D)adapter, xoff, yoff, w, h, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", + con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter2DSubData(con, (RsAdapter1D)adapter, xoff, yoff, w, h, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static jint +nAdapter2DCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DCreate, con(%p)", con); + return (jint)rsAdapter2DCreate(con); +} + +// ----------------------------------- + +static void +nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptBindAllocation, con(%p), script(%p), alloc(%p), slot(%i)", con, (RsScript)script, (RsAllocation)alloc, slot); + rsScriptBindAllocation(con, (RsScript)script, (RsAllocation)alloc, slot); +} + +static void +nScriptSetClearColor(JNIEnv *_env, jobject _this, jint script, jfloat r, jfloat g, jfloat b, jfloat a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptSetClearColor, con(%p), s(%p), r(%f), g(%f), b(%f), a(%f)", con, (void *)script, r, g, b, a); + rsScriptSetClearColor(con, (RsScript)script, r, g, b, a); +} + +static void +nScriptSetClearDepth(JNIEnv *_env, jobject _this, jint script, jfloat d) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetClearDepth, con(%p), s(%p), depth(%f)", con, (void *)script, d); + rsScriptSetClearDepth(con, (RsScript)script, d); +} + +static void +nScriptSetClearStencil(JNIEnv *_env, jobject _this, jint script, jint stencil) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetClearStencil, con(%p), s(%p), stencil(%i)", con, (void *)script, stencil); + rsScriptSetClearStencil(con, (RsScript)script, stencil); +} + +static void +nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetTimeZone, con(%p), s(%p), timeZone(%s)", con, (void *)script, (const char *)timeZone); + + jint length = _env->GetArrayLength(timeZone); + jbyte* timeZone_ptr; + timeZone_ptr = (jbyte *) _env->GetPrimitiveArrayCritical(timeZone, (jboolean *)0); + + rsScriptSetTimeZone(con, (RsScript)script, (const char *)timeZone_ptr, length); + + if (timeZone_ptr) { + _env->ReleasePrimitiveArrayCritical(timeZone, timeZone_ptr, 0); + } +} + +static void +nScriptSetType(JNIEnv *_env, jobject _this, jint type, jboolean writable, jstring _str, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCAddType, con(%p), type(%p), writable(%i), slot(%i)", con, (RsType)type, writable, slot); + const char* n = NULL; + if (_str) { + n = _env->GetStringUTFChars(_str, NULL); + } + rsScriptSetType(con, (RsType)type, slot, writable, n); + if (n) { + _env->ReleaseStringUTFChars(_str, n); + } +} + +static void +nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot); + rsScriptSetRoot(con, isRoot); +} + +// ----------------------------------- + +static void +nScriptCBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCBegin, con(%p)", con); + rsScriptCBegin(con); +} + +static void +nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef, + jint offset, jint length) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("!!! nScriptCSetScript, con(%p)", con); + jint _exception = 0; + jint remaining; + jbyte* script_base = 0; + jbyte* script_ptr; + if (!scriptRef) { + _exception = 1; + //_env->ThrowNew(IAEClass, "script == null"); + goto exit; + } + if (offset < 0) { + _exception = 1; + //_env->ThrowNew(IAEClass, "offset < 0"); + goto exit; + } + if (length < 0) { + _exception = 1; + //_env->ThrowNew(IAEClass, "length < 0"); + goto exit; + } + remaining = _env->GetArrayLength(scriptRef) - offset; + if (remaining < length) { + _exception = 1; + //_env->ThrowNew(IAEClass, "length > script.length - offset"); + goto exit; + } + script_base = (jbyte *) + _env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0); + script_ptr = script_base + offset; + + rsScriptCSetText(con, (const char *)script_ptr, length); + +exit: + if (script_base) { + _env->ReleasePrimitiveArrayCritical(scriptRef, script_base, + _exception ? JNI_ABORT: 0); + } +} + +static jint +nScriptCCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nScriptCCreate, con(%p)", con); + return (jint)rsScriptCCreate(con); +} + +static void +nScriptCAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* n = _env->GetStringUTFChars(name, NULL); + LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value); + rsScriptCSetDefineI32(con, n, value); + _env->ReleaseStringUTFChars(name, n); +} + +static void +nScriptCAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* n = _env->GetStringUTFChars(name, NULL); + LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value); + rsScriptCSetDefineF(con, n, value); + _env->ReleaseStringUTFChars(name, n); +} + +// --------------------------------------------------------------------------- + +static void +nProgramFragmentStoreBegin(JNIEnv *_env, jobject _this, jint in, jint out) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramFragmentStoreBegin(con, (RsElement)in, (RsElement)out); +} + +static void +nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDepthFunc, con(%p), func(%i)", con, func); + rsProgramFragmentStoreDepthFunc(con, (RsDepthFunc)func); +} + +static void +nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDepthMask, con(%p), enable(%i)", con, enable); + rsProgramFragmentStoreDepthMask(con, enable); +} + +static void +nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a); + rsProgramFragmentStoreColorMask(con, r, g, b, a); +} + +static void +nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst); + rsProgramFragmentStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst); +} + +static void +nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreDither, con(%p), enable(%i)", con, enable); + rsProgramFragmentStoreDither(con, enable); +} + +static jint +nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentStoreCreate, con(%p)", con); + + return (jint)rsProgramFragmentStoreCreate(con); +} + +// --------------------------------------------------------------------------- + +static void +nProgramFragmentBegin(JNIEnv *_env, jobject _this, jint in, jint out, jboolean pointSpriteEnable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBegin, con(%p), in(%p), out(%p) PointSprite(%i)", con, (RsElement)in, (RsElement)out, pointSpriteEnable); + rsProgramFragmentBegin(con, (RsElement)in, (RsElement)out, pointSpriteEnable); +} + +static void +nProgramFragmentBindTexture(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBindTexture, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsAllocation)a); + rsProgramFragmentBindTexture(con, (RsProgramFragment)vpf, slot, (RsAllocation)a); +} + +static void +nProgramFragmentBindSampler(JNIEnv *_env, jobject _this, jint vpf, jint slot, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentBindSampler, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramFragment)vpf, slot, (RsSampler)a); + rsProgramFragmentBindSampler(con, (RsProgramFragment)vpf, slot, (RsSampler)a); +} + +static void +nProgramFragmentSetSlot(JNIEnv *_env, jobject _this, jint slot, jboolean enable, jint env, jint vt) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentSetType, con(%p), slot(%i), enable(%i), env(%i), vt(%p)", con, slot, enable, env, (RsType)vt); + rsProgramFragmentSetSlot(con, slot, enable, (RsTexEnvMode)env, (RsType)vt); +} + +static jint +nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramFragmentCreate, con(%p)", con); + return (jint)rsProgramFragmentCreate(con); +} + +// --------------------------------------------------------------------------- + +static void +nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramVertexBegin(con, (RsElement)in, (RsElement)out); +} + +static void +nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), a(%p)", con, (RsProgramVertex)vpv, (RsAllocation)a); + rsProgramVertexBindAllocation(con, (RsProgramFragment)vpv, (RsAllocation)a); +} + +static void +nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable); + rsProgramVertexSetTextureMatrixEnable(con, enable); +} + +static void +nProgramVertexAddLight(JNIEnv *_env, jobject _this, jint light) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexAddLight, con(%p), light(%p)", con, (RsLight)light); + rsProgramVertexAddLight(con, (RsLight)light); +} + +static jint +nProgramVertexCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nProgramVertexCreate, con(%p)", con); + return (jint)rsProgramVertexCreate(con); +} + + + +// --------------------------------------------------------------------------- + +static void +nContextBindRootScript(JNIEnv *_env, jobject _this, jint script) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindRootScript, con(%p), script(%p)", con, (RsScript)script); + rsContextBindRootScript(con, (RsScript)script); +} + +static void +nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindProgramFragmentStore, con(%p), pfs(%p)", con, (RsProgramFragmentStore)pfs); + rsContextBindProgramFragmentStore(con, (RsProgramFragmentStore)pfs); +} + +static void +nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindProgramFragment, con(%p), pf(%p)", con, (RsProgramFragment)pf); + rsContextBindProgramFragment(con, (RsProgramFragment)pf); +} + +static void +nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf); + rsContextBindProgramVertex(con, (RsProgramVertex)pf); +} + +static void +nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* n = _env->GetStringUTFChars(name, NULL); + LOG_API("nScriptCAddDefineI32, con(%p) name(%s) value(%d)", con, n, value); + rsContextSetDefineI32(con, n, value); + _env->ReleaseStringUTFChars(name, n); +} + +static void +nContextAddDefineF(JNIEnv *_env, jobject _this, jstring name, jfloat value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* n = _env->GetStringUTFChars(name, NULL); + LOG_API("nScriptCAddDefineF, con(%p) name(%s) value(%f)", con, n, value); + rsContextSetDefineF(con, n, value); + _env->ReleaseStringUTFChars(name, n); +} + + +// --------------------------------------------------------------------------- + +static void +nSamplerBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerBegin, con(%p)", con); + rsSamplerBegin(con); +} + +static void +nSamplerSet(JNIEnv *_env, jobject _this, jint p, jint v) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerSet, con(%p), param(%i), value(%i)", con, p, v); + rsSamplerSet(con, (RsSamplerParam)p, (RsSamplerValue)v); +} + +static jint +nSamplerCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSamplerCreate, con(%p)", con); + return (jint)rsSamplerCreate(con); +} + +// --------------------------------------------------------------------------- + +static void +nLightBegin(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightBegin, con(%p)", con); + rsLightBegin(con); +} + +static void +nLightSetIsMono(JNIEnv *_env, jobject _this, jboolean isMono) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightSetIsMono, con(%p), isMono(%i)", con, isMono); + rsLightSetMonochromatic(con, isMono); +} + +static void +nLightSetIsLocal(JNIEnv *_env, jobject _this, jboolean isLocal) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightSetIsLocal, con(%p), isLocal(%i)", con, isLocal); + rsLightSetLocal(con, isLocal); +} + +static jint +nLightCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightCreate, con(%p)", con); + return (jint)rsLightCreate(con); +} + +static void +nLightSetColor(JNIEnv *_env, jobject _this, jint light, float r, float g, float b) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightSetColor, con(%p), light(%p), r(%f), g(%f), b(%f)", con, (RsLight)light, r, g, b); + rsLightSetColor(con, (RsLight)light, r, g, b); +} + +static void +nLightSetPosition(JNIEnv *_env, jobject _this, jint light, float x, float y, float z) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nLightSetPosition, con(%p), light(%p), x(%f), y(%f), z(%f)", con, (RsLight)light, x, y, z); + rsLightSetPosition(con, (RsLight)light, x, y, z); +} + +// --------------------------------------------------------------------------- + +static jint +nSimpleMeshCreate(JNIEnv *_env, jobject _this, jint batchID, jint indexID, jintArray vtxIDs, jint primID) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(vtxIDs); + LOG_API("nSimpleMeshCreate, con(%p), batchID(%i), indexID(%i), vtxIDs.len(%i), primID(%i)", + con, batchID, indexID, len, primID); + jint *ptr = _env->GetIntArrayElements(vtxIDs, NULL); + int id = (int)rsSimpleMeshCreate(con, (void *)batchID, (void *)indexID, (void **)ptr, len, primID); + _env->ReleaseIntArrayElements(vtxIDs, ptr, 0/*JNI_ABORT*/); + return id; +} + +static void +nSimpleMeshBindVertex(JNIEnv *_env, jobject _this, jint s, jint alloc, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSimpleMeshBindVertex, con(%p), SimpleMesh(%p), Alloc(%p), slot(%i)", con, (RsSimpleMesh)s, (RsAllocation)alloc, slot); + rsSimpleMeshBindVertex(con, (RsSimpleMesh)s, (RsAllocation)alloc, slot); +} + +static void +nSimpleMeshBindIndex(JNIEnv *_env, jobject _this, jint s, jint alloc) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nSimpleMeshBindIndex, con(%p), SimpleMesh(%p), Alloc(%p)", con, (RsSimpleMesh)s, (RsAllocation)alloc); + rsSimpleMeshBindIndex(con, (RsSimpleMesh)s, (RsAllocation)alloc); +} + +// --------------------------------------------------------------------------- + + +static const char *classPathName = "android/renderscript/RenderScript"; + +static JNINativeMethod methods[] = { +{"_nInit", "()V", (void*)_nInit }, +{"nInitElements", "(IIII)V", (void*)nInitElements }, + +{"nDeviceCreate", "()I", (void*)nDeviceCreate }, +{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy }, +{"nContextCreate", "(ILandroid/view/Surface;IZ)I", (void*)nContextCreate }, +{"nContextDestroy", "(I)V", (void*)nContextDestroy }, +{"nAssignName", "(I[B)V", (void*)nAssignName }, +{"nObjDestroy", "(I)V", (void*)nObjDestroy }, +{"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB }, + +{"nFileOpen", "([B)I", (void*)nFileOpen }, + +{"nElementBegin", "()V", (void*)nElementBegin }, +{"nElementAdd", "(IIIILjava/lang/String;)V", (void*)nElementAdd }, +{"nElementCreate", "()I", (void*)nElementCreate }, + +{"nTypeBegin", "(I)V", (void*)nTypeBegin }, +{"nTypeAdd", "(II)V", (void*)nTypeAdd }, +{"nTypeCreate", "()I", (void*)nTypeCreate }, +{"nTypeFinalDestroy", "(Landroid/renderscript/Type;)V", (void*)nTypeFinalDestroy }, +{"nTypeSetupFields", "(Landroid/renderscript/Type;[I[I[Ljava/lang/reflect/Field;)V", (void*)nTypeSetupFields }, + +{"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped }, +{"nAllocationCreateSized", "(II)I", (void*)nAllocationCreateSized }, +{"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap }, +{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmapBoxed }, +{"nAllocationCreateFromAssetStream","(IZI)I", (void*)nAllocationCreateFromAssetStream }, +{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture }, +{"nAllocationUploadToBufferObject","(I)V", (void*)nAllocationUploadToBufferObject }, +{"nAllocationData", "(I[II)V", (void*)nAllocationData_i }, +{"nAllocationData", "(I[FI)V", (void*)nAllocationData_f }, +{"nAllocationSubData1D", "(III[II)V", (void*)nAllocationSubData1D_i }, +{"nAllocationSubData1D", "(III[FI)V", (void*)nAllocationSubData1D_f }, +{"nAllocationSubData2D", "(IIIII[II)V", (void*)nAllocationSubData2D_i }, +{"nAllocationSubData2D", "(IIIII[FI)V", (void*)nAllocationSubData2D_f }, +{"nAllocationRead", "(I[I)V", (void*)nAllocationRead_i }, +{"nAllocationRead", "(I[F)V", (void*)nAllocationRead_f }, +{"nAllocationSubDataFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubDataFromObject }, + +{"nTriangleMeshBegin", "(II)V", (void*)nTriangleMeshBegin }, +{"nTriangleMeshAddVertex_XY", "(FF)V", (void*)nTriangleMeshAddVertex_XY }, +{"nTriangleMeshAddVertex_XYZ", "(FFF)V", (void*)nTriangleMeshAddVertex_XYZ }, +{"nTriangleMeshAddVertex_XY_ST", "(FFFF)V", (void*)nTriangleMeshAddVertex_XY_ST }, +{"nTriangleMeshAddVertex_XYZ_ST", "(FFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST }, +{"nTriangleMeshAddVertex_XYZ_ST_NORM", "(FFFFFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST_NORM }, +{"nTriangleMeshAddTriangle", "(III)V", (void*)nTriangleMeshAddTriangle }, +{"nTriangleMeshCreate", "()I", (void*)nTriangleMeshCreate }, + +{"nAdapter1DBindAllocation", "(II)V", (void*)nAdapter1DBindAllocation }, +{"nAdapter1DSetConstraint", "(III)V", (void*)nAdapter1DSetConstraint }, +{"nAdapter1DData", "(I[I)V", (void*)nAdapter1DData_i }, +{"nAdapter1DData", "(I[F)V", (void*)nAdapter1DData_f }, +{"nAdapter1DSubData", "(III[I)V", (void*)nAdapter1DSubData_i }, +{"nAdapter1DSubData", "(III[F)V", (void*)nAdapter1DSubData_f }, +{"nAdapter1DCreate", "()I", (void*)nAdapter1DCreate }, + +{"nAdapter2DBindAllocation", "(II)V", (void*)nAdapter2DBindAllocation }, +{"nAdapter2DSetConstraint", "(III)V", (void*)nAdapter2DSetConstraint }, +{"nAdapter2DData", "(I[I)V", (void*)nAdapter2DData_i }, +{"nAdapter2DData", "(I[F)V", (void*)nAdapter2DData_f }, +{"nAdapter2DSubData", "(IIIII[I)V", (void*)nAdapter2DSubData_i }, +{"nAdapter2DSubData", "(IIIII[F)V", (void*)nAdapter2DSubData_f }, +{"nAdapter2DCreate", "()I", (void*)nAdapter2DCreate }, + +{"nScriptBindAllocation", "(III)V", (void*)nScriptBindAllocation }, +{"nScriptSetClearColor", "(IFFFF)V", (void*)nScriptSetClearColor }, +{"nScriptSetClearDepth", "(IF)V", (void*)nScriptSetClearDepth }, +{"nScriptSetClearStencil", "(II)V", (void*)nScriptSetClearStencil }, +{"nScriptSetTimeZone", "(I[B)V", (void*)nScriptSetTimeZone }, +{"nScriptSetType", "(IZLjava/lang/String;I)V", (void*)nScriptSetType }, +{"nScriptSetRoot", "(Z)V", (void*)nScriptSetRoot }, + +{"nScriptCBegin", "()V", (void*)nScriptCBegin }, +{"nScriptCSetScript", "([BII)V", (void*)nScriptCSetScript }, +{"nScriptCCreate", "()I", (void*)nScriptCCreate }, +{"nScriptCAddDefineI32", "(Ljava/lang/String;I)V", (void*)nScriptCAddDefineI32 }, +{"nScriptCAddDefineF", "(Ljava/lang/String;F)V", (void*)nScriptCAddDefineF }, + +{"nProgramFragmentStoreBegin", "(II)V", (void*)nProgramFragmentStoreBegin }, +{"nProgramFragmentStoreDepthFunc", "(I)V", (void*)nProgramFragmentStoreDepthFunc }, +{"nProgramFragmentStoreDepthMask", "(Z)V", (void*)nProgramFragmentStoreDepthMask }, +{"nProgramFragmentStoreColorMask", "(ZZZZ)V", (void*)nProgramFragmentStoreColorMask }, +{"nProgramFragmentStoreBlendFunc", "(II)V", (void*)nProgramFragmentStoreBlendFunc }, +{"nProgramFragmentStoreDither", "(Z)V", (void*)nProgramFragmentStoreDither }, +{"nProgramFragmentStoreCreate", "()I", (void*)nProgramFragmentStoreCreate }, + +{"nProgramFragmentBegin", "(IIZ)V", (void*)nProgramFragmentBegin }, +{"nProgramFragmentBindTexture", "(III)V", (void*)nProgramFragmentBindTexture }, +{"nProgramFragmentBindSampler", "(III)V", (void*)nProgramFragmentBindSampler }, +{"nProgramFragmentSetSlot", "(IZII)V", (void*)nProgramFragmentSetSlot }, +{"nProgramFragmentCreate", "()I", (void*)nProgramFragmentCreate }, + +{"nProgramVertexBindAllocation", "(II)V", (void*)nProgramVertexBindAllocation }, +{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin }, +{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable }, +{"nProgramVertexAddLight", "(I)V", (void*)nProgramVertexAddLight }, +{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate }, + +{"nLightBegin", "()V", (void*)nLightBegin }, +{"nLightSetIsMono", "(Z)V", (void*)nLightSetIsMono }, +{"nLightSetIsLocal", "(Z)V", (void*)nLightSetIsLocal }, +{"nLightCreate", "()I", (void*)nLightCreate }, +{"nLightSetColor", "(IFFF)V", (void*)nLightSetColor }, +{"nLightSetPosition", "(IFFF)V", (void*)nLightSetPosition }, + +{"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript }, +{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore }, +{"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment }, +{"nContextBindProgramVertex", "(I)V", (void*)nContextBindProgramVertex }, + +{"nSamplerBegin", "()V", (void*)nSamplerBegin }, +{"nSamplerSet", "(II)V", (void*)nSamplerSet }, +{"nSamplerCreate", "()I", (void*)nSamplerCreate }, + +{"nSimpleMeshCreate", "(II[II)I", (void*)nSimpleMeshCreate }, +{"nSimpleMeshBindVertex", "(III)V", (void*)nSimpleMeshBindVertex }, +{"nSimpleMeshBindIndex", "(II)V", (void*)nSimpleMeshBindIndex }, + +}; + +static int registerFuncs(JNIEnv *_env) +{ + return android::AndroidRuntime::registerNativeMethods( + _env, classPathName, methods, NELEM(methods)); +} + +// --------------------------------------------------------------------------- + +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + JNIEnv* env = NULL; + jint result = -1; + + if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { + LOGE("ERROR: GetEnv failed\n"); + goto bail; + } + assert(env != NULL); + + if (registerFuncs(env) < 0) { + LOGE("ERROR: MediaPlayer native registration failed\n"); + goto bail; + } + + /* success -- return valid version number */ + result = JNI_VERSION_1_4; + +bail: + return result; +} |
