diff options
Diffstat (limited to 'graphics')
66 files changed, 3848 insertions, 1131 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 7ca3741..d9ee3ec 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -19,12 +19,16 @@ package android.graphics; import android.os.Parcel; import android.os.Parcelable; import android.util.DisplayMetrics; +import android.util.Finalizers; import java.io.OutputStream; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; public final class Bitmap implements Parcelable { /** @@ -35,9 +39,13 @@ public final class Bitmap implements Parcelable { */ public static final int DENSITY_NONE = 0; - // Note: mNativeBitmap is used by FaceDetector_jni.cpp - // Don't change/rename without updating FaceDetector_jni.cpp - private final int mNativeBitmap; + /** + * Note: mNativeBitmap is used by FaceDetector_jni.cpp + * Don't change/rename without updating FaceDetector_jni.cpp + * + * @hide + */ + public final int mNativeBitmap; private final boolean mIsMutable; private byte[] mNinePatchChunk; // may be null @@ -51,7 +59,7 @@ public final class Bitmap implements Parcelable { private static volatile Matrix sScaleMatrix; private static volatile int sDefaultDensity = -1; - + /** * For backwards compatibility, allows the app layer to change the default * density when running old apps. @@ -77,8 +85,7 @@ public final class Bitmap implements Parcelable { This can be called from JNI code. */ - private Bitmap(int nativeBitmap, boolean isMutable, byte[] ninePatchChunk, - int density) { + private Bitmap(int nativeBitmap, boolean isMutable, byte[] ninePatchChunk, int density) { if (nativeBitmap == 0) { throw new RuntimeException("internal error: native bitmap is 0"); } @@ -90,6 +97,13 @@ public final class Bitmap implements Parcelable { if (density >= 0) { mDensity = density; } + + // If the finalizers queue is null, we are running in zygote and the + // bitmap will never be reclaimed, so we don't need to run our native + // destructor + if (Finalizers.getQueue() != null) { + new BitmapFinalizer(this); + } } /** @@ -172,6 +186,19 @@ public final class Bitmap implements Parcelable { } /** + * Returns the generation ID of this bitmap. The generation ID changes + * whenever the bitmap is modified. This can be used as an efficient way to + * check if a bitmap has changed. + * + * @return The current generation ID for this bitmap. + * + * @hide + */ + public int getGenerationId() { + return nativeGenerationId(mNativeBitmap); + } + + /** * This is called by methods that want to throw an exception if the bitmap * has already been recycled. */ @@ -999,12 +1026,22 @@ public final class Bitmap implements Parcelable { nativePrepareToDraw(mNativeBitmap); } - @Override - protected void finalize() throws Throwable { - try { + private static class BitmapFinalizer extends Finalizers.ReclaimableReference<Bitmap> { + private static final Set<BitmapFinalizer> sFinalizers = Collections.synchronizedSet( + new HashSet<BitmapFinalizer>()); + + private int mNativeBitmap; + + BitmapFinalizer(Bitmap b) { + super(b, Finalizers.getQueue()); + mNativeBitmap = b.mNativeBitmap; + sFinalizers.add(this); + } + + @Override + public void reclaim() { nativeDestructor(mNativeBitmap); - } finally { - super.finalize(); + sFinalizers.remove(this); } } @@ -1041,6 +1078,7 @@ public final class Bitmap implements Parcelable { private static native void nativeCopyPixelsToBuffer(int nativeBitmap, Buffer dst); private static native void nativeCopyPixelsFromBuffer(int nb, Buffer src); + private static native int nativeGenerationId(int nativeBitmap); private static native Bitmap nativeCreateFromParcel(Parcel p); // returns true on success diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 2313f4c..320fc4d 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -69,8 +69,11 @@ public class BitmapFactory { * the decoder will try to pick the best matching config based on the * system's screen depth, and characteristics of the original image such * as if it has per-pixel alpha (requiring a config that also does). + * + * The configuration is set to {@link android.graphics.Bitmap.Config#ARGB_8888} + * by default. */ - public Bitmap.Config inPreferredConfig; + public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888; /** * If dither is true, the decoder will attempt to dither the decoded @@ -81,7 +84,7 @@ public class BitmapFactory { /** * The pixel density to use for the bitmap. This will always result * in the returned bitmap having a density set for it (see - * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)). In addition, + * {@link Bitmap#setDensity(int) Bitmap.setDensity(int))}. In addition, * if {@link #inScaled} is set (which it is by default} and this * density does not match {@link #inTargetDensity}, then the bitmap * will be scaled to the target density before being returned. @@ -507,9 +510,7 @@ public class BitmapFactory { * * @param is The input stream that holds the raw data to be decoded into a * bitmap. - * @return The decoded bitmap, or null if the image data could not be - * decoded, or, if opts is non-null, if opts requested only the - * size be returned (in opts.outWidth and opts.outHeight) + * @return The decoded bitmap, or null if the image data could not be decoded. */ public static Bitmap decodeStream(InputStream is) { return decodeStream(is, null, null); diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java index 612b0ab..4c92942 100644 --- a/graphics/java/android/graphics/BitmapShader.java +++ b/graphics/java/android/graphics/BitmapShader.java @@ -16,11 +16,11 @@ package android.graphics; +/** + * Shader used to draw a bitmap as a texture. The bitmap can be repeated or + * mirrored by setting the tiling mode. + */ public class BitmapShader extends Shader { - - // we hold on just for the GC, since our native counterpart is using it - private Bitmap mBitmap; - /** * Call this to create a new shader that will draw with a bitmap. * @@ -29,13 +29,13 @@ public class BitmapShader extends Shader { * @param tileY The tiling mode for y to draw the bitmap in. */ public BitmapShader(Bitmap bitmap, TileMode tileX, TileMode tileY) { - mBitmap = bitmap; - native_instance = nativeCreate(bitmap.ni(), - tileX.nativeInt, tileY.nativeInt); + final int b = bitmap.ni(); + native_instance = nativeCreate(b, tileX.nativeInt, tileY.nativeInt); + native_shader = nativePostCreate(native_instance, b, tileX.nativeInt, tileY.nativeInt); } - private static native int nativeCreate(int native_bitmap, - int shaderTileModeX, - int shaderTileModeY); + private static native int nativeCreate(int native_bitmap, int shaderTileModeX, + int shaderTileModeY); + private static native int nativePostCreate(int native_shader, int native_bitmap, + int shaderTileModeX, int shaderTileModeY); } - diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 76cde73..36a8e57 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -16,11 +16,10 @@ package android.graphics; -import android.text.TextUtils; -import android.text.SpannedString; -import android.text.SpannableString; import android.text.GraphicsOperations; -import android.util.DisplayMetrics; +import android.text.SpannableString; +import android.text.SpannedString; +import android.text.TextUtils; import javax.microedition.khronos.opengles.GL; @@ -43,22 +42,39 @@ public class Canvas { for both to be null. */ private Bitmap mBitmap; // if not null, mGL must be null - private GL mGL; // if not null, mBitmap must be null // optional field set by the caller - private DrawFilter mDrawFilter; + private DrawFilter mDrawFilter; - // Package-scoped for quick access. - /*package*/ int mDensity = Bitmap.DENSITY_NONE; + /** + * @hide + */ + protected int mDensity = Bitmap.DENSITY_NONE; - // Used to determine when compatibility scaling is in effect. - private int mScreenDensity = Bitmap.DENSITY_NONE; + /** + * Used to determine when compatibility scaling is in effect. + * + * @hide + */ + protected int mScreenDensity = Bitmap.DENSITY_NONE; // Used by native code @SuppressWarnings({"UnusedDeclaration"}) private int mSurfaceFormat; /** + * Flag for drawTextRun indicating left-to-right run direction. + * @hide + */ + public static final int DIRECTION_LTR = 0; + + /** + * Flag for drawTextRun indicating right-to-left run direction. + * @hide + */ + public static final int DIRECTION_RTL = 1; + + /** * Construct an empty raster canvas. Use setBitmap() to specify a bitmap to * draw into. The initial target density is {@link Bitmap#DENSITY_NONE}; * this will typically be replaced when a target bitmap is set for the @@ -89,47 +105,37 @@ public class Canvas { mDensity = bitmap.mDensity; } - /*package*/ Canvas(int nativeCanvas) { + Canvas(int nativeCanvas) { if (nativeCanvas == 0) { throw new IllegalStateException(); } mNativeCanvas = nativeCanvas; mDensity = Bitmap.getDefaultDensity(); } - + /** - * Construct a canvas with the specified gl context. All drawing through - * this canvas will be redirected to OpenGL. Note: some features may not - * be supported in this mode (e.g. some GL implementations may not support - * antialiasing or certain effects like ColorMatrix or certain Xfermodes). - * However, no exception will be thrown in those cases. + * Returns null. * - * <p>The initial target density of the canvas is the same as the initial - * density of bitmaps as per {@link Bitmap#getDensity() Bitmap.getDensity()}. + * @deprecated This method is not supported and should not be invoked. */ - public Canvas(GL gl) { - mNativeCanvas = initGL(); - mGL = gl; - mDensity = Bitmap.getDefaultDensity(); - } - - /** - * Return the GL object associated with this canvas, or null if it is not - * backed by GL. - */ - public GL getGL() { - return mGL; + @Deprecated + protected GL getGL() { + return null; } - + /** - * Call this to free up OpenGL resources that may be cached or allocated - * on behalf of the Canvas. Any subsequent drawing with a GL-backed Canvas - * will have to recreate those resources. + * Indicates whether this Canvas uses hardware acceleration. + * + * Note that this method does not define what type of hardware acceleration + * may or may not be used. + * + * @return True if drawing operations are hardware accelerated, + * false otherwise. */ - public static void freeGlCaches() { - freeCaches(); + public boolean isHardwareAccelerated() { + return false; } - + /** * Specify a bitmap for the canvas to draw into. As a side-effect, also * updates the canvas's target density to match that of the bitmap. @@ -143,7 +149,7 @@ public class Canvas { if (!bitmap.isMutable()) { throw new IllegalStateException(); } - if (mGL != null) { + if (isHardwareAccelerated()) { throw new RuntimeException("Can't set a bitmap device on a GL canvas"); } throwIfRecycled(bitmap); @@ -157,13 +163,12 @@ public class Canvas { * Set the viewport dimensions if this canvas is GL based. If it is not, * this method is ignored and no exception is thrown. * - * @param width The width of the viewport - * @param height The height of the viewport + * @param width The width of the viewport + * @param height The height of the viewport + * + * @hide */ public void setViewport(int width, int height) { - if (mGL != null) { - nativeSetViewport(mNativeCanvas, width, height); - } } /** @@ -377,8 +382,8 @@ public class Canvas { * * @param sx The amount to scale in X * @param sy The amount to scale in Y - * @param px The x-coord for the pivot point (unchanged by the rotation) - * @param py The y-coord for the pivot point (unchanged by the rotation) + * @param px The x-coord for the pivot point (unchanged by the scale) + * @param py The y-coord for the pivot point (unchanged by the scale) */ public final void scale(float sx, float sy, float px, float py) { translate(px, py); @@ -621,7 +626,11 @@ public class Canvas { EdgeType(int nativeInt) { this.nativeInt = nativeInt; } - final int nativeInt; + + /** + * @hide + */ + public final int nativeInt; } /** @@ -958,6 +967,21 @@ public class Canvas { } /** + * Draws the specified bitmap as an N-patch (most often, a 9-patches.) + * + * Note: Only supported by hardware accelerated canvas at the moment. + * + * @param bitmap The bitmap to draw as an N-patch + * @param chunks The patches information (matches the native struct Res_png_9patch) + * @param dst The destination rectangle. + * @param paint The paint to draw the bitmap with. may be null + * + * @hide + */ + public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { + } + + /** * Draw the specified bitmap, with its top/left corner at (x,y), using * the specified paint, transformed by the current matrix. * @@ -1246,8 +1270,8 @@ public class Canvas { (text.length - index - count)) < 0) { throw new IndexOutOfBoundsException(); } - native_drawText(mNativeCanvas, text, index, count, x, y, - paint.mNativePaint); + native_drawText(mNativeCanvas, text, index, count, x, y, paint.mBidiFlags, + paint.mNativePaint); } /** @@ -1259,7 +1283,10 @@ public class Canvas { * @param y The y-coordinate of the origin of the text being drawn * @param paint The paint used for the text (e.g. color, size, style) */ - public native void drawText(String text, float x, float y, Paint paint); + public void drawText(String text, float x, float y, Paint paint) { + native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags, + paint.mNativePaint); + } /** * Draw the text, with origin at (x,y), using the specified paint. @@ -1277,8 +1304,8 @@ public class Canvas { if ((start | end | (end - start) | (text.length() - end)) < 0) { throw new IndexOutOfBoundsException(); } - native_drawText(mNativeCanvas, text, start, end, x, y, - paint.mNativePaint); + native_drawText(mNativeCanvas, text, start, end, x, y, paint.mBidiFlags, + paint.mNativePaint); } /** @@ -1299,16 +1326,108 @@ public class Canvas { if (text instanceof String || text instanceof SpannedString || text instanceof SpannableString) { native_drawText(mNativeCanvas, text.toString(), start, end, x, y, - paint.mNativePaint); - } - else if (text instanceof GraphicsOperations) { + paint.mBidiFlags, paint.mNativePaint); + } else if (text instanceof GraphicsOperations) { ((GraphicsOperations) text).drawText(this, start, end, x, y, paint); - } - else { + } else { char[] buf = TemporaryBuffer.obtain(end - start); TextUtils.getChars(text, start, end, buf, 0); - drawText(buf, 0, end - start, x, y, paint); + native_drawText(mNativeCanvas, buf, 0, end - start, x, y, + paint.mBidiFlags, paint.mNativePaint); + TemporaryBuffer.recycle(buf); + } + } + + /** + * Render a run of all LTR or all RTL text, with shaping. This does not run + * bidi on the provided text, but renders it as a uniform right-to-left or + * left-to-right run, as indicated by dir. Alignment of the text is as + * determined by the Paint's TextAlign value. + * + * @param text the text to render + * @param index the start of the text to render + * @param count the count of chars to render + * @param contextIndex the start of the context for shaping. Must be + * no greater than index. + * @param contextCount the number of characters in the context for shaping. + * ContexIndex + contextCount must be no less than index + * + count. + * @param x the x position at which to draw the text + * @param y the y position at which to draw the text + * @param dir the run direction, either {@link #DIRECTION_LTR} or + * {@link #DIRECTION_RTL}. + * @param paint the paint + * @hide + */ + public void drawTextRun(char[] text, int index, int count, + int contextIndex, int contextCount, float x, float y, int dir, + Paint paint) { + + if (text == null) { + throw new NullPointerException("text is null"); + } + if (paint == null) { + throw new NullPointerException("paint is null"); + } + if ((index | count | text.length - index - count) < 0) { + throw new IndexOutOfBoundsException(); + } + if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) { + throw new IllegalArgumentException("unknown dir: " + dir); + } + + native_drawTextRun(mNativeCanvas, text, index, count, + contextIndex, contextCount, x, y, dir, paint.mNativePaint); + } + + /** + * Render a run of all LTR or all RTL text, with shaping. This does not run + * bidi on the provided text, but renders it as a uniform right-to-left or + * left-to-right run, as indicated by dir. Alignment of the text is as + * determined by the Paint's TextAlign value. + * + * @param text the text to render + * @param start the start of the text to render. Data before this position + * can be used for shaping context. + * @param end the end of the text to render. Data at or after this + * position can be used for shaping context. + * @param x the x position at which to draw the text + * @param y the y position at which to draw the text + * @param dir the run direction, either 0 for LTR or 1 for RTL. + * @param paint the paint + * @hide + */ + public void drawTextRun(CharSequence text, int start, int end, + int contextStart, int contextEnd, float x, float y, int dir, + Paint paint) { + + if (text == null) { + throw new NullPointerException("text is null"); + } + if (paint == null) { + throw new NullPointerException("paint is null"); + } + if ((start | end | end - start | text.length() - end) < 0) { + throw new IndexOutOfBoundsException(); + } + + int flags = dir == 0 ? 0 : 1; + + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + native_drawTextRun(mNativeCanvas, text.toString(), start, end, + contextStart, contextEnd, x, y, flags, paint.mNativePaint); + } else if (text instanceof GraphicsOperations) { + ((GraphicsOperations) text).drawTextRun(this, start, end, + contextStart, contextEnd, x, y, flags, paint); + } else { + int contextLen = contextEnd - contextStart; + int len = end - start; + char[] buf = TemporaryBuffer.obtain(contextLen); + TextUtils.getChars(text, contextStart, contextEnd, buf, 0); + native_drawTextRun(mNativeCanvas, buf, start - contextStart, len, + 0, contextLen, x, y, flags, paint.mNativePaint); TemporaryBuffer.recycle(buf); } } @@ -1368,7 +1487,7 @@ public class Canvas { } native_drawTextOnPath(mNativeCanvas, text, index, count, path.ni(), hOffset, vOffset, - paint.mNativePaint); + paint.mBidiFlags, paint.mNativePaint); } /** @@ -1388,7 +1507,8 @@ public class Canvas { float vOffset, Paint paint) { if (text.length() > 0) { native_drawTextOnPath(mNativeCanvas, text, path.ni(), - hOffset, vOffset, paint.mNativePaint); + hOffset, vOffset, paint.mBidiFlags, + paint.mNativePaint); } } @@ -1432,27 +1552,28 @@ public class Canvas { restore(); } + @Override protected void finalize() throws Throwable { - super.finalize(); - // If the constructor threw an exception before setting mNativeCanvas, the native finalizer - // must not be invoked. - if (mNativeCanvas != 0) { - finalizer(mNativeCanvas); + try { + super.finalize(); + } finally { + // If the constructor threw an exception before setting mNativeCanvas, + // the native finalizer must not be invoked. + if (mNativeCanvas != 0) { + finalizer(mNativeCanvas); + } } } /** - * Free up as much memory as possible from private caches (e.g. fonts, - * images) + * Free up as much memory as possible from private caches (e.g. fonts, images) * - * @hide - for now + * @hide */ public static native void freeCaches(); private static native int initRaster(int nativeBitmapOrZero); - private static native int initGL(); private static native void native_setBitmap(int nativeCanvas, int bitmap); - private static native void nativeSetViewport(int nCanvas, int w, int h); private static native int native_saveLayer(int nativeCanvas, RectF bounds, int paint, int layerFlags); private static native int native_saveLayer(int nativeCanvas, float l, @@ -1555,10 +1676,19 @@ public class Canvas { private static native void native_drawText(int nativeCanvas, char[] text, int index, int count, float x, - float y, int paint); + float y, int flags, int paint); private static native void native_drawText(int nativeCanvas, String text, int start, int end, float x, - float y, int paint); + float y, int flags, int paint); + + private static native void native_drawTextRun(int nativeCanvas, String text, + int start, int end, int contextStart, int contextEnd, + float x, float y, int flags, int paint); + + private static native void native_drawTextRun(int nativeCanvas, char[] text, + int start, int count, int contextStart, int contextCount, + float x, float y, int flags, int paint); + private static native void native_drawPosText(int nativeCanvas, char[] text, int index, int count, float[] pos, @@ -1570,11 +1700,13 @@ public class Canvas { char[] text, int index, int count, int path, float hOffset, - float vOffset, int paint); + float vOffset, int bidiFlags, + int paint); private static native void native_drawTextOnPath(int nativeCanvas, String text, int path, - float hOffset, - float vOffset, int paint); + float hOffset, + float vOffset, + int flags, int paint); private static native void native_drawPicture(int nativeCanvas, int nativePicture); private static native void finalizer(int nativeCanvas); diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java index 76f2c7f..e5cf830 100644 --- a/graphics/java/android/graphics/ColorFilter.java +++ b/graphics/java/android/graphics/ColorFilter.java @@ -23,12 +23,20 @@ package android.graphics; public class ColorFilter { + int native_instance; + + /** + * @hide + */ + public int nativeColorFilter; protected void finalize() throws Throwable { - finalizer(native_instance); + try { + super.finalize(); + } finally { + finalizer(native_instance, nativeColorFilter); + } } - private static native void finalizer(int native_instance); - - int native_instance; + private static native void finalizer(int native_instance, int nativeColorFilter); } diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java index 5d73cff..245c615 100644 --- a/graphics/java/android/graphics/ColorMatrixColorFilter.java +++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java @@ -25,7 +25,9 @@ public class ColorMatrixColorFilter extends ColorFilter { * is constructed will not be reflected in the filter. */ public ColorMatrixColorFilter(ColorMatrix matrix) { - native_instance = nativeColorMatrixFilter(matrix.getArray()); + final float[] colorMatrix = matrix.getArray(); + native_instance = nativeColorMatrixFilter(colorMatrix); + nativeColorFilter = nColorMatrixFilter(colorMatrix); } /** @@ -40,7 +42,9 @@ public class ColorMatrixColorFilter extends ColorFilter { throw new ArrayIndexOutOfBoundsException(); } native_instance = nativeColorMatrixFilter(array); + nativeColorFilter = nColorMatrixFilter(array); } private static native int nativeColorMatrixFilter(float[] array); + private static native int nColorMatrixFilter(float[] array); } diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java index a06d30b..8d5c913 100644 --- a/graphics/java/android/graphics/ComposeShader.java +++ b/graphics/java/android/graphics/ComposeShader.java @@ -20,6 +20,14 @@ package android.graphics; an {@link android.graphics.Xfermode} subclass. */ public class ComposeShader extends Shader { + /** + * Hold onto the shaders to avoid GC. + */ + @SuppressWarnings({"UnusedDeclaration"}) + private final Shader mShaderA; + @SuppressWarnings({"UnusedDeclaration"}) + private final Shader mShaderB; + /** Create a new compose shader, given shaders A, B, and a combining mode. When the mode is applied, it will be given the result from shader A as its "dst", and the result of from shader B as its "src". @@ -29,8 +37,18 @@ public class ComposeShader extends Shader { is null, then SRC_OVER is assumed. */ public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) { + mShaderA = shaderA; + mShaderB = shaderB; native_instance = nativeCreate1(shaderA.native_instance, shaderB.native_instance, - (mode != null) ? mode.native_instance : 0); + (mode != null) ? mode.native_instance : 0); + if (mode instanceof PorterDuffXfermode) { + PorterDuff.Mode pdMode = ((PorterDuffXfermode) mode).mode; + native_shader = nativePostCreate2(native_instance, shaderA.native_shader, + shaderB.native_shader, pdMode != null ? pdMode.nativeInt : 0); + } else { + native_shader = nativePostCreate1(native_instance, shaderA.native_shader, + shaderB.native_shader, mode != null ? mode.native_instance : 0); + } } /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode. @@ -41,11 +59,20 @@ public class ComposeShader extends Shader { @param mode The PorterDuff mode that combines the colors from the two shaders. */ public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) { + mShaderA = shaderA; + mShaderB = shaderB; native_instance = nativeCreate2(shaderA.native_instance, shaderB.native_instance, - mode.nativeInt); + mode.nativeInt); + native_shader = nativePostCreate2(native_instance, shaderA.native_shader, + shaderB.native_shader, mode.nativeInt); } - private static native int nativeCreate1(int native_shaderA, int native_shaderB, int native_mode); - private static native int nativeCreate2(int native_shaderA, int native_shaderB, int porterDuffMode); + private static native int nativeCreate1(int native_shaderA, int native_shaderB, + int native_mode); + private static native int nativeCreate2(int native_shaderA, int native_shaderB, + int porterDuffMode); + private static native int nativePostCreate1(int native_shader, int native_skiaShaderA, + int native_skiaShaderB, int native_mode); + private static native int nativePostCreate2(int native_shader, int native_skiaShaderA, + int native_skiaShaderB, int porterDuffMode); } - diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java index 5562389..715ce86 100644 --- a/graphics/java/android/graphics/LightingColorFilter.java +++ b/graphics/java/android/graphics/LightingColorFilter.java @@ -30,7 +30,9 @@ public class LightingColorFilter extends ColorFilter { */ public LightingColorFilter(int mul, int add) { native_instance = native_CreateLightingFilter(mul, add); + nativeColorFilter = nCreateLightingFilter(mul, add); } private static native int native_CreateLightingFilter(int mul, int add); + private static native int nCreateLightingFilter(int mul, int add); } diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java index e3db105..82ed199 100644 --- a/graphics/java/android/graphics/LinearGradient.java +++ b/graphics/java/android/graphics/LinearGradient.java @@ -17,7 +17,6 @@ package android.graphics; public class LinearGradient extends Shader { - /** Create a shader that draws a linear gradient along a line. @param x0 The x-coordinate for the start of the gradient line @param y0 The y-coordinate for the start of the gradient line @@ -38,6 +37,8 @@ public class LinearGradient extends Shader { throw new IllegalArgumentException("color and position arrays must be of equal length"); } native_instance = nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt); + native_shader = nativePostCreate1(native_instance, x0, y0, x1, y1, colors, positions, + tile.nativeInt); } /** Create a shader that draws a linear gradient along a line. @@ -52,12 +53,16 @@ public class LinearGradient extends Shader { public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, TileMode tile) { native_instance = nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt); + native_shader = nativePostCreate2(native_instance, x0, y0, x1, y1, color0, color1, + tile.nativeInt); } - - private static native int nativeCreate1(float x0, float y0, float x1, float y1, - int colors[], float positions[], int tileMode); - private static native int nativeCreate2(float x0, float y0, float x1, float y1, - int color0, int color1, int tileMode); + private native int nativeCreate1(float x0, float y0, float x1, float y1, + int colors[], float positions[], int tileMode); + private native int nativeCreate2(float x0, float y0, float x1, float y1, + int color0, int color1, int tileMode); + private native int nativePostCreate1(int native_shader, float x0, float y0, float x1, float y1, + int colors[], float positions[], int tileMode); + private native int nativePostCreate2(int native_shader, float x0, float y0, float x1, float y1, + int color0, int color1, int tileMode); } - diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java index f549900..b336995 100644 --- a/graphics/java/android/graphics/Matrix.java +++ b/graphics/java/android/graphics/Matrix.java @@ -37,7 +37,10 @@ public class Matrix { public static final int MPERSP_1 = 7; //!< use with getValues/setValues public static final int MPERSP_2 = 8; //!< use with getValues/setValues - /* package */ int native_instance; + /** + * @hide + */ + public int native_instance; /** * Create an identity matrix diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java index 88dfd67..df6feba 100644 --- a/graphics/java/android/graphics/NinePatch.java +++ b/graphics/java/android/graphics/NinePatch.java @@ -35,6 +35,12 @@ package android.graphics; * </p> */ public class NinePatch { + private final Bitmap mBitmap; + private final byte[] mChunk; + private Paint mPaint; + private String mSrcName; // Useful for debugging + private final RectF mRect = new RectF(); + /** * Create a drawable projection from a bitmap to nine patches. * @@ -74,10 +80,14 @@ public class NinePatch { * @param location Where to draw the bitmap. */ public void draw(Canvas canvas, RectF location) { - nativeDraw(canvas.mNativeCanvas, location, - mBitmap.ni(), mChunk, - mPaint != null ? mPaint.mNativePaint : 0, - canvas.mDensity, mBitmap.mDensity); + if (!canvas.isHardwareAccelerated()) { + nativeDraw(canvas.mNativeCanvas, location, + mBitmap.ni(), mChunk, + mPaint != null ? mPaint.mNativePaint : 0, + canvas.mDensity, mBitmap.mDensity); + } else { + canvas.drawPatch(mBitmap, mChunk, location, null); + } } /** @@ -87,10 +97,15 @@ public class NinePatch { * @param location Where to draw the bitmap. */ public void draw(Canvas canvas, Rect location) { - nativeDraw(canvas.mNativeCanvas, location, - mBitmap.ni(), mChunk, - mPaint != null ? mPaint.mNativePaint : 0, - canvas.mDensity, mBitmap.mDensity); + if (!canvas.isHardwareAccelerated()) { + nativeDraw(canvas.mNativeCanvas, location, + mBitmap.ni(), mChunk, + mPaint != null ? mPaint.mNativePaint : 0, + canvas.mDensity, mBitmap.mDensity); + } else { + mRect.set(location); + canvas.drawPatch(mBitmap, mChunk, mRect, null); + } } /** @@ -101,9 +116,14 @@ public class NinePatch { * @param paint The Paint to draw through. */ public void draw(Canvas canvas, Rect location, Paint paint) { - nativeDraw(canvas.mNativeCanvas, location, - mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0, - canvas.mDensity, mBitmap.mDensity); + if (!canvas.isHardwareAccelerated()) { + nativeDraw(canvas.mNativeCanvas, location, + mBitmap.ni(), mChunk, paint != null ? paint.mNativePaint : 0, + canvas.mDensity, mBitmap.mDensity); + } else { + mRect.set(location); + canvas.drawPatch(mBitmap, mChunk, mRect, paint); + } } /** @@ -133,11 +153,6 @@ public class NinePatch { public native static boolean isNinePatchChunk(byte[] chunk); - private final Bitmap mBitmap; - private final byte[] mChunk; - private Paint mPaint; - private String mSrcName; // Useful for debugging - private static native void validateNinePatchChunk(int bitmap, byte[] chunk); private static native void nativeDraw(int canvas_instance, RectF loc, int bitmap_instance, byte[] c, int paint_instance_or_null, diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 3e3f87b..6349cb3 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -16,10 +16,10 @@ package android.graphics; -import android.text.TextUtils; +import android.text.GraphicsOperations; import android.text.SpannableString; import android.text.SpannedString; -import android.text.GraphicsOperations; +import android.text.TextUtils; /** * The Paint class holds the style and color information about how to draw @@ -27,7 +27,11 @@ import android.text.GraphicsOperations; */ public class Paint { - /*package*/ int mNativePaint; + /** + * @hide + */ + public int mNativePaint; + private ColorFilter mColorFilter; private MaskFilter mMaskFilter; private PathEffect mPathEffect; @@ -39,6 +43,10 @@ public class Paint { private boolean mHasCompatScaling; private float mCompatScaling; private float mInvCompatScaling; + /** + * @hide + */ + public int mBidiFlags = BIDI_DEFAULT_LTR; private static final Style[] sStyleArray = { Style.FILL, Style.STROKE, Style.FILL_AND_STROKE @@ -76,8 +84,116 @@ public class Paint { private static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG; /** - * The Style specifies if the primitive being drawn is filled, - * stroked, or both (in the same color). The default is FILL. + * Bidi flag to set LTR paragraph direction. + * + * @hide + */ + public static final int BIDI_LTR = 0x0; + + /** + * Bidi flag to set RTL paragraph direction. + * + * @hide + */ + public static final int BIDI_RTL = 0x1; + + /** + * Bidi flag to detect paragraph direction via heuristics, defaulting to + * LTR. + * + * @hide + */ + public static final int BIDI_DEFAULT_LTR = 0x2; + + /** + * Bidi flag to detect paragraph direction via heuristics, defaulting to + * RTL. + * + * @hide + */ + public static final int BIDI_DEFAULT_RTL = 0x3; + + /** + * Bidi flag to override direction to all LTR (ignore bidi). + * + * @hide + */ + public static final int BIDI_FORCE_LTR = 0x4; + + /** + * Bidi flag to override direction to all RTL (ignore bidi). + * + * @hide + */ + public static final int BIDI_FORCE_RTL = 0x5; + + /** + * Maximum Bidi flag value. + * @hide + */ + private static final int BIDI_MAX_FLAG_VALUE = BIDI_FORCE_RTL; + + /** + * Mask for bidi flags. + * @hide + */ + private static final int BIDI_FLAG_MASK = 0x7; + + /** + * Flag for getTextRunAdvances indicating left-to-right run direction. + * @hide + */ + public static final int DIRECTION_LTR = 0; + + /** + * Flag for getTextRunAdvances indicating right-to-left run direction. + * @hide + */ + public static final int DIRECTION_RTL = 1; + + /** + * Option for getTextRunCursor to compute the valid cursor after + * offset or the limit of the context, whichever is less. + * @hide + */ + public static final int CURSOR_AFTER = 0; + + /** + * Option for getTextRunCursor to compute the valid cursor at or after + * the offset or the limit of the context, whichever is less. + * @hide + */ + public static final int CURSOR_AT_OR_AFTER = 1; + + /** + * Option for getTextRunCursor to compute the valid cursor before + * offset or the start of the context, whichever is greater. + * @hide + */ + public static final int CURSOR_BEFORE = 2; + + /** + * Option for getTextRunCursor to compute the valid cursor at or before + * offset or the start of the context, whichever is greater. + * @hide + */ + public static final int CURSOR_AT_OR_BEFORE = 3; + + /** + * Option for getTextRunCursor to return offset if the cursor at offset + * is valid, or -1 if it isn't. + * @hide + */ + public static final int CURSOR_AT = 4; + + /** + * Maximum cursor option value. + */ + private static final int CURSOR_OPT_MAX_VALUE = CURSOR_AT; + + /** + * The Style specifies if the primitive being drawn is filled, stroked, or + * both (in the same color). The default is FILL. */ public enum Style { /** @@ -93,7 +209,9 @@ public class Paint { /** * Geometry and text drawn with this style will be both filled and * stroked at the same time, respecting the stroke-related fields on - * the paint. + * the paint. This mode can give unexpected results if the geometry + * is oriented counter-clockwise. This restriction does not apply to + * either FILL or STROKE. */ FILL_AND_STROKE (2); @@ -208,6 +326,7 @@ public class Paint { mHasCompatScaling = paint.mHasCompatScaling; mCompatScaling = paint.mCompatScaling; mInvCompatScaling = paint.mInvCompatScaling; + mBidiFlags = paint.mBidiFlags; } /** Restores the paint to its default settings. */ @@ -216,6 +335,7 @@ public class Paint { setFlags(DEFAULT_PAINT_FLAGS); mHasCompatScaling = false; mCompatScaling = mInvCompatScaling = 1; + mBidiFlags = BIDI_DEFAULT_LTR; } /** @@ -238,6 +358,7 @@ public class Paint { mHasCompatScaling = src.mHasCompatScaling; mCompatScaling = src.mCompatScaling; mInvCompatScaling = src.mInvCompatScaling; + mBidiFlags = src.mBidiFlags; } } @@ -252,10 +373,33 @@ public class Paint { mInvCompatScaling = 1.0f/factor; } } - + + /** + * Return the bidi flags on the paint. + * + * @return the bidi flags on the paint + * @hide + */ + public int getBidiFlags() { + return mBidiFlags; + } + + /** + * Set the bidi flags on the paint. + * @hide + */ + public void setBidiFlags(int flags) { + // only flag value is the 3-bit BIDI control setting + flags &= BIDI_FLAG_MASK; + if (flags > BIDI_MAX_FLAG_VALUE) { + throw new IllegalArgumentException("unknown bidi flag: " + flags); + } + mBidiFlags = flags; + } + /** * Return the paint's flags. Use the Flag enum to test flag values. - * + * * @return the paint's flags (see enums ending in _Flag for bit masks) */ public native int getFlags(); @@ -787,15 +931,14 @@ public class Paint { } /** - * Temporary API to expose layer drawing. This draws a shadow layer below - * the main layer, with the specified offset and color, and blur radius. - * If radius is 0, then the shadow layer is removed. + * This draws a shadow layer below the main layer, with the specified + * offset and color, and blur radius. If radius is 0, then the shadow + * layer is removed. */ - public native void setShadowLayer(float radius, float dx, float dy, - int color); + public native void setShadowLayer(float radius, float dx, float dy, int color); /** - * Temporary API to clear the shadow layer. + * Clear the shadow layer. */ public void clearShadowLayer() { setShadowLayer(0, 0, 0, 0); @@ -1232,10 +1375,10 @@ public class Paint { } char[] buf = TemporaryBuffer.obtain(end - start); - TextUtils.getChars(text, start, end, buf, 0); - int result = getTextWidths(buf, 0, end - start, widths); + TextUtils.getChars(text, start, end, buf, 0); + int result = getTextWidths(buf, 0, end - start, widths); TemporaryBuffer.recycle(buf); - return result; + return result; } /** @@ -1282,6 +1425,284 @@ public class Paint { } /** + * Convenience overload that takes a char array instead of a + * String. + * + * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int) + * @hide + */ + public float getTextRunAdvances(char[] chars, int index, int count, + int contextIndex, int contextCount, int flags, float[] advances, + int advancesIndex) { + + if ((index | count | contextIndex | contextCount | advancesIndex + | (index - contextIndex) + | ((contextIndex + contextCount) - (index + count)) + | (chars.length - (contextIndex + contextCount)) + | (advances == null ? 0 : + (advances.length - (advancesIndex + count)))) < 0) { + throw new IndexOutOfBoundsException(); + } + if (flags != DIRECTION_LTR && flags != DIRECTION_RTL) { + throw new IllegalArgumentException("unknown flags value: " + flags); + } + + if (!mHasCompatScaling) { + return native_getTextRunAdvances(mNativePaint, chars, index, count, + contextIndex, contextCount, flags, advances, advancesIndex); + } + + final float oldSize = getTextSize(); + setTextSize(oldSize * mCompatScaling); + float res = native_getTextRunAdvances(mNativePaint, chars, index, count, + contextIndex, contextCount, flags, advances, advancesIndex); + setTextSize(oldSize); + + if (advances != null) { + for (int i = advancesIndex, e = i + count; i < e; i++) { + advances[i] *= mInvCompatScaling; + } + } + return res * mInvCompatScaling; // assume errors are not significant + } + + /** + * Convenience overload that takes a CharSequence instead of a + * String. + * + * @see #getTextRunAdvances(String, int, int, int, int, int, float[], int) + * @hide + */ + public float getTextRunAdvances(CharSequence text, int start, int end, + int contextStart, int contextEnd, int flags, float[] advances, + int advancesIndex) { + + if (text instanceof String) { + return getTextRunAdvances((String) text, start, end, + contextStart, contextEnd, flags, advances, advancesIndex); + } + if (text instanceof SpannedString || + text instanceof SpannableString) { + return getTextRunAdvances(text.toString(), start, end, + contextStart, contextEnd, flags, advances, advancesIndex); + } + if (text instanceof GraphicsOperations) { + return ((GraphicsOperations) text).getTextRunAdvances(start, end, + contextStart, contextEnd, flags, advances, advancesIndex, this); + } + + int contextLen = contextEnd - contextStart; + int len = end - start; + char[] buf = TemporaryBuffer.obtain(contextLen); + TextUtils.getChars(text, start, end, buf, 0); + float result = getTextRunAdvances(buf, start - contextStart, len, + 0, contextLen, flags, advances, advancesIndex); + TemporaryBuffer.recycle(buf); + return result; + } + + /** + * Returns the total advance width for the characters in the run + * between start and end, and if advances is not null, the advance + * assigned to each of these characters (java chars). + * + * <p>The trailing surrogate in a valid surrogate pair is assigned + * an advance of 0. Thus the number of returned advances is + * always equal to count, not to the number of unicode codepoints + * represented by the run. + * + * <p>In the case of conjuncts or combining marks, the total + * advance is assigned to the first logical character, and the + * following characters are assigned an advance of 0. + * + * <p>This generates the sum of the advances of glyphs for + * characters in a reordered cluster as the width of the first + * logical character in the cluster, and 0 for the widths of all + * other characters in the cluster. In effect, such clusters are + * treated like conjuncts. + * + * <p>The shaping bounds limit the amount of context available + * outside start and end that can be used for shaping analysis. + * These bounds typically reflect changes in bidi level or font + * metrics across which shaping does not occur. + * + * @param text the text to measure + * @param start the index of the first character to measure + * @param end the index past the last character to measure + * @param contextStart the index of the first character to use for shaping context, + * must be <= start + * @param contextEnd the index past the last character to use for shaping context, + * must be >= end + * @param flags the flags to control the advances, either {@link #DIRECTION_LTR} + * or {@link #DIRECTION_RTL} + * @param advances array to receive the advances, must have room for all advances, + * can be null if only total advance is needed + * @param advancesIndex the position in advances at which to put the + * advance corresponding to the character at start + * @return the total advance + * + * @hide + */ + public float getTextRunAdvances(String text, int start, int end, int contextStart, + int contextEnd, int flags, float[] advances, int advancesIndex) { + + if ((start | end | contextStart | contextEnd | advancesIndex | (end - start) + | (start - contextStart) | (contextEnd - end) + | (text.length() - contextEnd) + | (advances == null ? 0 : + (advances.length - advancesIndex - (end - start)))) < 0) { + throw new IndexOutOfBoundsException(); + } + if (flags != DIRECTION_LTR && flags != DIRECTION_RTL) { + throw new IllegalArgumentException("unknown flags value: " + flags); + } + + if (!mHasCompatScaling) { + return native_getTextRunAdvances(mNativePaint, text, start, end, + contextStart, contextEnd, flags, advances, advancesIndex); + } + + final float oldSize = getTextSize(); + setTextSize(oldSize * mCompatScaling); + float totalAdvance = native_getTextRunAdvances(mNativePaint, text, start, end, + contextStart, contextEnd, flags, advances, advancesIndex); + setTextSize(oldSize); + + if (advances != null) { + for (int i = advancesIndex, e = i + (end - start); i < e; i++) { + advances[i] *= mInvCompatScaling; + } + } + return totalAdvance * mInvCompatScaling; // assume errors are insignificant + } + + /** + * Returns the next cursor position in the run. This avoids placing the + * cursor between surrogates, between characters that form conjuncts, + * between base characters and combining marks, or within a reordering + * cluster. + * + * <p>ContextStart and offset are relative to the start of text. + * The context is the shaping context for cursor movement, generally + * the bounds of the metric span enclosing the cursor in the direction of + * movement. + * + * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid + * cursor position, this returns -1. Otherwise this will never return a + * value before contextStart or after contextStart + contextLength. + * + * @param text the text + * @param contextStart the start of the context + * @param contextLength the length of the context + * @param flags either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR} + * @param offset the cursor position to move from + * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER}, + * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE}, + * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT} + * @return the offset of the next position, or -1 + * @hide + */ + public int getTextRunCursor(char[] text, int contextStart, int contextLength, + int flags, int offset, int cursorOpt) { + int contextEnd = contextStart + contextLength; + if (((contextStart | contextEnd | offset | (contextEnd - contextStart) + | (offset - contextStart) | (contextEnd - offset) + | (text.length - contextEnd) | cursorOpt) < 0) + || cursorOpt > CURSOR_OPT_MAX_VALUE) { + throw new IndexOutOfBoundsException(); + } + + return native_getTextRunCursor(mNativePaint, text, + contextStart, contextLength, flags, offset, cursorOpt); + } + + /** + * Returns the next cursor position in the run. This avoids placing the + * cursor between surrogates, between characters that form conjuncts, + * between base characters and combining marks, or within a reordering + * cluster. + * + * <p>ContextStart, contextEnd, and offset are relative to the start of + * text. The context is the shaping context for cursor movement, generally + * the bounds of the metric span enclosing the cursor in the direction of + * movement. + * + * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid + * cursor position, this returns -1. Otherwise this will never return a + * value before contextStart or after contextEnd. + * + * @param text the text + * @param contextStart the start of the context + * @param contextEnd the end of the context + * @param flags either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR} + * @param offset the cursor position to move from + * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER}, + * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE}, + * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT} + * @return the offset of the next position, or -1 + * @hide + */ + public int getTextRunCursor(CharSequence text, int contextStart, + int contextEnd, int flags, int offset, int cursorOpt) { + + if (text instanceof String || text instanceof SpannedString || + text instanceof SpannableString) { + return getTextRunCursor(text.toString(), contextStart, contextEnd, + flags, offset, cursorOpt); + } + if (text instanceof GraphicsOperations) { + return ((GraphicsOperations) text).getTextRunCursor( + contextStart, contextEnd, flags, offset, cursorOpt, this); + } + + int contextLen = contextEnd - contextStart; + char[] buf = TemporaryBuffer.obtain(contextLen); + TextUtils.getChars(text, contextStart, contextEnd, buf, 0); + int result = getTextRunCursor(buf, 0, contextLen, flags, offset, cursorOpt); + TemporaryBuffer.recycle(buf); + return result; + } + + /** + * Returns the next cursor position in the run. This avoids placing the + * cursor between surrogates, between characters that form conjuncts, + * between base characters and combining marks, or within a reordering + * cluster. + * + * <p>ContextStart, contextEnd, and offset are relative to the start of + * text. The context is the shaping context for cursor movement, generally + * the bounds of the metric span enclosing the cursor in the direction of + * movement. + * + * <p>If cursorOpt is {@link #CURSOR_AT} and the offset is not a valid + * cursor position, this returns -1. Otherwise this will never return a + * value before contextStart or after contextEnd. + * + * @param text the text + * @param contextStart the start of the context + * @param contextEnd the end of the context + * @param flags either {@link #DIRECTION_RTL} or {@link #DIRECTION_LTR} + * @param offset the cursor position to move from + * @param cursorOpt how to move the cursor, one of {@link #CURSOR_AFTER}, + * {@link #CURSOR_AT_OR_AFTER}, {@link #CURSOR_BEFORE}, + * {@link #CURSOR_AT_OR_BEFORE}, or {@link #CURSOR_AT} + * @return the offset of the next position, or -1 + * @hide + */ + public int getTextRunCursor(String text, int contextStart, int contextEnd, + int flags, int offset, int cursorOpt) { + if (((contextStart | contextEnd | offset | (contextEnd - contextStart) + | (offset - contextStart) | (contextEnd - offset) + | (text.length() - contextEnd) | cursorOpt) < 0) + || cursorOpt > CURSOR_OPT_MAX_VALUE) { + throw new IndexOutOfBoundsException(); + } + + return native_getTextRunCursor(mNativePaint, text, + contextStart, contextEnd, flags, offset, cursorOpt); + } + + /** * Return the path (outline) for the specified text. * Note: just like Canvas.drawText, this will respect the Align setting in * the paint. @@ -1299,7 +1720,8 @@ public class Paint { if ((index | count) < 0 || index + count > text.length) { throw new ArrayIndexOutOfBoundsException(); } - native_getTextPath(mNativePaint, text, index, count, x, y, path.ni()); + native_getTextPath(mNativePaint, mBidiFlags, text, index, count, x, y, + path.ni()); } /** @@ -1320,7 +1742,8 @@ public class Paint { if ((start | end | (end - start) | (text.length() - end)) < 0) { throw new IndexOutOfBoundsException(); } - native_getTextPath(mNativePaint, text, start, end, x, y, path.ni()); + native_getTextPath(mNativePaint, mBidiFlags, text, start, end, x, y, + path.ni()); } /** @@ -1404,9 +1827,22 @@ public class Paint { char[] text, int index, int count, float[] widths); private static native int native_getTextWidths(int native_object, String text, int start, int end, float[] widths); - private static native void native_getTextPath(int native_object, + + private static native float native_getTextRunAdvances(int native_object, + char[] text, int index, int count, int contextIndex, int contextCount, + int flags, float[] advances, int advancesIndex); + private static native float native_getTextRunAdvances(int native_object, + String text, int start, int end, int contextStart, int contextEnd, + int flags, float[] advances, int advancesIndex); + + private native int native_getTextRunCursor(int native_object, char[] text, + int contextStart, int contextLength, int flags, int offset, int cursorOpt); + private native int native_getTextRunCursor(int native_object, String text, + int contextStart, int contextEnd, int flags, int offset, int cursorOpt); + + private static native void native_getTextPath(int native_object, int bidiFlags, char[] text, int index, int count, float x, float y, int path); - private static native void native_getTextPath(int native_object, + private static native void native_getTextPath(int native_object, int bidiFlags, String text, int start, int end, float x, float y, int path); private static native void nativeGetStringBounds(int nativePaint, String text, int start, int end, Rect bounds); @@ -1414,4 +1850,3 @@ public class Paint { char[] text, int index, int count, Rect bounds); private static native void finalizer(int nativePaint); } - diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 281823a..c3416a0 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -16,6 +16,8 @@ package android.graphics; +import android.view.HardwareRenderer; + /** * The Path class encapsulates compound (multiple contour) geometric paths * consisting of straight line segments, quadratic curves, and cubic curves. @@ -24,12 +26,27 @@ package android.graphics; * text on a path. */ public class Path { + /** + * @hide + */ + public final int mNativePath; + + /** + * @hide + */ + public boolean isSimplePath = true; + /** + * @hide + */ + public Region rects; + private boolean mDetectSimplePaths; /** * Create an empty path */ public Path() { mNativePath = init1(); + mDetectSimplePaths = HardwareRenderer.isAvailable(); } /** @@ -43,6 +60,7 @@ public class Path { valNative = src.mNativePath; } mNativePath = init2(valNative); + mDetectSimplePaths = HardwareRenderer.isAvailable(); } /** @@ -50,6 +68,10 @@ public class Path { * This does NOT change the fill-type setting. */ public void reset() { + isSimplePath = true; + if (mDetectSimplePaths) { + if (rects != null) rects.setEmpty(); + } native_reset(mNativePath); } @@ -58,6 +80,10 @@ public class Path { * keeps the internal data structure for faster reuse. */ public void rewind() { + isSimplePath = true; + if (mDetectSimplePaths) { + if (rects != null) rects.setEmpty(); + } native_rewind(mNativePath); } @@ -65,6 +91,7 @@ public class Path { */ public void set(Path src) { if (this != src) { + isSimplePath = src.isSimplePath; native_set(mNativePath, src.mNativePath); } } @@ -160,6 +187,7 @@ public class Path { * @param bounds Returns the computed bounds of the path's control points. * @param exact This parameter is no longer used. */ + @SuppressWarnings({"UnusedDeclaration"}) public void computeBounds(RectF bounds, boolean exact) { native_computeBounds(mNativePath, bounds); } @@ -236,6 +264,7 @@ public class Path { * @param y2 The y-coordinate of the end point on a quadratic curve */ public void quadTo(float x1, float y1, float x2, float y2) { + isSimplePath = false; native_quadTo(mNativePath, x1, y1, x2, y2); } @@ -254,6 +283,7 @@ public class Path { * this contour, for the end point of a quadratic curve */ public void rQuadTo(float dx1, float dy1, float dx2, float dy2) { + isSimplePath = false; native_rQuadTo(mNativePath, dx1, dy1, dx2, dy2); } @@ -271,6 +301,7 @@ public class Path { */ public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) { + isSimplePath = false; native_cubicTo(mNativePath, x1, y1, x2, y2, x3, y3); } @@ -281,6 +312,7 @@ public class Path { */ public void rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) { + isSimplePath = false; native_rCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); } @@ -299,6 +331,7 @@ public class Path { */ public void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) { + isSimplePath = false; native_arcTo(mNativePath, oval, startAngle, sweepAngle, forceMoveTo); } @@ -314,6 +347,7 @@ public class Path { * @param sweepAngle Sweep angle (in degrees) measured clockwise */ public void arcTo(RectF oval, float startAngle, float sweepAngle) { + isSimplePath = false; native_arcTo(mNativePath, oval, startAngle, sweepAngle, false); } @@ -322,6 +356,7 @@ public class Path { * first point of the contour, a line segment is automatically added. */ public void close() { + isSimplePath = false; native_close(mNativePath); } @@ -351,6 +386,11 @@ public class Path { if (rect == null) { throw new NullPointerException("need rect parameter"); } + if (mDetectSimplePaths) { + if (rects == null) rects = new Region(); + rects.op((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom, + Region.Op.UNION); + } native_addRect(mNativePath, rect, dir.nativeInt); } @@ -363,8 +403,11 @@ public class Path { * @param bottom The bottom of a rectangle to add to the path * @param dir The direction to wind the rectangle's contour */ - public void addRect(float left, float top, float right, float bottom, - Direction dir) { + public void addRect(float left, float top, float right, float bottom, Direction dir) { + if (mDetectSimplePaths) { + if (rects == null) rects = new Region(); + rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION); + } native_addRect(mNativePath, left, top, right, bottom, dir.nativeInt); } @@ -378,6 +421,7 @@ public class Path { if (oval == null) { throw new NullPointerException("need oval parameter"); } + isSimplePath = false; native_addOval(mNativePath, oval, dir.nativeInt); } @@ -390,6 +434,7 @@ public class Path { * @param dir The direction to wind the circle's contour */ public void addCircle(float x, float y, float radius, Direction dir) { + isSimplePath = false; native_addCircle(mNativePath, x, y, radius, dir.nativeInt); } @@ -404,6 +449,7 @@ public class Path { if (oval == null) { throw new NullPointerException("need oval parameter"); } + isSimplePath = false; native_addArc(mNativePath, oval, startAngle, sweepAngle); } @@ -419,6 +465,7 @@ public class Path { if (rect == null) { throw new NullPointerException("need rect parameter"); } + isSimplePath = false; native_addRoundRect(mNativePath, rect, rx, ry, dir.nativeInt); } @@ -438,6 +485,7 @@ public class Path { if (radii.length < 8) { throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values"); } + isSimplePath = false; native_addRoundRect(mNativePath, rect, radii, dir.nativeInt); } @@ -448,6 +496,7 @@ public class Path { * @param dx The amount to translate the path in X as it is added */ public void addPath(Path src, float dx, float dy) { + isSimplePath = false; native_addPath(mNativePath, src.mNativePath, dx, dy); } @@ -457,6 +506,7 @@ public class Path { * @param src The path that is appended to the current path */ public void addPath(Path src) { + isSimplePath = false; native_addPath(mNativePath, src.mNativePath); } @@ -466,6 +516,7 @@ public class Path { * @param src The path to add as a new contour */ public void addPath(Path src, Matrix matrix) { + if (!src.isSimplePath) isSimplePath = false; native_addPath(mNativePath, src.mNativePath, matrix.native_instance); } @@ -502,6 +553,7 @@ public class Path { * @param dy The new Y coordinate for the last point */ public void setLastPoint(float dx, float dy) { + isSimplePath = false; native_setLastPoint(mNativePath, dx, dy); } @@ -537,8 +589,8 @@ public class Path { super.finalize(); } } - - /*package*/ final int ni() { + + final int ni() { return mNativePath; } @@ -592,6 +644,4 @@ public class Path { int dst_path); private static native void native_transform(int nPath, int matrix); private static native void finalizer(int nPath); - - private final int mNativePath; } diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index 3904234..2ef1662 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -53,11 +53,18 @@ public class PorterDuff { /** [Sa * Da, Sc * Dc] */ MULTIPLY (14), /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */ - SCREEN (15); + SCREEN (15), + /** Saturate(S + D) */ + ADD (16), + OVERLAY (17); Mode(int nativeInt) { this.nativeInt = nativeInt; } - final int nativeInt; + + /** + * @hide + */ + public final int nativeInt; } } diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java index 06724bd..b02dab1 100644 --- a/graphics/java/android/graphics/PorterDuffColorFilter.java +++ b/graphics/java/android/graphics/PorterDuffColorFilter.java @@ -25,10 +25,10 @@ public class PorterDuffColorFilter extends ColorFilter { * @param mode The porter-duff mode that is applied */ public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode) { - native_instance = native_CreatePorterDuffFilter(srcColor, - mode.nativeInt); + native_instance = native_CreatePorterDuffFilter(srcColor, mode.nativeInt); + nativeColorFilter = nCreatePorterDuffFilter(srcColor, mode.nativeInt); } - private static native int native_CreatePorterDuffFilter(int srcColor, - int porterDuffMode); + private static native int native_CreatePorterDuffFilter(int srcColor, int porterDuffMode); + private static native int nCreatePorterDuffFilter(int srcColor, int porterDuffMode); } diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java index cb127fd..6ba064c 100644 --- a/graphics/java/android/graphics/PorterDuffXfermode.java +++ b/graphics/java/android/graphics/PorterDuffXfermode.java @@ -18,11 +18,17 @@ package android.graphics; public class PorterDuffXfermode extends Xfermode { /** + * @hide + */ + public final PorterDuff.Mode mode; + + /** * Create an xfermode that uses the specified porter-duff mode. * * @param mode The porter-duff mode that is applied */ public PorterDuffXfermode(PorterDuff.Mode mode) { + this.mode = mode; native_instance = nativeCreateXfermode(mode.nativeInt); } diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 98ffb8b..7830224 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -75,6 +75,7 @@ public final class Rect implements Parcelable { bottom = r.bottom; } + @Override public boolean equals(Object obj) { Rect r = (Rect) obj; if (r != null) { @@ -84,6 +85,7 @@ public final class Rect implements Parcelable { return false; } + @Override public String toString() { StringBuilder sb = new StringBuilder(32); sb.append("Rect("); sb.append(left); sb.append(", "); @@ -351,7 +353,7 @@ public final class Rect implements Parcelable { * rectangle, return true and set this rectangle to that intersection, * otherwise return false and do not change this rectangle. No check is * performed to see if either rectangle is empty. Note: To just test for - * intersection, use intersects() + * intersection, use {@link #intersects(Rect, Rect)}. * * @param left The left side of the rectangle being intersected with this * rectangle @@ -445,7 +447,7 @@ public final class Rect implements Parcelable { /** * Returns true iff the two specified rectangles intersect. In no event are * either of the rectangles modified. To record the intersection, - * use intersect() or setIntersect(). + * use {@link #intersect(Rect)} or {@link #setIntersect(Rect, Rect)}. * * @param a The first rectangle being tested for intersection * @param b The second rectangle being tested for intersection diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java index 2b080aa..e540806 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -20,6 +20,10 @@ import android.os.Parcel; import android.os.Parcelable; public class Region implements Parcelable { + /** + * @hide + */ + public final int mNativeRegion; // the native values for these must match up with the enum in SkRegion.h public enum Op { @@ -33,7 +37,11 @@ public class Region implements Parcelable { Op(int nativeInt) { this.nativeInt = nativeInt; } - final int nativeInt; + + /** + * @hide + */ + public final int nativeInt; } /** Create an empty region @@ -325,10 +333,14 @@ public class Region implements Parcelable { } protected void finalize() throws Throwable { - nativeDestructor(mNativeRegion); + try { + nativeDestructor(mNativeRegion); + } finally { + super.finalize(); + } } - /*package*/ Region(int ni) { + Region(int ni) { if (ni == 0) { throw new RuntimeException(); } @@ -341,7 +353,7 @@ public class Region implements Parcelable { this(ni); } - /*package*/ final int ni() { + final int ni() { return mNativeRegion; } @@ -370,6 +382,4 @@ public class Region implements Parcelable { Parcel p); private static native boolean nativeEquals(int native_r1, int native_r2); - - private final int mNativeRegion; } diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java index ae0304e..b397662 100644 --- a/graphics/java/android/graphics/Shader.java +++ b/graphics/java/android/graphics/Shader.java @@ -23,9 +23,16 @@ package android.graphics; * drawn with that paint will get its color(s) from the shader. */ public class Shader { - - // this is set by subclasses, but don't make it public - /* package */ int native_instance; + /** + * This is set by subclasses, but don't make it public. + * + * @hide + */ + public int native_instance; + /** + * @hide + */ + public int native_shader; public enum TileMode { /** @@ -64,17 +71,20 @@ public class Shader { * @param localM The shader's new local matrix, or null to specify identity */ public void setLocalMatrix(Matrix localM) { - nativeSetLocalMatrix(native_instance, - localM != null ? localM.native_instance : 0); + nativeSetLocalMatrix(native_instance, native_shader, localM.native_instance); } protected void finalize() throws Throwable { - nativeDestructor(native_instance); + try { + super.finalize(); + } finally { + nativeDestructor(native_instance, native_shader); + } } - private static native void nativeDestructor(int native_shader); + private static native void nativeDestructor(int native_shader, int native_skiaShader); private static native boolean nativeGetLocalMatrix(int native_shader, - int matrix_instance); + int matrix_instance); private static native void nativeSetLocalMatrix(int native_shader, - int matrix_instance); + int native_skiaShader, int matrix_instance); } diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java index 1d7fe01..c5b8143 100644 --- a/graphics/java/android/graphics/TemporaryBuffer.java +++ b/graphics/java/android/graphics/TemporaryBuffer.java @@ -18,9 +18,11 @@ package android.graphics; import com.android.internal.util.ArrayUtils; -/* package */ class TemporaryBuffer -{ - /* package */ static char[] obtain(int len) { +/** + * @hide + */ +public class TemporaryBuffer { + public static char[] obtain(int len) { char[] buf; synchronized (TemporaryBuffer.class) { @@ -28,15 +30,15 @@ import com.android.internal.util.ArrayUtils; sTemp = null; } - if (buf == null || buf.length < len) + if (buf == null || buf.length < len) { buf = new char[ArrayUtils.idealCharArraySize(len)]; + } return buf; } - /* package */ static void recycle(char[] temp) { - if (temp.length > 1000) - return; + public static void recycle(char[] temp) { + if (temp.length > 1000) return; synchronized (TemporaryBuffer.class) { sTemp = temp; diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java index 42c410e..2467bdc 100644 --- a/graphics/java/android/graphics/Xfermode.java +++ b/graphics/java/android/graphics/Xfermode.java @@ -31,7 +31,11 @@ package android.graphics; public class Xfermode { protected void finalize() throws Throwable { - finalizer(native_instance); + try { + finalizer(native_instance); + } finally { + super.finalize(); + } } private static native void finalizer(int native_instance); diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 3125321..7b2d9d7 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -16,21 +16,30 @@ package android.graphics.drawable; -import java.io.InputStream; -import java.io.IOException; -import java.util.Arrays; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.res.Resources; import android.content.res.TypedArray; -import android.graphics.*; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.NinePatch; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.Rect; +import android.graphics.Region; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.StateSet; -import android.util.Xml; import android.util.TypedValue; +import android.util.Xml; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; /** * A Drawable is a general abstraction for "something that can be drawn." Most @@ -645,6 +654,8 @@ public abstract class Drawable { * Calling this method on a mutable Drawable will have no effect. * * @return This drawable. + * @see ConstantState + * @see #getConstantState() */ public Drawable mutate() { return this; @@ -749,6 +760,8 @@ public abstract class Drawable { drawable = new StateListDrawable(); } else if (name.equals("level-list")) { drawable = new LevelListDrawable(); + } else if (name.equals("mipmap")) { + drawable = new MipmapDrawable(); } else if (name.equals("layer-list")) { drawable = new LayerDrawable(); } else if (name.equals("transition")) { @@ -770,7 +783,7 @@ public abstract class Drawable { } else if (name.equals("inset")) { drawable = new InsetDrawable(); } else if (name.equals("bitmap")) { - drawable = new BitmapDrawable(); + drawable = new BitmapDrawable(r); if (r != null) { ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics()); } @@ -805,6 +818,9 @@ public abstract class Drawable { return null; } + /** + * Inflate this Drawable from an XML resource. + */ public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException { @@ -813,6 +829,12 @@ public abstract class Drawable { a.recycle(); } + /** + * Inflate a Drawable from an XML resource. + * + * @throws XmlPullParserException + * @throws IOException + */ void inflateWithAttributes(Resources r, XmlPullParser parser, TypedArray attrs, int visibleAttr) throws XmlPullParserException, IOException { @@ -820,12 +842,27 @@ public abstract class Drawable { mVisible = attrs.getBoolean(visibleAttr, mVisible); } + /** + * This abstract class is used by {@link Drawable}s to store shared constant state and data + * between Drawables. {@link BitmapDrawable}s created from the same resource will for instance + * share a unique bitmap stored in their ConstantState. + * + * <p> + * {@link #newDrawable(Resources)} can be used as a factory to create new Drawable instances + * from this ConstantState. + * </p> + * + * Use {@link Drawable#getConstantState()} to retrieve the ConstantState of a Drawable. Calling + * {@link Drawable#mutate()} on a Drawable should typically create a new ConstantState for that + * Drawable. + */ public static abstract class ConstantState { /** * Create a new drawable without supplying resources the caller * is running in. Note that using this means the density-dependent * drawables (like bitmaps) will not be able to update their target - * density correctly. + * density correctly. One should use {@link #newDrawable(Resources)} + * instead to provide a resource. */ public abstract Drawable newDrawable(); /** @@ -844,6 +881,13 @@ public abstract class Drawable { public abstract int getChangingConfigurations(); } + /** + * Return a {@link ConstantState} instance that holds the shared state of this Drawable. + *q + * @return The ConstantState associated to that Drawable. + * @see ConstantState + * @see Drawable#mutate() + */ public ConstantState getConstantState() { return null; } diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index c6f57d4..124d907 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -17,8 +17,16 @@ package android.graphics.drawable; import android.content.res.Resources; -import android.graphics.*; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.PixelFormat; +import android.graphics.Rect; +/** + * A helper class that contains several {@link Drawable}s and selects which one to use. + * + * You can subclass it to create your own DrawableContainers or directly use one its child classes. + */ public class DrawableContainer extends Drawable implements Drawable.Callback { /** @@ -196,8 +204,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mDrawableContainerState.getOpacity(); } - public boolean selectDrawable(int idx) - { + public boolean selectDrawable(int idx) { if (idx == mCurIndex) { return false; } @@ -255,6 +262,12 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return this; } + /** + * A ConstantState that can contain several {@link Drawable}s. + * + * This class was made public to enable testing, and its visibility may change in a future + * release. + */ public abstract static class DrawableContainerState extends ConstantState { final DrawableContainer mOwner; @@ -443,12 +456,12 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { return mConstantMinimumHeight; } - private void computeConstantSize() { + protected void computeConstantSize() { mComputedConstantSize = true; final int N = getChildCount(); final Drawable[] drawables = mDrawables; - mConstantWidth = mConstantHeight = 0; + mConstantWidth = mConstantHeight = -1; mConstantMinimumWidth = mConstantMinimumHeight = 0; for (int i = 0; i < N; i++) { Drawable dr = drawables[i]; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 33ecbea..88f6d43 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -313,18 +313,16 @@ public class GradientDrawable extends Drawable { case RECTANGLE: if (st.mRadiusArray != null) { mPath.reset(); - mPath.addRoundRect(mRect, st.mRadiusArray, - Path.Direction.CW); + mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); canvas.drawPath(mPath, mFillPaint); if (haveStroke) { canvas.drawPath(mPath, mStrokePaint); } - } - else { + } else if (st.mRadius > 0.0f) { // since the caller is only giving us 1 value, we will force // it to be square if the rect is too small in one dimension // to show it. If we did nothing, Skia would clamp the rad - // independently along each axis, giving us a thin ellips + // independently along each axis, giving us a thin ellipse // if the rect were very wide but not very tall float rad = st.mRadius; float r = Math.min(mRect.width(), mRect.height()) * 0.5f; @@ -335,6 +333,11 @@ public class GradientDrawable extends Drawable { if (haveStroke) { canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); } + } else { + canvas.drawRect(mRect, mFillPaint); + if (haveStroke) { + canvas.drawRect(mRect, mStrokePaint); + } } break; case OVAL: diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 8047dd4..501cca9 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -266,6 +266,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { */ public boolean setDrawableByLayerId(int id, Drawable drawable) { final ChildDrawable[] layers = mLayerState.mChildren; + drawable.setCallback(this); for (int i = mLayerState.mNum - 1; i >= 0; i--) { if (layers[i].mId == id) { diff --git a/graphics/java/android/graphics/drawable/MipmapDrawable.java b/graphics/java/android/graphics/drawable/MipmapDrawable.java new file mode 100644 index 0000000..75fdeed --- /dev/null +++ b/graphics/java/android/graphics/drawable/MipmapDrawable.java @@ -0,0 +1,309 @@ +/* + * 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. + */ + +package android.graphics.drawable; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Rect; +import android.util.AttributeSet; + +import java.io.IOException; + +/** + * A resource that manages a number of alternate Drawables, and which actually draws the one which + * size matches the most closely the drawing bounds. Providing several pre-scaled version of the + * drawable helps minimizing the aliasing artifacts that can be introduced by the scaling. + * + * <p> + * Use {@link #addDrawable(Drawable)} to define the different Drawables that will represent the + * mipmap levels of this MipmapDrawable. The mipmap Drawable that will actually be used when this + * MipmapDrawable is drawn is the one which has the smallest intrinsic height greater or equal than + * the bounds' height. This selection ensures that the best available mipmap level is scaled down to + * draw this MipmapDrawable. + * </p> + * + * If the bounds' height is larger than the largest mipmap, the largest mipmap will be scaled up. + * Note that Drawables without intrinsic height (i.e. with a negative value, such as Color) will + * only be used if no other mipmap Drawable are provided. The Drawables' intrinsic heights should + * not be changed after the Drawable has been added to this MipmapDrawable. + * + * <p> + * The different mipmaps' parameters (opacity, padding, color filter, gravity...) should typically + * be similar to ensure a continuous visual appearance when the MipmapDrawable is scaled. The aspect + * ratio of the different mipmaps should especially be equal. + * </p> + * + * A typical example use of a MipmapDrawable would be for an image which is intended to be scaled at + * various sizes, and for which one wants to provide pre-scaled versions to precisely control its + * appearance. + * + * <p> + * The intrinsic size of a MipmapDrawable are inferred from those of the largest mipmap (in terms of + * {@link Drawable#getIntrinsicHeight()}). On the opposite, its minimum + * size is defined by the smallest provided mipmap. + * </p> + + * It can be defined in an XML file with the <code><mipmap></code> element. + * Each mipmap Drawable is defined in a nested <code><item></code>. For example: + * <pre> + * <mipmap xmlns:android="http://schemas.android.com/apk/res/android"> + * <item android:drawable="@drawable/my_image_8" /> + * <item android:drawable="@drawable/my_image_32" /> + * <item android:drawable="@drawable/my_image_128" /> + * </mipmap> + *</pre> + * <p> + * With this XML saved into the res/drawable/ folder of the project, it can be referenced as + * the drawable for an {@link android.widget.ImageView}. Assuming that the heights of the provided + * drawables are respectively 8, 32 and 128 pixels, the first one will be scaled down when the + * bounds' height is lower or equal than 8 pixels. The second drawable will then be used up to a + * height of 32 pixels and the largest drawable will be used for greater heights. + * </p> + * @attr ref android.R.styleable#MipmapDrawableItem_drawable + */ +public class MipmapDrawable extends DrawableContainer { + private final MipmapContainerState mMipmapContainerState; + private boolean mMutated; + + public MipmapDrawable() { + this(null, null); + } + + /** + * Adds a Drawable to the list of available mipmap Drawables. The Drawable actually used when + * this MipmapDrawable is drawn is determined from its bounds. + * + * This method has no effect if drawable is null. + * + * @param drawable The Drawable that will be added to list of available mipmap Drawables. + */ + + public void addDrawable(Drawable drawable) { + if (drawable != null) { + mMipmapContainerState.addDrawable(drawable); + onDrawableAdded(); + } + } + + private void onDrawableAdded() { + // selectDrawable assumes that the container content does not change. + // When a Drawable is added, the same index can correspond to a new Drawable, and since + // selectDrawable has a fast exit case when oldIndex==newIndex, the new drawable could end + // up not being used in place of the previous one if they happen to share the same index. + // This make sure the new computed index can actually replace the previous one. + selectDrawable(-1); + onBoundsChange(getBounds()); + } + + // overrides from Drawable + + @Override + protected void onBoundsChange(Rect bounds) { + final int index = mMipmapContainerState.indexForBounds(bounds); + + // Will call invalidateSelf() if needed + selectDrawable(index); + + super.onBoundsChange(bounds); + } + + @Override + public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) + throws XmlPullParserException, IOException { + + super.inflate(r, parser, attrs); + + int type; + + final int innerDepth = parser.getDepth() + 1; + int depth; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlPullParser.END_TAG)) { + if (type != XmlPullParser.START_TAG) { + continue; + } + + if (depth > innerDepth || !parser.getName().equals("item")) { + continue; + } + + TypedArray a = r.obtainAttributes(attrs, + com.android.internal.R.styleable.MipmapDrawableItem); + + int drawableRes = a.getResourceId( + com.android.internal.R.styleable.MipmapDrawableItem_drawable, 0); + + a.recycle(); + + Drawable dr; + if (drawableRes != 0) { + dr = r.getDrawable(drawableRes); + } else { + while ((type = parser.next()) == XmlPullParser.TEXT) { + } + if (type != XmlPullParser.START_TAG) { + throw new XmlPullParserException( + parser.getPositionDescription() + + ": <item> tag requires a 'drawable' attribute or " + + "child tag defining a drawable"); + } + dr = Drawable.createFromXmlInner(r, parser, attrs); + } + + mMipmapContainerState.addDrawable(dr); + } + + onDrawableAdded(); + } + + @Override + public Drawable mutate() { + if (!mMutated && super.mutate() == this) { + mMipmapContainerState.mMipmapHeights = mMipmapContainerState.mMipmapHeights.clone(); + mMutated = true; + } + return this; + } + + private final static class MipmapContainerState extends DrawableContainerState { + private int[] mMipmapHeights; + + MipmapContainerState(MipmapContainerState orig, MipmapDrawable owner, Resources res) { + super(orig, owner, res); + + if (orig != null) { + mMipmapHeights = orig.mMipmapHeights; + } else { + mMipmapHeights = new int[getChildren().length]; + } + + // Change the default value + setConstantSize(true); + } + + /** + * Returns the index of the child mipmap drawable that will best fit the provided bounds. + * This index is determined by comparing bounds' height and children intrinsic heights. + * The returned mipmap index is the smallest mipmap which height is greater or equal than + * the bounds' height. If the bounds' height is larger than the largest mipmap, the largest + * mipmap index is returned. + * + * @param bounds The bounds of the MipMapDrawable. + * @return The index of the child Drawable that will best fit these bounds, or -1 if there + * are no children mipmaps. + */ + public int indexForBounds(Rect bounds) { + final int boundsHeight = bounds.height(); + final int N = getChildCount(); + for (int i = 0; i < N; i++) { + if (boundsHeight <= mMipmapHeights[i]) { + return i; + } + } + + // No mipmap larger than bounds found. Use largest one which will be scaled up. + if (N > 0) { + return N - 1; + } + // No Drawable mipmap at all + return -1; + } + + /** + * Adds a Drawable to the list of available mipmap Drawables. This list can be retrieved + * using {@link DrawableContainer.DrawableContainerState#getChildren()} and this method + * ensures that it is always sorted by increasing {@link Drawable#getIntrinsicHeight()}. + * + * @param drawable The Drawable that will be added to children list + */ + public void addDrawable(Drawable drawable) { + // Insert drawable in last position, correctly resetting cached values and + // especially mComputedConstantSize + int pos = addChild(drawable); + + // Bubble sort the last drawable to restore the sort by intrinsic height + final int drawableHeight = drawable.getIntrinsicHeight(); + + while (pos > 0) { + final Drawable previousDrawable = mDrawables[pos-1]; + final int previousIntrinsicHeight = previousDrawable.getIntrinsicHeight(); + + if (drawableHeight < previousIntrinsicHeight) { + mDrawables[pos] = previousDrawable; + mMipmapHeights[pos] = previousIntrinsicHeight; + + mDrawables[pos-1] = drawable; + mMipmapHeights[pos-1] = drawableHeight; + pos--; + } else { + break; + } + } + } + + /** + * Intrinsic sizes are those of the largest available mipmap. + * Minimum sizes are those of the smallest available mipmap. + */ + @Override + protected void computeConstantSize() { + final int N = getChildCount(); + if (N > 0) { + final Drawable smallestDrawable = mDrawables[0]; + mConstantMinimumWidth = smallestDrawable.getMinimumWidth(); + mConstantMinimumHeight = smallestDrawable.getMinimumHeight(); + + final Drawable largestDrawable = mDrawables[N-1]; + mConstantWidth = largestDrawable.getIntrinsicWidth(); + mConstantHeight = largestDrawable.getIntrinsicHeight(); + } else { + mConstantWidth = mConstantHeight = -1; + mConstantMinimumWidth = mConstantMinimumHeight = 0; + } + mComputedConstantSize = true; + } + + @Override + public Drawable newDrawable() { + return new MipmapDrawable(this, null); + } + + @Override + public Drawable newDrawable(Resources res) { + return new MipmapDrawable(this, res); + } + + @Override + public void growArray(int oldSize, int newSize) { + super.growArray(oldSize, newSize); + int[] newInts = new int[newSize]; + System.arraycopy(mMipmapHeights, 0, newInts, 0, oldSize); + mMipmapHeights = newInts; + } + } + + private MipmapDrawable(MipmapContainerState state, Resources res) { + MipmapContainerState as = new MipmapContainerState(state, this, res); + mMipmapContainerState = as; + setConstantState(as); + onDrawableAdded(); + } +} diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index bad94fb..9a98d53 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -175,16 +175,9 @@ public class NinePatchDrawable extends Drawable { dest.bottom = Bitmap.scaleFromDensity(src.bottom, sdensity, tdensity); } } - - // overrides @Override public void draw(Canvas canvas) { - if (false) { - float[] pts = new float[2]; - canvas.getMatrix().mapPoints(pts); - Log.v("9patch", "Drawing 9-patch @ " + pts[0] + "," + pts[1] + ": " + getBounds()); - } mNinePatch.draw(canvas, getBounds(), mPaint); } diff --git a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java index f4cf15c..b469d2a 100644 --- a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java +++ b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java @@ -57,13 +57,11 @@ public class RoundRectShape extends RectShape { */ public RoundRectShape(float[] outerRadii, RectF inset, float[] innerRadii) { - if (outerRadii.length < 8) { - throw new ArrayIndexOutOfBoundsException( - "outer radii must have >= 8 values"); + if (outerRadii != null && outerRadii.length < 8) { + throw new ArrayIndexOutOfBoundsException("outer radii must have >= 8 values"); } if (innerRadii != null && innerRadii.length < 8) { - throw new ArrayIndexOutOfBoundsException( - "inner radii must have >= 8 values"); + throw new ArrayIndexOutOfBoundsException("inner radii must have >= 8 values"); } mOuterRadii = outerRadii; mInset = inset; @@ -97,8 +95,7 @@ public class RoundRectShape extends RectShape { r.right - mInset.right, r.bottom - mInset.bottom); if (mInnerRect.width() < w && mInnerRect.height() < h) { if (mInnerRadii != null) { - mPath.addRoundRect(mInnerRect, mInnerRadii, - Path.Direction.CCW); + mPath.addRoundRect(mInnerRect, mInnerRadii, Path.Direction.CCW); } else { mPath.addRect(mInnerRect, Path.Direction.CCW); } @@ -109,8 +106,8 @@ public class RoundRectShape extends RectShape { @Override public RoundRectShape clone() throws CloneNotSupportedException { RoundRectShape shape = (RoundRectShape) super.clone(); - shape.mOuterRadii = mOuterRadii.clone(); - shape.mInnerRadii = mInnerRadii.clone(); + shape.mOuterRadii = mOuterRadii != null ? mOuterRadii.clone() : null; + shape.mInnerRadii = mInnerRadii != null ? mInnerRadii.clone() : null; shape.mInset = new RectF(mInset); shape.mInnerRect = new RectF(mInnerRect); shape.mPath = new Path(mPath); diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 17c0778..46f3eae 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -40,6 +40,22 @@ public class Allocation extends BaseObj { mType = t; } + Allocation(int id, RenderScript rs) { + super(rs); + mID = id; + } + + @Override + void updateFromNative() { + mRS.validate(); + mName = mRS.nGetName(mID); + int typeID = mRS.nAllocationGetType(mID); + if(typeID != 0) { + mType = new Type(typeID, mRS); + mType.updateFromNative(); + } + } + public Type getType() { return mType; } @@ -76,10 +92,30 @@ public class Allocation extends BaseObj { subData1D(0, mType.getElementCount(), d); } + public void subData(int off, FieldPacker fp) { + int eSize = mType.mElement.getSizeBytes(); + final byte[] data = fp.getData(); + + int count = data.length / eSize; + if ((eSize * count) != data.length) { + throw new IllegalArgumentException("Field packer length " + data.length + + " not divisible by element size " + eSize + "."); + } + data1DChecks(off, count, data.length, data.length); + mRS.nAllocationSubData1D(mID, off, count, data, data.length); + } + private void data1DChecks(int off, int count, int len, int dataSize) { mRS.validate(); - if((off < 0) || (count < 1) || ((off + count) > mType.getElementCount())) { - throw new IllegalArgumentException("Offset or Count out of bounds."); + if(off < 0) { + throw new IllegalArgumentException("Offset must be >= 0."); + } + if(count < 1) { + throw new IllegalArgumentException("Count must be >= 1."); + } + if((off + count) > mType.getElementCount()) { + throw new IllegalArgumentException("Overflow, Available count " + mType.getElementCount() + + ", got " + count + " at offset " + off + "."); } if((len) < dataSize) { throw new IllegalArgumentException("Array too small for allocation type."); @@ -366,6 +402,21 @@ public class Allocation extends BaseObj { Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions); return createFromBitmapBoxed(rs, b, dstFmt, genMips); } + + static public Allocation createFromString(RenderScript rs, String str) + throws IllegalArgumentException { + byte[] allocArray = null; + try { + allocArray = str.getBytes("UTF-8"); + Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length); + alloc.data(allocArray); + return alloc; + } + catch (Exception e) { + Log.e("rs", "could not convert string to utf-8"); + } + return null; + } } diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java index 002fc78..28675dc 100644 --- a/graphics/java/android/renderscript/BaseObj.java +++ b/graphics/java/android/renderscript/BaseObj.java @@ -81,5 +81,10 @@ class BaseObj { mRS.nObjDestroy(mID); } + // If an object came from an a3d file, java fields need to be + // created with objects from the native layer + void updateFromNative() { + } + } diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java new file mode 100644 index 0000000..95cf88c --- /dev/null +++ b/graphics/java/android/renderscript/Byte2.java @@ -0,0 +1,37 @@ +/* + * 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 Byte2 { + public Byte2() { + } + + public byte x; + public byte y; +} + + + + diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java new file mode 100644 index 0000000..a6c0ca9 --- /dev/null +++ b/graphics/java/android/renderscript/Byte3.java @@ -0,0 +1,38 @@ +/* + * 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 Byte3 { + public Byte3() { + } + + public byte x; + public byte y; + public byte z; +} + + + + diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java new file mode 100644 index 0000000..a5bfc61 --- /dev/null +++ b/graphics/java/android/renderscript/Byte4.java @@ -0,0 +1,38 @@ +/* + * 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 Byte4 { + public Byte4() { + } + + public byte x; + public byte y; + public byte z; + public byte w; +} + + + diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 10ef05a..5d2a059 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -17,6 +17,7 @@ package android.renderscript; import java.lang.reflect.Field; +import android.util.Log; /** * @hide @@ -47,20 +48,22 @@ public class Element extends BaseObj { UNSIGNED_32 (10, 4), //UNSIGNED_64 (11, 8), - UNSIGNED_5_6_5 (12, 2), - UNSIGNED_5_5_5_1 (13, 2), - UNSIGNED_4_4_4_4 (14, 2), - - RS_ELEMENT (15, 4), - RS_TYPE (16, 4), - RS_ALLOCATION (17, 4), - RS_SAMPLER (18, 4), - RS_SCRIPT (19, 4), - RS_MESH (20, 4), - RS_PROGRAM_FRAGMENT (21, 4), - RS_PROGRAM_VERTEX (22, 4), - RS_PROGRAM_RASTER (23, 4), - RS_PROGRAM_STORE (24, 4); + BOOLEAN(12, 1), + + UNSIGNED_5_6_5 (13, 2), + UNSIGNED_5_5_5_1 (14, 2), + UNSIGNED_4_4_4_4 (15, 2), + + RS_ELEMENT (16, 4), + RS_TYPE (17, 4), + RS_ALLOCATION (18, 4), + RS_SAMPLER (19, 4), + RS_SCRIPT (20, 4), + RS_MESH (21, 4), + RS_PROGRAM_FRAGMENT (22, 4), + RS_PROGRAM_VERTEX (23, 4), + RS_PROGRAM_RASTER (24, 4), + RS_PROGRAM_STORE (25, 4); int mID; int mSize; @@ -72,12 +75,6 @@ public class Element extends BaseObj { public enum DataKind { USER (0), - COLOR (1), - POSITION (2), - TEXTURE (3), - NORMAL (4), - INDEX (5), - POINT_SIZE(6), PIXEL_L (7), PIXEL_A (8), @@ -91,41 +88,133 @@ public class Element extends BaseObj { } } - public static Element USER_U8(RenderScript rs) { - if(rs.mElement_USER_U8 == null) { - rs.mElement_USER_U8 = createUser(rs, DataType.UNSIGNED_8); + public static Element BOOLEAN(RenderScript rs) { + if(rs.mElement_BOOLEAN == null) { + rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN); + } + return rs.mElement_BOOLEAN; + } + + public static Element U8(RenderScript rs) { + if(rs.mElement_U8 == null) { + rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8); + } + return rs.mElement_U8; + } + + public static Element I8(RenderScript rs) { + if(rs.mElement_I8 == null) { + rs.mElement_I8 = createUser(rs, DataType.SIGNED_8); + } + return rs.mElement_I8; + } + + public static Element U16(RenderScript rs) { + if(rs.mElement_U16 == null) { + rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16); + } + return rs.mElement_U16; + } + + public static Element I16(RenderScript rs) { + if(rs.mElement_I16 == null) { + rs.mElement_I16 = createUser(rs, DataType.SIGNED_16); + } + return rs.mElement_I16; + } + + public static Element U32(RenderScript rs) { + if(rs.mElement_U32 == null) { + rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32); + } + return rs.mElement_U32; + } + + public static Element I32(RenderScript rs) { + if(rs.mElement_I32 == null) { + rs.mElement_I32 = createUser(rs, DataType.SIGNED_32); + } + return rs.mElement_I32; + } + + public static Element F32(RenderScript rs) { + if(rs.mElement_F32 == null) { + rs.mElement_F32 = createUser(rs, DataType.FLOAT_32); + } + return rs.mElement_F32; + } + + public static Element ELEMENT(RenderScript rs) { + if(rs.mElement_ELEMENT == null) { + rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT); + } + return rs.mElement_ELEMENT; + } + + public static Element TYPE(RenderScript rs) { + if(rs.mElement_TYPE == null) { + rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE); + } + return rs.mElement_TYPE; + } + + public static Element ALLOCATION(RenderScript rs) { + if(rs.mElement_ALLOCATION == null) { + rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION); + } + return rs.mElement_ALLOCATION; + } + + public static Element SAMPLER(RenderScript rs) { + if(rs.mElement_SAMPLER == null) { + rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER); + } + return rs.mElement_SAMPLER; + } + + public static Element SCRIPT(RenderScript rs) { + if(rs.mElement_SCRIPT == null) { + rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT); + } + return rs.mElement_SCRIPT; + } + + public static Element MESH(RenderScript rs) { + if(rs.mElement_MESH == null) { + rs.mElement_MESH = createUser(rs, DataType.RS_MESH); } - return rs.mElement_USER_U8; + return rs.mElement_MESH; } - public static Element USER_I8(RenderScript rs) { - if(rs.mElement_USER_I8 == null) { - rs.mElement_USER_I8 = createUser(rs, DataType.SIGNED_8); + public static Element PROGRAM_FRAGMENT(RenderScript rs) { + if(rs.mElement_PROGRAM_FRAGMENT == null) { + rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT); } - return rs.mElement_USER_I8; + return rs.mElement_PROGRAM_FRAGMENT; } - public static Element USER_U32(RenderScript rs) { - if(rs.mElement_USER_U32 == null) { - rs.mElement_USER_U32 = createUser(rs, DataType.UNSIGNED_32); + public static Element PROGRAM_VERTEX(RenderScript rs) { + if(rs.mElement_PROGRAM_VERTEX == null) { + rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX); } - return rs.mElement_USER_U32; + return rs.mElement_PROGRAM_VERTEX; } - public static Element USER_I32(RenderScript rs) { - if(rs.mElement_USER_I32 == null) { - rs.mElement_USER_I32 = createUser(rs, DataType.SIGNED_32); + public static Element PROGRAM_RASTER(RenderScript rs) { + if(rs.mElement_PROGRAM_RASTER == null) { + rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER); } - return rs.mElement_USER_I32; + return rs.mElement_PROGRAM_RASTER; } - public static Element USER_F32(RenderScript rs) { - if(rs.mElement_USER_F32 == null) { - rs.mElement_USER_F32 = createUser(rs, DataType.FLOAT_32); + public static Element PROGRAM_STORE(RenderScript rs) { + if(rs.mElement_PROGRAM_STORE == null) { + rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE); } - return rs.mElement_USER_F32; + return rs.mElement_PROGRAM_STORE; } + public static Element A_8(RenderScript rs) { if(rs.mElement_A_8 == null) { rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A); @@ -168,54 +257,34 @@ public class Element extends BaseObj { return rs.mElement_RGBA_8888; } - public static Element INDEX_16(RenderScript rs) { - if(rs.mElement_INDEX_16 == null) { - rs.mElement_INDEX_16 = createIndex(rs); - } - return rs.mElement_INDEX_16; - } - - public static Element ATTRIB_POSITION_2(RenderScript rs) { - if(rs.mElement_POSITION_2 == null) { - rs.mElement_POSITION_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 2); + public static Element F32_2(RenderScript rs) { + if(rs.mElement_FLOAT_2 == null) { + rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2); } - return rs.mElement_POSITION_2; + return rs.mElement_FLOAT_2; } - public static Element ATTRIB_POSITION_3(RenderScript rs) { - if(rs.mElement_POSITION_3 == null) { - rs.mElement_POSITION_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.POSITION, 3); + public static Element F32_3(RenderScript rs) { + if(rs.mElement_FLOAT_3 == null) { + rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3); } - return rs.mElement_POSITION_3; + return rs.mElement_FLOAT_3; } - public static Element ATTRIB_TEXTURE_2(RenderScript rs) { - if(rs.mElement_TEXTURE_2 == null) { - rs.mElement_TEXTURE_2 = createAttrib(rs, DataType.FLOAT_32, DataKind.TEXTURE, 2); + public static Element F32_4(RenderScript rs) { + if(rs.mElement_FLOAT_4 == null) { + rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4); } - return rs.mElement_TEXTURE_2; + return rs.mElement_FLOAT_4; } - public static Element ATTRIB_NORMAL_3(RenderScript rs) { - if(rs.mElement_NORMAL_3 == null) { - rs.mElement_NORMAL_3 = createAttrib(rs, DataType.FLOAT_32, DataKind.NORMAL, 3); + public static Element U8_4(RenderScript rs) { + if(rs.mElement_UCHAR_4 == null) { + rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4); } - return rs.mElement_NORMAL_3; + return rs.mElement_UCHAR_4; } - public static Element ATTRIB_COLOR_U8_4(RenderScript rs) { - if(rs.mElement_COLOR_U8_4 == null) { - rs.mElement_COLOR_U8_4 = createAttrib(rs, DataType.UNSIGNED_8, DataKind.COLOR, 4); - } - return rs.mElement_COLOR_U8_4; - } - - public static Element ATTRIB_COLOR_F32_4(RenderScript rs) { - if(rs.mElement_COLOR_F32_4 == null) { - rs.mElement_COLOR_F32_4 = createAttrib(rs, DataType.FLOAT_32, DataKind.COLOR, 4); - } - return rs.mElement_COLOR_F32_4; - } Element(RenderScript rs, Element[] e, String[] n) { super(rs); @@ -240,32 +309,48 @@ public class Element extends BaseObj { mID = rs.nElementCreate(dt.mID, dk.mID, norm, size); } - public void destroy() throws IllegalStateException { - super.destroy(); + Element(RenderScript rs, int id) { + super(rs); + mID = id; } - public static Element createFromClass(RenderScript rs, Class c) { - rs.validate(); - Field[] fields = c.getFields(); - Builder b = new Builder(rs); - - for(Field f: fields) { - Class fc = f.getType(); - if(fc == int.class) { - b.add(createUser(rs, DataType.SIGNED_32), f.getName()); - } else if(fc == short.class) { - b.add(createUser(rs, DataType.SIGNED_16), f.getName()); - } else if(fc == byte.class) { - b.add(createUser(rs, DataType.SIGNED_8), f.getName()); - } else if(fc == float.class) { - b.add(createUser(rs, DataType.FLOAT_32), f.getName()); - } else { - throw new IllegalArgumentException("Unkown field type"); + @Override + void updateFromNative() { + + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + int[] dataBuffer = new int[5]; + mRS.nElementGetNativeData(mID, dataBuffer); + for (DataType dt: DataType.values()) { + if(dt.mID == dataBuffer[0]){ + mType = dt; + } + } + for (DataKind dk: DataKind.values()) { + if(dk.mID == dataBuffer[1]){ + mKind = dk; + } + } + + mNormalized = dataBuffer[2] == 1 ? true : false; + mVectorSize = dataBuffer[3]; + int numSubElements = dataBuffer[4]; + if(numSubElements > 0) { + mElements = new Element[numSubElements]; + mElementNames = new String[numSubElements]; + + int[] subElementIds = new int[numSubElements]; + mRS.nElementGetSubElements(mID, subElementIds, mElementNames); + for(int i = 0; i < numSubElements; i ++) { + mElements[i] = new Element(mRS, subElementIds[i]); + mElements[i].updateFromNative(); } } - return b.create(); + } + public void destroy() throws IllegalStateException { + super.destroy(); + } ///////////////////////////////////////// public static Element createUser(RenderScript rs, DataType dt) { @@ -279,59 +364,6 @@ public class Element extends BaseObj { return new Element(rs, dt, DataKind.USER, false, size); } - public static Element createIndex(RenderScript rs) { - return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1); - } - - public static Element createAttrib(RenderScript rs, DataType dt, DataKind dk, int size) { - if (!(dt == DataType.FLOAT_32 || - dt == DataType.UNSIGNED_8 || - dt == DataType.UNSIGNED_16 || - dt == DataType.UNSIGNED_32 || - dt == DataType.SIGNED_8 || - dt == DataType.SIGNED_16 || - dt == DataType.SIGNED_32)) { - throw new IllegalArgumentException("Unsupported DataType"); - } - - if (!(dk == DataKind.COLOR || - dk == DataKind.POSITION || - dk == DataKind.TEXTURE || - dk == DataKind.NORMAL || - dk == DataKind.POINT_SIZE || - dk == DataKind.USER)) { - throw new IllegalArgumentException("Unsupported DataKind"); - } - - if (dk == DataKind.COLOR && - ((dt != DataType.FLOAT_32 && dt != DataType.UNSIGNED_8) || - size < 3 || size > 4)) { - throw new IllegalArgumentException("Bad combo"); - } - if (dk == DataKind.POSITION && (size < 1 || size > 4)) { - throw new IllegalArgumentException("Bad combo"); - } - if (dk == DataKind.TEXTURE && - (dt != DataType.FLOAT_32 || size < 1 || size > 4)) { - throw new IllegalArgumentException("Bad combo"); - } - if (dk == DataKind.NORMAL && - (dt != DataType.FLOAT_32 || size != 3)) { - throw new IllegalArgumentException("Bad combo"); - } - if (dk == DataKind.POINT_SIZE && - (dt != DataType.FLOAT_32 || size != 1)) { - throw new IllegalArgumentException("Bad combo"); - } - - boolean norm = false; - if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) { - norm = true; - } - - return new Element(rs, dt, dk, norm, size); - } - public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) { if (!(dk == DataKind.PIXEL_L || dk == DataKind.PIXEL_A || diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java index b26e47d..f03b51c 100644 --- a/graphics/java/android/renderscript/FieldPacker.java +++ b/graphics/java/android/renderscript/FieldPacker.java @@ -33,21 +33,28 @@ public class FieldPacker { } } - void reset() { + public void reset() { mPos = 0; } + public void reset(int i) { + mPos = i; + } + + public void skip(int i) { + mPos += i; + } - void addI8(byte v) { + public void addI8(byte v) { mData[mPos++] = v; } - void addI16(short v) { + public void addI16(short v) { align(2); mData[mPos++] = (byte)(v & 0xff); mData[mPos++] = (byte)(v >> 8); } - void addI32(int v) { + public void addI32(int v) { align(4); mData[mPos++] = (byte)(v & 0xff); mData[mPos++] = (byte)((v >> 8) & 0xff); @@ -55,7 +62,7 @@ public class FieldPacker { mData[mPos++] = (byte)((v >> 24) & 0xff); } - void addI64(long v) { + public void addI64(long v) { align(8); mData[mPos++] = (byte)(v & 0xff); mData[mPos++] = (byte)((v >> 8) & 0xff); @@ -67,14 +74,14 @@ public class FieldPacker { mData[mPos++] = (byte)((v >> 56) & 0xff); } - void addU8(short v) { + public void addU8(short v) { if ((v < 0) || (v > 0xff)) { throw new IllegalArgumentException("Saving value out of range for type"); } mData[mPos++] = (byte)v; } - void addU16(int v) { + public void addU16(int v) { if ((v < 0) || (v > 0xffff)) { throw new IllegalArgumentException("Saving value out of range for type"); } @@ -83,7 +90,7 @@ public class FieldPacker { mData[mPos++] = (byte)(v >> 8); } - void addU32(long v) { + public void addU32(long v) { if ((v < 0) || (v > 0xffffffff)) { throw new IllegalArgumentException("Saving value out of range for type"); } @@ -94,7 +101,7 @@ public class FieldPacker { mData[mPos++] = (byte)((v >> 24) & 0xff); } - void addU64(long v) { + public void addU64(long v) { if (v < 0) { throw new IllegalArgumentException("Saving value out of range for type"); } @@ -109,15 +116,139 @@ public class FieldPacker { mData[mPos++] = (byte)((v >> 56) & 0xff); } - void addF32(float v) { + public void addF32(float v) { addI32(Float.floatToRawIntBits(v)); } - void addF64(float v) { + public void addF64(float v) { addI64(Double.doubleToRawLongBits(v)); } - final byte[] getData() { + public void addObj(BaseObj obj) { + if (obj != null) { + addI32(obj.getID()); + } else { + addI32(0); + } + } + + public void addF32(Float2 v) { + addF32(v.x); + addF32(v.y); + } + public void addF32(Float3 v) { + addF32(v.x); + addF32(v.y); + addF32(v.z); + } + public void addF32(Float4 v) { + addF32(v.x); + addF32(v.y); + addF32(v.z); + addF32(v.w); + } + + public void addI8(Byte2 v) { + addI8(v.x); + addI8(v.y); + } + public void addI8(Byte3 v) { + addI8(v.x); + addI8(v.y); + addI8(v.z); + } + public void addI8(Byte4 v) { + addI8(v.x); + addI8(v.y); + addI8(v.z); + addI8(v.w); + } + + public void addU8(Short2 v) { + addU8(v.x); + addU8(v.y); + } + public void addU8(Short3 v) { + addU8(v.x); + addU8(v.y); + addU8(v.z); + } + public void addU8(Short4 v) { + addU8(v.x); + addU8(v.y); + addU8(v.z); + addU8(v.w); + } + + public void addI16(Short2 v) { + addI16(v.x); + addI16(v.y); + } + public void addI16(Short3 v) { + addI16(v.x); + addI16(v.y); + addI16(v.z); + } + public void addI16(Short4 v) { + addI16(v.x); + addI16(v.y); + addI16(v.z); + addI16(v.w); + } + + public void addU16(Int2 v) { + addU16(v.x); + addU16(v.y); + } + public void addU16(Int3 v) { + addU16(v.x); + addU16(v.y); + addU16(v.z); + } + public void addU16(Int4 v) { + addU16(v.x); + addU16(v.y); + addU16(v.z); + addU16(v.w); + } + + public void addI32(Int2 v) { + addI32(v.x); + addI32(v.y); + } + public void addI32(Int3 v) { + addI32(v.x); + addI32(v.y); + addI32(v.z); + } + public void addI32(Int4 v) { + addI32(v.x); + addI32(v.y); + addI32(v.z); + addI32(v.w); + } + + public void addU32(Int2 v) { + addU32(v.x); + addU32(v.y); + } + public void addU32(Int3 v) { + addU32(v.x); + addU32(v.y); + addU32(v.z); + } + public void addU32(Int4 v) { + addU32(v.x); + addU32(v.y); + addU32(v.z); + addU32(v.w); + } + + public void addBoolean(boolean v) { + addI8((byte)(v ? 1 : 0)); + } + + public final byte[] getData() { return mData; } diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java new file mode 100644 index 0000000..302a5f4 --- /dev/null +++ b/graphics/java/android/renderscript/FileA3D.java @@ -0,0 +1,218 @@ +/* + * 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 FileA3D extends BaseObj { + + public enum ClassID { + + UNKNOWN, + MESH, + TYPE, + ELEMENT, + ALLOCATION, + PROGRAM_VERTEX, + PROGRAM_RASTER, + PROGRAM_FRAGMENT, + PROGRAM_STORE, + SAMPLER, + ANIMATION, + LIGHT, + ADAPTER_1D, + ADAPTER_2D, + SCRIPT_C; + + public static ClassID toClassID(int intID) { + return ClassID.values()[intID]; + } + } + + // Read only class with index entries + public static class IndexEntry { + RenderScript mRS; + int mIndex; + int mID; + String mName; + ClassID mClassID; + BaseObj mLoadedObj; + + public String getName() { + return mName; + } + + public ClassID getClassID() { + return mClassID; + } + + public BaseObj getObject() { + mRS.validate(); + BaseObj obj = internalCreate(mRS, this); + return obj; + } + + static synchronized BaseObj internalCreate(RenderScript rs, IndexEntry entry) { + if(entry.mLoadedObj != null) { + return entry.mLoadedObj; + } + + if(entry.mClassID == ClassID.UNKNOWN) { + return null; + } + + int objectID = rs.nFileA3DGetEntryByIndex(entry.mID, entry.mIndex); + if(objectID == 0) { + return null; + } + + switch (entry.mClassID) { + case MESH: + entry.mLoadedObj = new Mesh(objectID, rs); + break; + case TYPE: + entry.mLoadedObj = new Type(objectID, rs); + break; + case ELEMENT: + entry.mLoadedObj = null; + break; + case ALLOCATION: + entry.mLoadedObj = null; + break; + case PROGRAM_VERTEX: + entry.mLoadedObj = new ProgramVertex(objectID, rs); + break; + case PROGRAM_RASTER: + break; + case PROGRAM_FRAGMENT: + break; + case PROGRAM_STORE: + break; + case SAMPLER: + break; + case ANIMATION: + break; + case LIGHT: + break; + case ADAPTER_1D: + break; + case ADAPTER_2D: + break; + case SCRIPT_C: + break; + } + + entry.mLoadedObj.updateFromNative(); + + return entry.mLoadedObj; + } + + IndexEntry(RenderScript rs, int index, int id, String name, ClassID classID) { + mRS = rs; + mIndex = index; + mID = id; + mName = name; + mClassID = classID; + mLoadedObj = null; + } + } + + IndexEntry[] mFileEntries; + + FileA3D(int id, RenderScript rs) { + super(rs); + mID = id; + } + + private void initEntries() { + int numFileEntries = mRS.nFileA3DGetNumIndexEntries(mID); + if(numFileEntries <= 0) { + return; + } + + mFileEntries = new IndexEntry[numFileEntries]; + int[] ids = new int[numFileEntries]; + String[] names = new String[numFileEntries]; + + mRS.nFileA3DGetIndexEntries(mID, numFileEntries, ids, names); + + for(int i = 0; i < numFileEntries; i ++) { + mFileEntries[i] = new IndexEntry(mRS, i, mID, names[i], ClassID.toClassID(ids[i])); + } + } + + public int getNumIndexEntries() { + if(mFileEntries == null) { + return 0; + } + return mFileEntries.length; + } + + public IndexEntry getIndexEntry(int index) { + if(getNumIndexEntries() == 0 || index < 0 || index >= mFileEntries.length) { + return null; + } + return mFileEntries[index]; + } + + static public FileA3D createFromResource(RenderScript rs, Resources res, int id) + throws IllegalArgumentException { + + rs.validate(); + InputStream is = null; + try { + final TypedValue value = new TypedValue(); + is = res.openRawResource(id, value); + + int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); + + int fileId = rs.nFileA3DCreateFromAssetStream(asset); + + if(fileId == 0) { + throw new IllegalStateException("Load failed."); + } + FileA3D fa3d = new FileA3D(fileId, rs); + fa3d.initEntries(); + return fa3d; + + } catch (Exception e) { + // Ignore + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + // Ignore + } + } + } + + return null; + } +} diff --git a/graphics/java/android/renderscript/Vector2f.java b/graphics/java/android/renderscript/Float2.java index 567d57f..8fea91f 100644 --- a/graphics/java/android/renderscript/Vector2f.java +++ b/graphics/java/android/renderscript/Float2.java @@ -24,8 +24,8 @@ import android.util.Log; * @hide * **/ -public class Vector2f { - public Vector2f() { +public class Float2 { + public Float2() { } public float x; diff --git a/graphics/java/android/renderscript/Vector3f.java b/graphics/java/android/renderscript/Float3.java index f2842f3..9d9e406 100644 --- a/graphics/java/android/renderscript/Vector3f.java +++ b/graphics/java/android/renderscript/Float3.java @@ -24,8 +24,8 @@ import android.util.Log; * @hide * **/ -public class Vector3f { - public Vector3f() { +public class Float3 { + public Float3() { } public float x; diff --git a/graphics/java/android/renderscript/Vector4f.java b/graphics/java/android/renderscript/Float4.java index fabd959..a703e80 100644 --- a/graphics/java/android/renderscript/Vector4f.java +++ b/graphics/java/android/renderscript/Float4.java @@ -24,8 +24,8 @@ import android.util.Log; * @hide * **/ -public class Vector4f { - public Vector4f() { +public class Float4 { + public Float4() { } public float x; diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java new file mode 100644 index 0000000..41f8827 --- /dev/null +++ b/graphics/java/android/renderscript/Font.java @@ -0,0 +1,59 @@ +/* + * 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.util.Log; +import android.util.TypedValue; + +/** + * @hide + * + **/ +public class Font extends BaseObj { + + Font(int id, RenderScript rs) { + super(rs); + mID = id; + } + + static public Font create(RenderScript rs, Resources res, String fileName, int size) + throws IllegalArgumentException { + + rs.validate(); + try { + int dpi = res.getDisplayMetrics().densityDpi; + int fontId = rs.nFontCreateFromFile(fileName, size, dpi); + + if(fontId == 0) { + throw new IllegalStateException("Load loading a font"); + } + Font rsFont = new Font(fontId, rs); + + return rsFont; + + } catch (Exception e) { + // Ignore + } + + return null; + } +} diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java new file mode 100644 index 0000000..56e2fe9 --- /dev/null +++ b/graphics/java/android/renderscript/Int2.java @@ -0,0 +1,37 @@ +/* + * 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 Int2 { + public Int2() { + } + + public int x; + public int y; +} + + + + diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java new file mode 100644 index 0000000..1b27509 --- /dev/null +++ b/graphics/java/android/renderscript/Int3.java @@ -0,0 +1,38 @@ +/* + * 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 Int3 { + public Int3() { + } + + public int x; + public int y; + public int z; +} + + + + diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java new file mode 100644 index 0000000..3d6f3f5 --- /dev/null +++ b/graphics/java/android/renderscript/Int4.java @@ -0,0 +1,38 @@ +/* + * 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 Int4 { + public Int4() { + } + + public int x; + public int y; + public int z; + public int w; +} + + + diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java new file mode 100644 index 0000000..11ead2f --- /dev/null +++ b/graphics/java/android/renderscript/Long2.java @@ -0,0 +1,37 @@ +/* + * 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 Long2 { + public Long2() { + } + + public long x; + public long y; +} + + + + diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java new file mode 100644 index 0000000..1604532 --- /dev/null +++ b/graphics/java/android/renderscript/Long3.java @@ -0,0 +1,38 @@ +/* + * 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 Long3 { + public Long3() { + } + + public long x; + public long y; + public long z; +} + + + + diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java new file mode 100644 index 0000000..2fd2747 --- /dev/null +++ b/graphics/java/android/renderscript/Long4.java @@ -0,0 +1,38 @@ +/* + * 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 Long4 { + public Long4() { + } + + public long x; + public long y; + public long z; + public long w; +} + + + diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java index 4b5e61b..99d23db 100644 --- a/graphics/java/android/renderscript/Matrix2f.java +++ b/graphics/java/android/renderscript/Matrix2f.java @@ -51,6 +51,57 @@ public class Matrix2f { System.arraycopy(mMat, 0, src, 0, 4); } + public void loadRotate(float rot) { + float c, s; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + mMat[0] = c; + mMat[1] = -s; + mMat[2] = s; + mMat[3] = c; + } + + public void loadScale(float x, float y) { + loadIdentity(); + mMat[0] = x; + mMat[3] = y; + } + public void loadMultiply(Matrix2f lhs, Matrix2f rhs) { + for (int i=0 ; i<2 ; i++) { + float ri0 = 0; + float ri1 = 0; + for (int j=0 ; j<2 ; j++) { + float rhs_ij = rhs.get(i,j); + ri0 += lhs.get(j,0) * rhs_ij; + ri1 += lhs.get(j,1) * rhs_ij; + } + set(i,0, ri0); + set(i,1, ri1); + } + } + + public void multiply(Matrix2f rhs) { + Matrix2f tmp = new Matrix2f(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + public void rotate(float rot) { + Matrix2f tmp = new Matrix2f(); + tmp.loadRotate(rot); + multiply(tmp); + } + public void scale(float x, float y) { + Matrix2f tmp = new Matrix2f(); + tmp.loadScale(x, y); + multiply(tmp); + } + public void transpose() { + float temp = mMat[1]; + mMat[1] = mMat[2]; + mMat[2] = temp; + } + final float[] mMat; } diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java index 19d7b43..961bc5d 100644 --- a/graphics/java/android/renderscript/Matrix3f.java +++ b/graphics/java/android/renderscript/Matrix3f.java @@ -57,6 +57,124 @@ public class Matrix3f { System.arraycopy(mMat, 0, src, 0, 9); } + public void loadRotate(float rot, float x, float y, float z) { + float c, s; + 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[3] = xy*nc - zs; + mMat[6] = zx*nc + ys; + mMat[1] = xy*nc + zs; + mMat[4] = y*y*nc + c; + mMat[9] = yz*nc - xs; + mMat[2] = zx*nc - ys; + mMat[6] = yz*nc + xs; + mMat[8] = z*z*nc + c; + } + + public void loadRotate(float rot) { + float c, s; + rot *= (float)(java.lang.Math.PI / 180.0f); + c = (float)java.lang.Math.cos(rot); + s = (float)java.lang.Math.sin(rot); + mMat[0] = c; + mMat[1] = -s; + mMat[3] = s; + mMat[4] = c; + } + + public void loadScale(float x, float y) { + loadIdentity(); + mMat[0] = x; + mMat[4] = y; + } + + public void loadScale(float x, float y, float z) { + loadIdentity(); + mMat[0] = x; + mMat[4] = y; + mMat[8] = z; + } + + public void loadTranslate(float x, float y) { + loadIdentity(); + mMat[6] = x; + mMat[7] = y; + } + + public void loadMultiply(Matrix3f lhs, Matrix3f rhs) { + for (int i=0 ; i<3 ; i++) { + float ri0 = 0; + float ri1 = 0; + float ri2 = 0; + for (int j=0 ; j<3 ; 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; + } + set(i,0, ri0); + set(i,1, ri1); + set(i,2, ri2); + } + } + + public void multiply(Matrix3f rhs) { + Matrix3f tmp = new Matrix3f(); + tmp.loadMultiply(this, rhs); + load(tmp); + } + public void rotate(float rot, float x, float y, float z) { + Matrix3f tmp = new Matrix3f(); + tmp.loadRotate(rot, x, y, z); + multiply(tmp); + } + public void rotate(float rot) { + Matrix3f tmp = new Matrix3f(); + tmp.loadRotate(rot); + multiply(tmp); + } + public void scale(float x, float y) { + Matrix3f tmp = new Matrix3f(); + tmp.loadScale(x, y); + multiply(tmp); + } + public void scale(float x, float y, float z) { + Matrix3f tmp = new Matrix3f(); + tmp.loadScale(x, y, z); + multiply(tmp); + } + public void translate(float x, float y) { + Matrix3f tmp = new Matrix3f(); + tmp.loadTranslate(x, y); + multiply(tmp); + } + public void transpose() { + for(int i = 0; i < 2; ++i) { + for(int j = i + 1; j < 3; ++j) { + float temp = mMat[i*3 + j]; + mMat[i*3 + j] = mMat[j*3 + i]; + mMat[j*3 + i] = temp; + } + } + } + final float[] mMat; } diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java index ebd5bde..5ffc21a 100644 --- a/graphics/java/android/renderscript/Matrix4f.java +++ b/graphics/java/android/renderscript/Matrix4f.java @@ -179,6 +179,85 @@ public class Matrix4f { tmp.loadTranslate(x, y, z); multiply(tmp); } + private float computeCofactor(int i, int j) { + int c0 = (i+1) % 4; + int c1 = (i+2) % 4; + int c2 = (i+3) % 4; + int r0 = (j+1) % 4; + int r1 = (j+2) % 4; + int r2 = (j+3) % 4; + + float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] - + mMat[c1 + 4*r2] * mMat[c2 + 4*r1])) + - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] - + mMat[c1 + 4*r2] * mMat[c2 + 4*r0])) + + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] - + mMat[c1 + 4*r1] * mMat[c2 + 4*r0])); + + float cofactor = ((i+j) & 1) != 0 ? -minor : minor; + return cofactor; + } + + public boolean inverse() { + + Matrix4f result = new Matrix4f(); + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.mMat[4*i + j] = computeCofactor(i, j); + } + } + + // Dot product of 0th column of source and 0th row of result + float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] + + mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3]; + + if (Math.abs(det) < 1e-6) { + return false; + } + + det = 1.0f / det; + for (int i = 0; i < 16; ++i) { + mMat[i] = result.mMat[i] * det; + } + + return true; + } + + public boolean inverseTranspose() { + + Matrix4f result = new Matrix4f(); + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + result.mMat[4*j + i] = computeCofactor(i, j); + } + } + + float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] + + mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12]; + + if (Math.abs(det) < 1e-6) { + return false; + } + + det = 1.0f / det; + for (int i = 0; i < 16; ++i) { + mMat[i] = result.mMat[i] * det; + } + + return true; + } + + public void transpose() { + for(int i = 0; i < 3; ++i) { + for(int j = i + 1; j < 4; ++j) { + float temp = mMat[i*4 + j]; + mMat[i*4 + j] = mMat[j*4 + i]; + mMat[j*4 + i] = temp; + } + } + } final float[] mMat; } diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java new file mode 100644 index 0000000..bf02319 --- /dev/null +++ b/graphics/java/android/renderscript/Mesh.java @@ -0,0 +1,480 @@ +/* + * 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.util.Vector; + +import android.util.Config; +import android.util.Log; + +/** + * @hide + * + **/ +public class Mesh extends BaseObj { + + Allocation[] mVertexBuffers; + Allocation[] mIndexBuffers; + Primitive[] mPrimitives; + + Mesh(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public int getVertexAllocationCount() { + if(mVertexBuffers == null) { + return 0; + } + return mVertexBuffers.length; + } + public Allocation getVertexAllocation(int slot) { + return mVertexBuffers[slot]; + } + + public int getPrimitiveCount() { + if(mIndexBuffers == null) { + return 0; + } + return mIndexBuffers.length; + } + public Allocation getIndexAllocation(int slot) { + return mIndexBuffers[slot]; + } + public Primitive getPrimitive(int slot) { + return mPrimitives[slot]; + } + + @Override + void updateFromNative() { + mName = mRS.nGetName(mID); + int vtxCount = mRS.nMeshGetVertexBufferCount(mID); + int idxCount = mRS.nMeshGetIndexCount(mID); + + int[] vtxIDs = new int[vtxCount]; + int[] idxIDs = new int[idxCount]; + int[] primitives = new int[idxCount]; + + mRS.nMeshGetVertices(mID, vtxIDs, vtxCount); + mRS.nMeshGetIndices(mID, idxIDs, primitives, vtxCount); + + mVertexBuffers = new Allocation[vtxCount]; + mIndexBuffers = new Allocation[idxCount]; + mPrimitives = new Primitive[idxCount]; + + for(int i = 0; i < vtxCount; i ++) { + if(vtxIDs[i] != 0) { + mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS); + mVertexBuffers[i].updateFromNative(); + } + } + + for(int i = 0; i < idxCount; i ++) { + if(idxIDs[i] != 0) { + mIndexBuffers[i] = new Allocation(idxIDs[i], mRS); + mIndexBuffers[i].updateFromNative(); + } + mPrimitives[i] = Primitive.values()[primitives[i]]; + } + } + + public static class Builder { + RenderScript mRS; + + class Entry { + Type t; + Element e; + int size; + Primitive prim; + } + + int mVertexTypeCount; + Entry[] mVertexTypes; + Vector mIndexTypes; + + public Builder(RenderScript rs) { + mRS = rs; + mVertexTypeCount = 0; + mVertexTypes = new Entry[16]; + mIndexTypes = new Vector(); + } + + 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; + mVertexTypes[mVertexTypeCount].e = null; + 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].t = null; + mVertexTypes[mVertexTypeCount].e = e; + mVertexTypes[mVertexTypeCount].size = size; + mVertexTypeCount++; + return addedIndex; + } + + public int addIndexType(Type t, Primitive p) { + int addedIndex = mIndexTypes.size(); + Entry indexType = new Entry(); + indexType.t = t; + indexType.e = null; + indexType.size = 0; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return addedIndex; + } + + public int addIndexType(Primitive p) { + int addedIndex = mIndexTypes.size(); + Entry indexType = new Entry(); + indexType.t = null; + indexType.e = null; + indexType.size = 0; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return addedIndex; + } + + public int addIndexType(Element e, int size, Primitive p) { + int addedIndex = mIndexTypes.size(); + Entry indexType = new Entry(); + indexType.t = null; + indexType.e = e; + indexType.size = size; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return addedIndex; + } + + Type newType(Element e, int size) { + Type.Builder tb = new Type.Builder(mRS, e); + tb.add(Dimension.X, size); + return tb.create(); + } + + static synchronized Mesh internalCreate(RenderScript rs, Builder b) { + + int id = rs.nMeshCreate(b.mVertexTypeCount, b.mIndexTypes.size()); + Mesh newMesh = new Mesh(id, rs); + newMesh.mIndexBuffers = new Allocation[b.mIndexTypes.size()]; + newMesh.mPrimitives = new Primitive[b.mIndexTypes.size()]; + newMesh.mVertexBuffers = new Allocation[b.mVertexTypeCount]; + + for(int ct = 0; ct < b.mIndexTypes.size(); ct ++) { + Allocation alloc = null; + Entry entry = (Entry)b.mIndexTypes.elementAt(ct); + if (entry.t != null) { + alloc = Allocation.createTyped(rs, entry.t); + } + else if(entry.e != null) { + alloc = Allocation.createSized(rs, entry.e, entry.size); + } + int allocID = (alloc == null) ? 0 : alloc.getID(); + rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct); + newMesh.mIndexBuffers[ct] = alloc; + newMesh.mPrimitives[ct] = entry.prim; + } + + for(int ct = 0; ct < b.mVertexTypeCount; ct ++) { + Allocation alloc = null; + Entry entry = b.mVertexTypes[ct]; + if (entry.t != null) { + alloc = Allocation.createTyped(rs, entry.t); + } else if(entry.e != null) { + alloc = Allocation.createSized(rs, entry.e, entry.size); + } + rs.nMeshBindVertex(id, alloc.getID(), ct); + newMesh.mVertexBuffers[ct] = alloc; + } + + return newMesh; + } + + public Mesh create() { + mRS.validate(); + Mesh sm = internalCreate(mRS, this); + return sm; + } + } + + public static class AllocationBuilder { + RenderScript mRS; + + class Entry { + Allocation a; + Primitive prim; + } + + int mVertexTypeCount; + Entry[] mVertexTypes; + + Vector mIndexTypes; + + public AllocationBuilder(RenderScript rs) { + mRS = rs; + mVertexTypeCount = 0; + mVertexTypes = new Entry[16]; + mIndexTypes = new Vector(); + } + + public int addVertexAllocation(Allocation a) throws IllegalStateException { + if (mVertexTypeCount >= mVertexTypes.length) { + throw new IllegalStateException("Max vertex types exceeded."); + } + + int addedIndex = mVertexTypeCount; + mVertexTypes[mVertexTypeCount] = new Entry(); + mVertexTypes[mVertexTypeCount].a = a; + mVertexTypeCount++; + return addedIndex; + } + + public int addIndexAllocation(Allocation a, Primitive p) { + int addedIndex = mIndexTypes.size(); + Entry indexType = new Entry(); + indexType.a = a; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return addedIndex; + } + + public int addIndexType(Primitive p) { + int addedIndex = mIndexTypes.size(); + Entry indexType = new Entry(); + indexType.a = null; + indexType.prim = p; + mIndexTypes.addElement(indexType); + return addedIndex; + } + + static synchronized Mesh internalCreate(RenderScript rs, AllocationBuilder b) { + + int id = rs.nMeshCreate(b.mVertexTypeCount, b.mIndexTypes.size()); + Mesh newMesh = new Mesh(id, rs); + newMesh.mIndexBuffers = new Allocation[b.mIndexTypes.size()]; + newMesh.mPrimitives = new Primitive[b.mIndexTypes.size()]; + newMesh.mVertexBuffers = new Allocation[b.mVertexTypeCount]; + + for(int ct = 0; ct < b.mIndexTypes.size(); ct ++) { + Entry entry = (Entry)b.mIndexTypes.elementAt(ct); + int allocID = (entry.a == null) ? 0 : entry.a.getID(); + rs.nMeshBindIndex(id, allocID, entry.prim.mID, ct); + newMesh.mIndexBuffers[ct] = entry.a; + newMesh.mPrimitives[ct] = entry.prim; + } + + for(int ct = 0; ct < b.mVertexTypeCount; ct ++) { + Entry entry = b.mVertexTypes[ct]; + rs.nMeshBindVertex(id, entry.a.mID, ct); + newMesh.mVertexBuffers[ct] = entry.a; + } + + return newMesh; + } + + public Mesh create() { + mRS.validate(); + Mesh sm = internalCreate(mRS, this); + return sm; + } + } + + + public static class TriangleMeshBuilder { + float mVtxData[]; + int mVtxCount; + short mIndexData[]; + int mIndexCount; + RenderScript mRS; + Element mElement; + + float mNX = 0; + float mNY = 0; + float mNZ = -1; + float mS0 = 0; + float mT0 = 0; + float mR = 1; + float mG = 1; + float mB = 1; + float mA = 1; + + int mVtxSize; + int mFlags; + + public static final int COLOR = 0x0001; + public static final int NORMAL = 0x0002; + public static final int TEXTURE_0 = 0x0100; + + public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) { + mRS = rs; + mVtxCount = 0; + mIndexCount = 0; + mVtxData = new float[128]; + mIndexData = new short[128]; + mVtxSize = vtxSize; + mFlags = flags; + + 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; + } + } + + private void latch() { + if ((mFlags & COLOR) != 0) { + makeSpace(4); + mVtxData[mVtxCount++] = mR; + mVtxData[mVtxCount++] = mG; + mVtxData[mVtxCount++] = mB; + mVtxData[mVtxCount++] = mA; + } + if ((mFlags & TEXTURE_0) != 0) { + makeSpace(2); + mVtxData[mVtxCount++] = mS0; + mVtxData[mVtxCount++] = mT0; + } + if ((mFlags & NORMAL) != 0) { + makeSpace(3); + mVtxData[mVtxCount++] = mNX; + mVtxData[mVtxCount++] = mNY; + mVtxData[mVtxCount++] = mNZ; + } + } + + public void addVertex(float x, float y) { + if (mVtxSize != 2) { + throw new IllegalStateException("add mistmatch with declared components."); + } + makeSpace(2); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + latch(); + } + + public void addVertex(float x, float y, float z) { + if (mVtxSize != 3) { + throw new IllegalStateException("add mistmatch with declared components."); + } + makeSpace(3); + mVtxData[mVtxCount++] = x; + mVtxData[mVtxCount++] = y; + mVtxData[mVtxCount++] = z; + latch(); + } + + public void setTexture(float s, float t) { + if ((mFlags & TEXTURE_0) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mS0 = s; + mT0 = t; + } + + public void setNormal(float x, float y, float z) { + if ((mFlags & NORMAL) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mNX = x; + mNY = y; + mNZ = z; + } + + public void setColor(float r, float g, float b, float a) { + if ((mFlags & COLOR) == 0) { + throw new IllegalStateException("add mistmatch with declared components."); + } + mR = r; + mG = g; + mB = b; + mA = a; + } + + public void addTriangle(int idx1, int idx2, int idx3) { + if((idx1 >= mVtxCount) || (idx1 < 0) || + (idx2 >= mVtxCount) || (idx2 < 0) || + (idx3 >= mVtxCount) || (idx3 < 0)) { + throw new IllegalStateException("Index provided greater than vertex count."); + } + if ((mIndexCount + 3) >= mIndexData.length) { + short t[] = new short[mIndexData.length * 2]; + System.arraycopy(mIndexData, 0, t, 0, mIndexData.length); + mIndexData = t; + } + mIndexData[mIndexCount++] = (short)idx1; + mIndexData[mIndexCount++] = (short)idx2; + mIndexData[mIndexCount++] = (short)idx3; + } + + public Mesh create(boolean uploadToBufferObject) { + Element.Builder b = new Element.Builder(mRS); + int floatCount = mVtxSize; + b.add(Element.createVector(mRS, + Element.DataType.FLOAT_32, + mVtxSize), "position"); + if ((mFlags & COLOR) != 0) { + floatCount += 4; + b.add(Element.F32_4(mRS), "color"); + } + if ((mFlags & TEXTURE_0) != 0) { + floatCount += 2; + b.add(Element.F32_2(mRS), "texture0"); + } + if ((mFlags & NORMAL) != 0) { + floatCount += 3; + b.add(Element.F32_3(mRS), "normal"); + } + mElement = b.create(); + + Builder smb = new Builder(mRS); + smb.addVertexType(mElement, mVtxCount / floatCount); + smb.addIndexType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE); + + Mesh sm = smb.create(); + + sm.getVertexAllocation(0).data(mVtxData); + if(uploadToBufferObject) { + sm.getVertexAllocation(0).uploadToBufferObject(); + } + + sm.getIndexAllocation(0).data(mIndexData); + sm.getIndexAllocation(0).uploadToBufferObject(); + + return sm; + } + } +} + diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java index 1614ec5..b16dac1 100644 --- a/graphics/java/android/renderscript/Program.java +++ b/graphics/java/android/renderscript/Program.java @@ -91,8 +91,9 @@ public class Program extends BaseObj { mTextureCount = 0; } - public void setShader(String s) { + public BaseProgramBuilder setShader(String s) { mShader = s; + return this; } public void addInput(Element e) throws IllegalStateException { @@ -120,12 +121,13 @@ public class Program extends BaseObj { return mConstantCount++; } - public void setTextureCount(int count) throws IllegalArgumentException { + public BaseProgramBuilder setTextureCount(int count) throws IllegalArgumentException { // Should check for consistant and non-conflicting names... if(count >= MAX_CONSTANT) { throw new IllegalArgumentException("Max texture count exceeded."); } mTextureCount = count; + return this; } protected void initProgram(Program p) { diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java index 5e04f0c..04091a3 100644 --- a/graphics/java/android/renderscript/ProgramFragment.java +++ b/graphics/java/android/renderscript/ProgramFragment.java @@ -66,6 +66,7 @@ public class ProgramFragment extends Program { public static final int MAX_TEXTURE = 2; RenderScript mRS; boolean mPointSpriteEnable; + boolean mVaryingColorEnable; public enum EnvMode { REPLACE (1), @@ -106,21 +107,28 @@ public class ProgramFragment extends Program { mPointSpriteEnable = false; } - public void setTexture(EnvMode env, Format fmt, int slot) + public Builder setTexture(EnvMode env, Format fmt, int slot) throws IllegalArgumentException { if((slot < 0) || (slot >= MAX_TEXTURE)) { throw new IllegalArgumentException("MAX_TEXTURE exceeded."); } mSlots[slot] = new Slot(env, fmt); + return this; } - public void setPointSpriteTexCoordinateReplacement(boolean enable) { + public Builder setPointSpriteTexCoordinateReplacement(boolean enable) { mPointSpriteEnable = enable; + return this; + } + + public Builder setVaryingColor(boolean enable) { + mVaryingColorEnable = enable; + return this; } public ProgramFragment create() { mRS.validate(); - int[] tmp = new int[MAX_TEXTURE * 2 + 1]; + int[] tmp = new int[MAX_TEXTURE * 2 + 2]; if (mSlots[0] != null) { tmp[0] = mSlots[0].env.mID; tmp[1] = mSlots[0].format.mID; @@ -130,6 +138,7 @@ public class ProgramFragment extends Program { tmp[3] = mSlots[1].format.mID; } tmp[4] = mPointSpriteEnable ? 1 : 0; + tmp[5] = mVaryingColorEnable ? 1 : 0; int id = mRS.nProgramFragmentCreate(tmp); ProgramFragment pf = new ProgramFragment(id, mRS); pf.mTextureCount = MAX_TEXTURE; diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java index 56f9bf4..6fc9fff 100644 --- a/graphics/java/android/renderscript/ProgramRaster.java +++ b/graphics/java/android/renderscript/ProgramRaster.java @@ -26,23 +26,34 @@ import android.util.Log; * **/ public class ProgramRaster extends BaseObj { + + public enum CullMode { + BACK (0), + FRONT (1), + NONE (2); + + int mID; + CullMode(int id) { + mID = id; + } + } + boolean mPointSmooth; boolean mLineSmooth; boolean mPointSprite; - float mPointSize; float mLineWidth; - Element mIn; - Element mOut; + CullMode mCullMode; ProgramRaster(int id, RenderScript rs) { super(rs); mID = id; - mPointSize = 1.0f; mLineWidth = 1.0f; mPointSmooth = false; mLineSmooth = false; mPointSprite = false; + + mCullMode = CullMode.BACK; } public void setLineWidth(float w) { @@ -51,51 +62,43 @@ public class ProgramRaster extends BaseObj { mRS.nProgramRasterSetLineWidth(mID, w); } - public void setPointSize(float s) { + public void setCullMode(CullMode m) { mRS.validate(); - mPointSize = s; - mRS.nProgramRasterSetPointSize(mID, s); + mCullMode = m; + mRS.nProgramRasterSetCullMode(mID, m.mID); } - void internalInit() { - int inID = 0; - int outID = 0; - if (mIn != null) { - inID = mIn.mID; - } - if (mOut != null) { - outID = mOut.mID; - } - mID = mRS.nProgramRasterCreate(inID, outID, mPointSmooth, mLineSmooth, mPointSprite); - } - - public static class Builder { RenderScript mRS; - ProgramRaster mPR; + boolean mPointSprite; + boolean mPointSmooth; + boolean mLineSmooth; - public Builder(RenderScript rs, Element in, Element out) { + public Builder(RenderScript rs) { mRS = rs; - mPR = new ProgramRaster(0, rs); + mPointSmooth = false; + mLineSmooth = false; + mPointSprite = false; } - public void setPointSpriteEnable(boolean enable) { - mPR.mPointSprite = enable; + public Builder setPointSpriteEnable(boolean enable) { + mPointSprite = enable; + return this; } - public void setPointSmoothEnable(boolean enable) { - mPR.mPointSmooth = enable; + public Builder setPointSmoothEnable(boolean enable) { + mPointSmooth = enable; + return this; } - public void setLineSmoothEnable(boolean enable) { - mPR.mLineSmooth = enable; + public Builder setLineSmoothEnable(boolean enable) { + mLineSmooth = enable; + return this; } - static synchronized ProgramRaster internalCreate(RenderScript rs, Builder b) { - b.mPR.internalInit(); - ProgramRaster pr = b.mPR; - b.mPR = new ProgramRaster(0, b.mRS); + int id = rs.nProgramRasterCreate(b.mPointSmooth, b.mLineSmooth, b.mPointSprite); + ProgramRaster pr = new ProgramRaster(id, rs); return pr; } @@ -111,3 +114,4 @@ public class ProgramRaster extends BaseObj { + diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java index 69be245..a92cbb6 100644 --- a/graphics/java/android/renderscript/ProgramStore.java +++ b/graphics/java/android/renderscript/ProgramStore.java @@ -114,28 +114,33 @@ public class ProgramStore extends BaseObj { } - public void setDepthFunc(DepthFunc func) { + public Builder setDepthFunc(DepthFunc func) { mDepthFunc = func; + return this; } - public void setDepthMask(boolean enable) { + public Builder setDepthMask(boolean enable) { mDepthMask = enable; + return this; } - public void setColorMask(boolean r, boolean g, boolean b, boolean a) { + public Builder setColorMask(boolean r, boolean g, boolean b, boolean a) { mColorMaskR = r; mColorMaskG = g; mColorMaskB = b; mColorMaskA = a; + return this; } - public void setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) { + public Builder setBlendFunc(BlendSrcFunc src, BlendDstFunc dst) { mBlendSrc = src; mBlendDst = dst; + return this; } - public void setDitherEnable(boolean enable) { + public Builder setDitherEnable(boolean enable) { mDither = enable; + return this; } static synchronized ProgramStore internalCreate(RenderScript rs, Builder b) { @@ -147,17 +152,17 @@ public class ProgramStore extends BaseObj { 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, + rs.nProgramStoreBegin(inID, outID); + rs.nProgramStoreDepthFunc(b.mDepthFunc.mID); + rs.nProgramStoreDepthMask(b.mDepthMask); + rs.nProgramStoreColorMask(b.mColorMaskR, b.mColorMaskG, b.mColorMaskB, b.mColorMaskA); - rs.nProgramFragmentStoreBlendFunc(b.mBlendSrc.mID, b.mBlendDst.mID); - rs.nProgramFragmentStoreDither(b.mDither); + rs.nProgramStoreBlendFunc(b.mBlendSrc.mID, b.mBlendDst.mID); + rs.nProgramStoreDither(b.mDither); - int id = rs.nProgramFragmentStoreCreate(); + int id = rs.nProgramStoreCreate(); return new ProgramStore(id, rs); } diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java index 1b155d7..ec377e2 100644 --- a/graphics/java/android/renderscript/ProgramVertex.java +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -47,8 +47,9 @@ public class ProgramVertex extends Program { mRS = rs; } - public void setTextureMatrixEnable(boolean enable) { + public Builder setTextureMatrixEnable(boolean enable) { mTextureMatrixEnable = enable; + return this; } public ProgramVertex create() { diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index a935243..4eeb4d3 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -68,10 +68,11 @@ public class RenderScript { native void nContextSetSurface(int w, int h, Surface sur); native void nContextSetPriority(int p); native void nContextDump(int bits); + native void nContextFinish(); native void nContextBindRootScript(int script); native void nContextBindSampler(int sampler, int slot); - native void nContextBindProgramFragmentStore(int pfs); + native void nContextBindProgramStore(int pfs); native void nContextBindProgramFragment(int pf); native void nContextBindProgramVertex(int pf); native void nContextBindProgramRaster(int pr); @@ -82,6 +83,7 @@ public class RenderScript { native void nContextDeinitToClient(); native void nAssignName(int obj, byte[] name); + native String nGetName(int obj); native void nObjDestroy(int id); native void nObjDestroyOOB(int id); native int nFileOpen(byte[] name); @@ -89,12 +91,15 @@ public class RenderScript { native int nElementCreate(int type, int kind, boolean norm, int vecSize); native int nElementCreate2(int[] elements, String[] names); + native void nElementGetNativeData(int id, int[] elementData); + native void nElementGetSubElements(int id, int[] IDs, String[] names); 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 void nTypeGetNativeData(int id, int[] typeData); native int nAllocationCreateTyped(int type); native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp); @@ -116,6 +121,14 @@ public class RenderScript { native void nAllocationRead(int id, float[] d); native void nAllocationSubDataFromObject(int id, Type t, int offset, Object o); native void nAllocationSubReadFromObject(int id, Type t, int offset, Object o); + native int nAllocationGetType(int id); + + native int nFileA3DCreateFromAssetStream(int assetStream); + native int nFileA3DGetNumIndexEntries(int fileA3D); + native void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names); + native int nFileA3DGetEntryByIndex(int fileA3D, int index); + + native int nFontCreateFromFile(String fileName, int size, int dpi); native void nAdapter1DBindAllocation(int ad, int alloc); native void nAdapter1DSetConstraint(int ad, int dim, int value); @@ -134,36 +147,32 @@ public class RenderScript { 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 nScriptSetInvokable(String name, int slot); native void nScriptInvoke(int id, int slot); + native void nScriptInvokeV(int id, int slot, byte[] params); + native void nScriptSetVarI(int id, int slot, int val); + native void nScriptSetVarF(int id, int slot, float val); + native void nScriptSetVarV(int id, int slot, byte[] val); 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 nProgramStoreBegin(int in, int out); + native void nProgramStoreDepthFunc(int func); + native void nProgramStoreDepthMask(boolean enable); + native void nProgramStoreColorMask(boolean r, boolean g, boolean b, boolean a); + native void nProgramStoreBlendFunc(int src, int dst); + native void nProgramStoreDither(boolean enable); + native int nProgramStoreCreate(); - native int nProgramRasterCreate(int in, int out, boolean pointSmooth, boolean lineSmooth, boolean pointSprite); + native int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth, boolean pointSprite); native void nProgramRasterSetLineWidth(int pr, float v); - native void nProgramRasterSetPointSize(int pr, float v); + native void nProgramRasterSetCullMode(int pr, int mode); native void nProgramBindConstants(int pv, int slot, int mID); native void nProgramBindTexture(int vpf, int slot, int a); @@ -182,9 +191,13 @@ public class RenderScript { 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 int nMeshCreate(int vtxCount, int indexCount); + native void nMeshBindVertex(int id, int alloc, int slot); + native void nMeshBindIndex(int id, int alloc, int prim, int slot); + native int nMeshGetVertexBufferCount(int id); + native int nMeshGetIndexCount(int id); + native void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount); + native void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount); native void nAnimationBegin(int attribCount, int keyframeCount); native void nAnimationAdd(float time, float[] attribs); @@ -195,13 +208,25 @@ public class RenderScript { @SuppressWarnings({"FieldCanBeLocal"}) protected MessageThread mMessageThread; - Element mElement_USER_U8; - Element mElement_USER_I8; - Element mElement_USER_U16; - Element mElement_USER_I16; - Element mElement_USER_U32; - Element mElement_USER_I32; - Element mElement_USER_F32; + Element mElement_U8; + Element mElement_I8; + Element mElement_U16; + Element mElement_I16; + Element mElement_U32; + Element mElement_I32; + Element mElement_F32; + Element mElement_BOOLEAN; + + Element mElement_ELEMENT; + Element mElement_TYPE; + Element mElement_ALLOCATION; + Element mElement_SAMPLER; + Element mElement_SCRIPT; + Element mElement_MESH; + Element mElement_PROGRAM_FRAGMENT; + Element mElement_PROGRAM_VERTEX; + Element mElement_PROGRAM_RASTER; + Element mElement_PROGRAM_STORE; Element mElement_A_8; Element mElement_RGB_565; @@ -210,13 +235,17 @@ public class RenderScript { Element mElement_RGBA_4444; Element mElement_RGBA_8888; - Element mElement_INDEX_16; - Element mElement_POSITION_2; - Element mElement_POSITION_3; - Element mElement_TEXTURE_2; - Element mElement_NORMAL_3; - Element mElement_COLOR_U8_4; - Element mElement_COLOR_F32_4; + Element mElement_FLOAT_2; + Element mElement_FLOAT_3; + Element mElement_FLOAT_4; + Element mElement_UCHAR_4; + + Sampler mSampler_CLAMP_NEAREST; + Sampler mSampler_CLAMP_LINEAR; + Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR; + Sampler mSampler_WRAP_NEAREST; + Sampler mSampler_WRAP_LINEAR; + Sampler mSampler_WRAP_LINEAR_MIP_LINEAR; /////////////////////////////////////////////////////////////////////////////////// // @@ -282,7 +311,6 @@ public class RenderScript { mRS.mMessageCallback.mID = msg; mRS.mMessageCallback.run(); } - //Log.d(LOG_TAG, "MessageThread msg " + msg + " v1 " + rbuf[0] + " v2 " + rbuf[1] + " v3 " +rbuf[2]); } Log.d(LOG_TAG, "MessageThread exiting."); } @@ -307,6 +335,10 @@ public class RenderScript { nContextDump(bits); } + public void finish() { + nContextFinish(); + } + public void destroy() { validate(); nContextDeinitToClient(); @@ -335,3 +367,4 @@ public class RenderScript { } + diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java index d1df23d..e90b4fc 100644 --- a/graphics/java/android/renderscript/RenderScriptGL.java +++ b/graphics/java/android/renderscript/RenderScriptGL.java @@ -74,9 +74,9 @@ public class RenderScriptGL extends RenderScript { nContextBindRootScript(safeID(s)); } - public void contextBindProgramFragmentStore(ProgramStore p) { + public void contextBindProgramStore(ProgramStore p) { validate(); - nContextBindProgramFragmentStore(safeID(p)); + nContextBindProgramStore(safeID(p)); } public void contextBindProgramFragment(ProgramFragment p) { diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java index 40ba722..da83d04 100644 --- a/graphics/java/android/renderscript/Sampler.java +++ b/graphics/java/android/renderscript/Sampler.java @@ -51,6 +51,86 @@ public class Sampler extends BaseObj { mID = id; } + Sampler mSampler_CLAMP_NEAREST; + Sampler mSampler_CLAMP_LINEAR; + Sampler mSampler_CLAMP_LINEAR_MIP; + Sampler mSampler_WRAP_NEAREST; + Sampler mSampler_WRAP_LINEAR; + Sampler mSampler_WRAP_LINEAR_MIP; + + public static Sampler CLAMP_NEAREST(RenderScript rs) { + if(rs.mSampler_CLAMP_NEAREST == null) { + Builder b = new Builder(rs); + b.setMin(Value.NEAREST); + b.setMag(Value.NEAREST); + b.setWrapS(Value.CLAMP); + b.setWrapT(Value.CLAMP); + rs.mSampler_CLAMP_NEAREST = b.create(); + } + return rs.mSampler_CLAMP_NEAREST; + } + + public static Sampler CLAMP_LINEAR(RenderScript rs) { + if(rs.mSampler_CLAMP_LINEAR == null) { + Builder b = new Builder(rs); + b.setMin(Value.LINEAR); + b.setMag(Value.LINEAR); + b.setWrapS(Value.CLAMP); + b.setWrapT(Value.CLAMP); + rs.mSampler_CLAMP_LINEAR = b.create(); + } + return rs.mSampler_CLAMP_LINEAR; + } + + public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) { + if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) { + Builder b = new Builder(rs); + b.setMin(Value.LINEAR_MIP_LINEAR); + b.setMag(Value.LINEAR_MIP_LINEAR); + b.setWrapS(Value.CLAMP); + b.setWrapT(Value.CLAMP); + rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create(); + } + return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR; + } + + public static Sampler WRAP_NEAREST(RenderScript rs) { + if(rs.mSampler_WRAP_NEAREST == null) { + Builder b = new Builder(rs); + b.setMin(Value.NEAREST); + b.setMag(Value.NEAREST); + b.setWrapS(Value.WRAP); + b.setWrapT(Value.WRAP); + rs.mSampler_WRAP_NEAREST = b.create(); + } + return rs.mSampler_WRAP_NEAREST; + } + + public static Sampler WRAP_LINEAR(RenderScript rs) { + if(rs.mSampler_WRAP_LINEAR == null) { + Builder b = new Builder(rs); + b.setMin(Value.LINEAR); + b.setMag(Value.LINEAR); + b.setWrapS(Value.WRAP); + b.setWrapT(Value.WRAP); + rs.mSampler_WRAP_LINEAR = b.create(); + } + return rs.mSampler_WRAP_LINEAR; + } + + public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) { + if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) { + Builder b = new Builder(rs); + b.setMin(Value.LINEAR_MIP_LINEAR); + b.setMag(Value.LINEAR_MIP_LINEAR); + b.setWrapS(Value.WRAP); + b.setWrapT(Value.WRAP); + rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create(); + } + return rs.mSampler_WRAP_LINEAR_MIP_LINEAR; + } + + public static class Builder { RenderScript mRS; Value mMin; diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java index 57ccfa3..d9aec59 100644 --- a/graphics/java/android/renderscript/Script.java +++ b/graphics/java/android/renderscript/Script.java @@ -42,6 +42,19 @@ public class Script extends BaseObj { } } + protected void invoke(int slot) { + mRS.nScriptInvoke(mID, slot); + } + + protected void invoke(int slot, FieldPacker v) { + if (v != null) { + mRS.nScriptInvokeV(mID, slot, v.getData()); + } else { + mRS.nScriptInvoke(mID, slot); + } + } + + Script(int id, RenderScript rs) { super(rs); mID = id; @@ -49,22 +62,27 @@ public class Script extends BaseObj { public void bindAllocation(Allocation va, int slot) { mRS.validate(); - mRS.nScriptBindAllocation(mID, va.mID, slot); + if (va != null) { + mRS.nScriptBindAllocation(mID, va.mID, slot); + } else { + mRS.nScriptBindAllocation(mID, 0, slot); + } } - public void setClearColor(float r, float g, float b, float a) { - mRS.validate(); - mRS.nScriptSetClearColor(mID, r, g, b, a); + public void setVar(int index, float v) { + mRS.nScriptSetVarF(mID, index, v); } - public void setClearDepth(float d) { - mRS.validate(); - mRS.nScriptSetClearDepth(mID, d); + public void setVar(int index, int v) { + mRS.nScriptSetVarI(mID, index, v); } - public void setClearStencil(int stencil) { - mRS.validate(); - mRS.nScriptSetClearStencil(mID, stencil); + public void setVar(int index, boolean v) { + mRS.nScriptSetVarI(mID, index, v ? 1 : 0); + } + + public void setVar(int index, FieldPacker v) { + mRS.nScriptSetVarV(mID, index, v.getData()); } public void setTimeZone(String timeZone) { @@ -78,72 +96,54 @@ public class Script extends BaseObj { public static class Builder { RenderScript mRS; - boolean mIsRoot = false; - Type[] mTypes; - String[] mNames; - boolean[] mWritable; - int mInvokableCount = 0; - Invokable[] mInvokables; Builder(RenderScript rs) { mRS = rs; - mTypes = new Type[MAX_SLOT]; - mNames = new String[MAX_SLOT]; - mWritable = new boolean[MAX_SLOT]; - mInvokables = new Invokable[MAX_SLOT]; } + } + + + public static class FieldBase { + protected Element mElement; + protected Type mType; + protected Allocation mAllocation; - public void setType(Type t, int slot) { - mTypes[slot] = t; - mNames[slot] = null; + protected void init(RenderScript rs, int dimx) { + mAllocation = Allocation.createSized(rs, mElement, dimx); + mType = mAllocation.getType(); } - public void setType(Type t, String name, int slot) { - mTypes[slot] = t; - mNames[slot] = name; + protected FieldBase() { } - public Invokable addInvokable(String func) { - Invokable i = new Invokable(); - i.mName = func; - i.mRS = mRS; - i.mSlot = mInvokableCount; - mInvokables[mInvokableCount++] = i; - return i; + public Element getElement() { + return mElement; } - public void setType(boolean writable, int slot) { - mWritable[slot] = writable; + public Type getType() { + return mType; } - 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); - } - } - for(int ct=0; ct < mInvokableCount; ct++) { - mRS.nScriptSetInvokable(mInvokables[ct].mName, ct); - } + public Allocation getAllocation() { + return mAllocation; } - void transferObject(Script s) { - s.mIsRoot = mIsRoot; - s.mTypes = mTypes; - s.mInvokables = new Invokable[mInvokableCount]; - for(int ct=0; ct < mInvokableCount; ct++) { - s.mInvokables[ct] = mInvokables[ct]; - s.mInvokables[ct].mScript = s; - } - s.mInvokables = null; + //@Override + public void updateAllocation() { } - public void setRoot(boolean r) { - mIsRoot = r; + + // + /* + public class ScriptField_UserField + extends android.renderscript.Script.FieldBase { + + protected + } - } + */ + } } diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java index bb99e23..5959be4 100644 --- a/graphics/java/android/renderscript/ScriptC.java +++ b/graphics/java/android/renderscript/ScriptC.java @@ -37,11 +37,49 @@ public class ScriptC extends Script { super(id, rs); } + protected ScriptC(RenderScript rs, Resources resources, int resourceID, boolean isRoot) { + super(0, rs); + mID = internalCreate(rs, resources, resourceID); + } + + + private static synchronized int internalCreate(RenderScript rs, Resources resources, int resourceID) { + byte[] pgm; + int pgmLength; + InputStream is = resources.openRawResource(resourceID); + try { + try { + pgm = new byte[1024]; + pgmLength = 0; + while(true) { + int bytesLeft = pgm.length - pgmLength; + if (bytesLeft == 0) { + byte[] buf2 = new byte[pgm.length * 2]; + System.arraycopy(pgm, 0, buf2, 0, pgm.length); + pgm = buf2; + bytesLeft = pgm.length - pgmLength; + } + int bytesRead = is.read(pgm, pgmLength, bytesLeft); + if (bytesRead <= 0) { + break; + } + pgmLength += bytesRead; + } + } finally { + is.close(); + } + } catch(IOException e) { + throw new Resources.NotFoundException(); + } + + rs.nScriptCBegin(); + rs.nScriptCSetScript(pgm, 0, pgmLength); + return rs.nScriptCCreate(); + } + 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); @@ -92,66 +130,20 @@ public class ScriptC extends Script { 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()); - } + android.util.Log.e("rs", "len = " + b.mProgramLength); 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 void addDefine(String name, int value) {} + public void addDefine(String name, float value) {} + public void addDefines(Class cl) {} + public void addDefines(Object o) {} + void addDefines(Field[] fields, int mask, Object o) {} public ScriptC create() { return internalCreate(this); diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java new file mode 100644 index 0000000..426801f --- /dev/null +++ b/graphics/java/android/renderscript/Short2.java @@ -0,0 +1,37 @@ +/* + * 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 Short2 { + public Short2() { + } + + public short x; + public short y; +} + + + + diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java new file mode 100644 index 0000000..7b9c305 --- /dev/null +++ b/graphics/java/android/renderscript/Short3.java @@ -0,0 +1,38 @@ +/* + * 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 Short3 { + public Short3() { + } + + public short x; + public short y; + public short z; +} + + + + diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java new file mode 100644 index 0000000..9a474e2 --- /dev/null +++ b/graphics/java/android/renderscript/Short4.java @@ -0,0 +1,38 @@ +/* + * 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 Short4 { + public Short4() { + } + + public short x; + public short y; + public short z; + public short w; +} + + + diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java deleted file mode 100644 index 4a217a9..0000000 --- a/graphics/java/android/renderscript/SimpleMesh.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * 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.validate(); - mRS.nSimpleMeshBindVertex(mID, a.mID, slot); - } - - public void bindIndexAllocation(Allocation a) { - mRS.validate(); - mRS.nSimpleMeshBindIndex(mID, a.mID); - } - - public Allocation createVertexAllocation(int slot) { - mRS.validate(); - return Allocation.createTyped(mRS, mVertexTypes[slot]); - } - - public Allocation createIndexAllocation() { - mRS.validate(); - 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() { - mRS.validate(); - 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; - short mIndexData[]; - int mIndexCount; - RenderScript mRS; - Element mElement; - - float mNX = 0; - float mNY = 0; - float mNZ = -1; - float mS0 = 0; - float mT0 = 0; - float mR = 1; - float mG = 1; - float mB = 1; - float mA = 1; - - int mVtxSize; - int mFlags; - - public static final int COLOR = 0x0001; - public static final int NORMAL = 0x0002; - public static final int TEXTURE_0 = 0x0100; - - public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) { - mRS = rs; - mVtxCount = 0; - mIndexCount = 0; - mVtxData = new float[128]; - mIndexData = new short[128]; - mVtxSize = vtxSize; - mFlags = flags; - - 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; - } - } - - private void latch() { - if ((mFlags & COLOR) != 0) { - makeSpace(4); - mVtxData[mVtxCount++] = mR; - mVtxData[mVtxCount++] = mG; - mVtxData[mVtxCount++] = mB; - mVtxData[mVtxCount++] = mA; - } - if ((mFlags & TEXTURE_0) != 0) { - makeSpace(2); - mVtxData[mVtxCount++] = mS0; - mVtxData[mVtxCount++] = mT0; - } - if ((mFlags & NORMAL) != 0) { - makeSpace(3); - mVtxData[mVtxCount++] = mNX; - mVtxData[mVtxCount++] = mNY; - mVtxData[mVtxCount++] = mNZ; - } - } - - public void addVertex(float x, float y) { - if (mVtxSize != 2) { - throw new IllegalStateException("add mistmatch with declared components."); - } - makeSpace(2); - mVtxData[mVtxCount++] = x; - mVtxData[mVtxCount++] = y; - latch(); - } - - public void addVertex(float x, float y, float z) { - if (mVtxSize != 3) { - throw new IllegalStateException("add mistmatch with declared components."); - } - makeSpace(3); - mVtxData[mVtxCount++] = x; - mVtxData[mVtxCount++] = y; - mVtxData[mVtxCount++] = z; - latch(); - } - - public void setTexture(float s, float t) { - if ((mFlags & TEXTURE_0) == 0) { - throw new IllegalStateException("add mistmatch with declared components."); - } - mS0 = s; - mT0 = t; - } - - public void setNormal(float x, float y, float z) { - if ((mFlags & NORMAL) == 0) { - throw new IllegalStateException("add mistmatch with declared components."); - } - mNX = x; - mNY = y; - mNZ = z; - } - - public void setColor(float r, float g, float b, float a) { - if ((mFlags & COLOR) == 0) { - throw new IllegalStateException("add mistmatch with declared components."); - } - mR = r; - mG = g; - mB = b; - mA = a; - } - - public void addTriangle(int idx1, int idx2, int idx3) { - if((idx1 >= mVtxCount) || (idx1 < 0) || - (idx2 >= mVtxCount) || (idx2 < 0) || - (idx3 >= mVtxCount) || (idx3 < 0)) { - throw new IllegalStateException("Index provided greater than vertex count."); - } - if ((mIndexCount + 3) >= mIndexData.length) { - short t[] = new short[mIndexData.length * 2]; - System.arraycopy(mIndexData, 0, t, 0, mIndexData.length); - mIndexData = t; - } - mIndexData[mIndexCount++] = (short)idx1; - mIndexData[mIndexCount++] = (short)idx2; - mIndexData[mIndexCount++] = (short)idx3; - } - - public SimpleMesh create() { - Element.Builder b = new Element.Builder(mRS); - int floatCount = mVtxSize; - b.add(Element.createAttrib(mRS, - Element.DataType.FLOAT_32, - Element.DataKind.POSITION, - mVtxSize), "position"); - if ((mFlags & COLOR) != 0) { - floatCount += 4; - b.add(Element.createAttrib(mRS, - Element.DataType.FLOAT_32, - Element.DataKind.COLOR, - 4), "color"); - } - if ((mFlags & TEXTURE_0) != 0) { - floatCount += 2; - b.add(Element.createAttrib(mRS, - Element.DataType.FLOAT_32, - Element.DataKind.TEXTURE, - 2), "texture"); - } - if ((mFlags & NORMAL) != 0) { - floatCount += 3; - b.add(Element.createAttrib(mRS, - Element.DataType.FLOAT_32, - Element.DataKind.NORMAL, - 3), "normal"); - } - mElement = b.create(); - - Builder smb = new Builder(mRS); - smb.addVertexType(mElement, mVtxCount / floatCount); - smb.setIndexType(Element.createIndex(mRS), 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(); - - indexAlloc.data(mIndexData); - indexAlloc.uploadToBufferObject(); - - return sm; - } - } -} - diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java index 62d3867..8e45f2b 100644 --- a/graphics/java/android/renderscript/Type.java +++ b/graphics/java/android/renderscript/Type.java @@ -16,7 +16,9 @@ package android.renderscript; + import java.lang.reflect.Field; +import android.util.Log; /** * @hide @@ -108,48 +110,30 @@ public class Type extends BaseObj { 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_32.mID; - arBits[ct] = 32; - } else if(fc == short.class) { - arTypes[ct] = Element.DataType.SIGNED_16.mID; - arBits[ct] = 16; - } else if(fc == byte.class) { - arTypes[ct] = Element.DataType.SIGNED_8.mID; - arBits[ct] = 8; - } else if(fc == float.class) { - arTypes[ct] = Element.DataType.FLOAT_32.mID; - arBits[ct] = 32; - } else { - throw new IllegalArgumentException("Unkown field type"); - } - } - rs.nTypeSetupFields(t, arTypes, arBits, fields); + @Override + void updateFromNative() { + // We have 6 integer to obtain mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; + int[] dataBuffer = new int[6]; + mRS.nTypeGetNativeData(mID, dataBuffer); + + mDimX = dataBuffer[0]; + mDimY = dataBuffer[1]; + mDimZ = dataBuffer[2]; + mDimLOD = dataBuffer[3] == 1 ? true : false; + mDimFaces = dataBuffer[4] == 1 ? true : false; + + int elementID = dataBuffer[5]; + if(elementID != 0) { + mElement = new Element(mRS, elementID); + mElement.updateFromNative(); } - t.mJavaClass = c; - return t; + calcElementCount(); } public static Type createFromClass(RenderScript rs, Class c, int size, String scriptName) { - Type t = createFromClass(rs, c, size); - t.setName(scriptName); - return t; + android.util.Log.e("RenderScript", "Calling depricated createFromClass"); + return null; } diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index 45cc72e..8968dfb 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -85,6 +85,14 @@ static void nInitElements(JNIEnv *_env, jobject _this, jint a8, jint rgba4444, j // --------------------------------------------------------------------------- static void +nContextFinish(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextFinish, con(%p)", con); + rsContextFinish(con); +} + +static void nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); @@ -96,6 +104,17 @@ nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str) _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT); } +static jstring +nGetName(JNIEnv *_env, jobject _this, jint obj) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nGetName, con(%p), obj(%p)", con, (void *)obj); + + const char *name = NULL; + rsGetName(con, (void *)obj, &name); + return _env->NewStringUTF(name); +} + static void nObjDestroy(JNIEnv *_env, jobject _this, jint obj) { @@ -289,6 +308,46 @@ nElementCreate2(JNIEnv *_env, jobject _this, jintArray _ids, jobjectArray _names return (jint)id; } +static void +nElementGetNativeData(JNIEnv *_env, jobject _this, jint id, jintArray _elementData) +{ + int dataSize = _env->GetArrayLength(_elementData); + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementGetNativeData, con(%p)", con); + + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + assert(dataSize == 5); + + uint32_t elementData[5]; + rsElementGetNativeData(con, (RsElement)id, elementData, dataSize); + + for(jint i = 0; i < dataSize; i ++) { + _env->SetIntArrayRegion(_elementData, i, 1, (const jint*)&elementData[i]); + } +} + + +static void +nElementGetSubElements(JNIEnv *_env, jobject _this, jint id, jintArray _IDs, jobjectArray _names) +{ + int dataSize = _env->GetArrayLength(_IDs); + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nElementGetSubElements, con(%p)", con); + + uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t)); + const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *)); + + rsElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize); + + for(jint i = 0; i < dataSize; i ++) { + _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i])); + _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]); + } + + free(ids); + free(names); +} + // ----------------------------------- static void @@ -315,6 +374,26 @@ nTypeCreate(JNIEnv *_env, jobject _this) return (jint)rsTypeCreate(con); } +static void +nTypeGetNativeData(JNIEnv *_env, jobject _this, jint id, jintArray _typeData) +{ + // We are packing 6 items: mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; into typeData + int elementCount = _env->GetArrayLength(_typeData); + + assert(elementCount == 6); + + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nTypeCreate, con(%p)", con); + + uint32_t typeData[6]; + rsTypeGetNativeData(con, (RsType)id, typeData, 6); + + for(jint i = 0; i < elementCount; i ++) { + _env->SetIntArrayRegion(_typeData, i, 1, (const jint*)&typeData[i]); + } +} + static void * SF_LoadInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer) { ((int32_t *)buffer)[0] = _env->GetIntField(_obj, _field); @@ -700,6 +779,78 @@ nAllocationSubReadFromObject(JNIEnv *_env, jobject _this, jint alloc, jobject _t free(bufAlloc); } +static jint +nAllocationGetType(JNIEnv *_env, jobject _this, jint a) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAllocationGetType, con(%p), a(%p)", con, (RsAllocation)a); + return (jint) rsAllocationGetType(con, (RsAllocation)a); +} + +// ----------------------------------- + +static int +nFileA3DCreateFromAssetStream(JNIEnv *_env, jobject _this, jint native_asset) +{ + LOGV("______nFileA3D %u", (uint32_t) native_asset); + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + + Asset* asset = reinterpret_cast<Asset*>(native_asset); + + jint id = (jint)rsFileA3DCreateFromAssetStream(con, asset->getBuffer(false), asset->getLength()); + return id; +} + +static int +nFileA3DGetNumIndexEntries(JNIEnv *_env, jobject _this, jint fileA3D) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + + int32_t numEntries = 0; + rsFileA3DGetNumIndexEntries(con, &numEntries, (RsFile)fileA3D); + return numEntries; +} + +static void +nFileA3DGetIndexEntries(JNIEnv *_env, jobject _this, jint fileA3D, jint numEntries, jintArray _ids, jobjectArray _entries) +{ + LOGV("______nFileA3D %u", (uint32_t) fileA3D); + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + + RsFileIndexEntry *fileEntries = (RsFileIndexEntry*)malloc((uint32_t)numEntries * sizeof(RsFileIndexEntry)); + + rsFileA3DGetIndexEntries(con, fileEntries, (uint32_t)numEntries, (RsFile)fileA3D); + + for(jint i = 0; i < numEntries; i ++) { + _env->SetObjectArrayElement(_entries, i, _env->NewStringUTF(fileEntries[i].objectName)); + _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&fileEntries[i].classID); + } + + free(fileEntries); +} + +static int +nFileA3DGetEntryByIndex(JNIEnv *_env, jobject _this, jint fileA3D, jint index) +{ + LOGV("______nFileA3D %u", (uint32_t) fileA3D); + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + + jint id = (jint)rsFileA3DGetEntryByIndex(con, (uint32_t)index, (RsFile)fileA3D); + return id; +} + +// ----------------------------------- + +static int +nFontCreateFromFile(JNIEnv *_env, jobject _this, jstring fileName, jint fontSize, jint dpi) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + const char* fileNameUTF = _env->GetStringUTFChars(fileName, NULL); + + jint id = (jint)rsFontCreateFromFile(con, fileNameUTF, fontSize, dpi); + return id; +} + // ----------------------------------- @@ -854,29 +1005,33 @@ nScriptBindAllocation(JNIEnv *_env, jobject _this, jint script, jint alloc, jint } static void -nScriptSetClearColor(JNIEnv *_env, jobject _this, jint script, jfloat r, jfloat g, jfloat b, jfloat a) +nScriptSetVarI(JNIEnv *_env, jobject _this, jint script, jint slot, jint val) { 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); + LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i), b(%f), a(%f)", con, (void *)script, slot, val); + rsScriptSetVarI(con, (RsScript)script, slot, val); } static void -nScriptSetClearDepth(JNIEnv *_env, jobject _this, jint script, jfloat d) +nScriptSetVarF(JNIEnv *_env, jobject _this, jint script, jint slot, float val) { 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); + LOG_API("nScriptSetVarI, con(%p), s(%p), slot(%i), val(%i), b(%f), a(%f)", con, (void *)script, slot, val); + rsScriptSetVarF(con, (RsScript)script, slot, val); } static void -nScriptSetClearStencil(JNIEnv *_env, jobject _this, jint script, jint stencil) +nScriptSetVarV(JNIEnv *_env, jobject _this, jint script, jint slot, jbyteArray data) { 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); + LOG_API("nScriptSetVarV, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsScriptSetVarV(con, (RsScript)script, slot, ptr, len); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); } + static void nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone) { @@ -895,36 +1050,6 @@ nScriptSetTimeZone(JNIEnv *_env, jobject _this, jint script, jbyteArray timeZone } 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 -nScriptSetInvoke(JNIEnv *_env, jobject _this, jstring _str, jint slot) -{ - RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nScriptSetInvoke, con(%p)", con); - const char* n = NULL; - if (_str) { - n = _env->GetStringUTFChars(_str, NULL); - } - rsScriptSetInvoke(con, n, slot); - if (n) { - _env->ReleaseStringUTFChars(_str, n); - } -} - -static void nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); @@ -933,13 +1058,17 @@ nScriptInvoke(JNIEnv *_env, jobject _this, jint obj, jint slot) } static void -nScriptSetRoot(JNIEnv *_env, jobject _this, jboolean isRoot) +nScriptInvokeV(JNIEnv *_env, jobject _this, jint script, jint slot, jbyteArray data) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nScriptCSetRoot, con(%p), isRoot(%i)", con, isRoot); - rsScriptSetRoot(con, isRoot); + LOG_API("nScriptInvokeV, con(%p), s(%p), slot(%i)", con, (void *)script, slot); + jint len = _env->GetArrayLength(data); + jbyte *ptr = _env->GetByteArrayElements(data, NULL); + rsScriptInvokeV(con, (RsScript)script, slot, ptr, len); + _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT); } + // ----------------------------------- static void @@ -1002,83 +1131,63 @@ nScriptCCreate(JNIEnv *_env, jobject _this) 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) +nProgramStoreBegin(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); + LOG_API("nProgramStoreBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out); + rsProgramStoreBegin(con, (RsElement)in, (RsElement)out); } static void -nProgramFragmentStoreDepthFunc(JNIEnv *_env, jobject _this, jint func) +nProgramStoreDepthFunc(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); + LOG_API("nProgramStoreDepthFunc, con(%p), func(%i)", con, func); + rsProgramStoreDepthFunc(con, (RsDepthFunc)func); } static void -nProgramFragmentStoreDepthMask(JNIEnv *_env, jobject _this, jboolean enable) +nProgramStoreDepthMask(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); + LOG_API("nProgramStoreDepthMask, con(%p), enable(%i)", con, enable); + rsProgramStoreDepthMask(con, enable); } static void -nProgramFragmentStoreColorMask(JNIEnv *_env, jobject _this, jboolean r, jboolean g, jboolean b, jboolean a) +nProgramStoreColorMask(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); + LOG_API("nProgramStoreColorMask, con(%p), r(%i), g(%i), b(%i), a(%i)", con, r, g, b, a); + rsProgramStoreColorMask(con, r, g, b, a); } static void -nProgramFragmentStoreBlendFunc(JNIEnv *_env, jobject _this, int src, int dst) +nProgramStoreBlendFunc(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); + LOG_API("nProgramStoreBlendFunc, con(%p), src(%i), dst(%i)", con, src, dst); + rsProgramStoreBlendFunc(con, (RsBlendSrcFunc)src, (RsBlendDstFunc)dst); } static void -nProgramFragmentStoreDither(JNIEnv *_env, jobject _this, jboolean enable) +nProgramStoreDither(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); + LOG_API("nProgramStoreDither, con(%p), enable(%i)", con, enable); + rsProgramStoreDither(con, enable); } static jint -nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this) +nProgramStoreCreate(JNIEnv *_env, jobject _this) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramFragmentStoreCreate, con(%p)", con); + LOG_API("nProgramStoreCreate, con(%p)", con); - return (jint)rsProgramFragmentStoreCreate(con); + return (jint)rsProgramStoreCreate(con); } // --------------------------------------------------------------------------- @@ -1171,29 +1280,28 @@ nProgramVertexCreate2(JNIEnv *_env, jobject _this, jstring shader, jintArray par // --------------------------------------------------------------------------- static jint -nProgramRasterCreate(JNIEnv *_env, jobject _this, jint in, jint out, - jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite) +nProgramRasterCreate(JNIEnv *_env, jobject _this, jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramRasterCreate, con(%p), in(%p), out(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)", - con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite); - return (jint)rsProgramRasterCreate(con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite); + LOG_API("nProgramRasterCreate, con(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)", + con, pointSmooth, lineSmooth, pointSprite); + return (jint)rsProgramRasterCreate(con, pointSmooth, lineSmooth, pointSprite); } static void -nProgramRasterSetPointSize(JNIEnv *_env, jobject _this, jint vpr, jfloat v) +nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, jint vpr, jfloat v) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramRasterSetPointSize, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v); - rsProgramRasterSetPointSize(con, (RsProgramFragment)vpr, v); + LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v); + rsProgramRasterSetLineWidth(con, (RsProgramRaster)vpr, v); } static void -nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, jint vpr, jfloat v) +nProgramRasterSetCullMode(JNIEnv *_env, jobject _this, jint vpr, jint v) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); - LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v); - rsProgramRasterSetLineWidth(con, (RsProgramFragment)vpr, v); + LOG_API("nProgramRasterSetCullMode, con(%p), vpf(%p), value(%i)", con, (RsProgramRaster)vpr, v); + rsProgramRasterSetCullMode(con, (RsProgramRaster)vpr, (RsCullMode)v); } @@ -1208,11 +1316,11 @@ nContextBindRootScript(JNIEnv *_env, jobject _this, jint script) } static void -nContextBindProgramFragmentStore(JNIEnv *_env, jobject _this, jint pfs) +nContextBindProgramStore(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); + LOG_API("nContextBindProgramStore, con(%p), pfs(%p)", con, (RsProgramStore)pfs); + rsContextBindProgramStore(con, (RsProgramStore)pfs); } static void @@ -1319,32 +1427,84 @@ nLightSetPosition(JNIEnv *_env, jobject _this, jint light, float x, float y, flo // --------------------------------------------------------------------------- static jint -nSimpleMeshCreate(JNIEnv *_env, jobject _this, jint batchID, jint indexID, jintArray vtxIDs, jint primID) +nMeshCreate(JNIEnv *_env, jobject _this, jint vtxCount, jint idxCount) { 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*/); + LOG_API("nMeshCreate, con(%p), vtxCount(%i), idxCount(%i)", con, vtxCount, idxCount); + int id = (int)rsMeshCreate(con, vtxCount, idxCount); return id; } static void -nSimpleMeshBindVertex(JNIEnv *_env, jobject _this, jint s, jint alloc, jint slot) +nMeshBindVertex(JNIEnv *_env, jobject _this, jint mesh, 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); + LOG_API("nMeshBindVertex, con(%p), Mesh(%p), Alloc(%p), slot(%i)", con, (RsMesh)mesh, (RsAllocation)alloc, slot); + rsMeshBindVertex(con, (RsMesh)mesh, (RsAllocation)alloc, slot); } static void -nSimpleMeshBindIndex(JNIEnv *_env, jobject _this, jint s, jint alloc) +nMeshBindIndex(JNIEnv *_env, jobject _this, jint mesh, jint alloc, jint primID, jint slot) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nMeshBindIndex, con(%p), Mesh(%p), Alloc(%p)", con, (RsMesh)mesh, (RsAllocation)alloc); + rsMeshBindIndex(con, (RsMesh)mesh, (RsAllocation)alloc, primID, slot); +} + +static jint +nMeshGetVertexBufferCount(JNIEnv *_env, jobject _this, jint mesh) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nMeshGetVertexBufferCount, con(%p), Mesh(%p)", con, (RsMesh)mesh); + jint vtxCount = 0; + rsMeshGetVertexBufferCount(con, (RsMesh)mesh, &vtxCount); + return vtxCount; +} + +static jint +nMeshGetIndexCount(JNIEnv *_env, jobject _this, jint mesh) { 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); + LOG_API("nMeshGetIndexCount, con(%p), Mesh(%p)", con, (RsMesh)mesh); + jint idxCount = 0; + rsMeshGetIndexCount(con, (RsMesh)mesh, &idxCount); + return idxCount; +} + +static void +nMeshGetVertices(JNIEnv *_env, jobject _this, jint mesh, jintArray _ids, int numVtxIDs) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh); + + RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numVtxIDs * sizeof(RsAllocation)); + rsMeshGetVertices(con, (RsMesh)mesh, allocs, (uint32_t)numVtxIDs); + + for(jint i = 0; i < numVtxIDs; i ++) { + _env->SetIntArrayRegion(_ids, i, 1, (const jint*)&allocs[i]); + } + + free(allocs); +} + +static void +nMeshGetIndices(JNIEnv *_env, jobject _this, jint mesh, jintArray _idxIds, jintArray _primitives, int numIndices) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nMeshGetVertices, con(%p), Mesh(%p)", con, (RsMesh)mesh); + + RsAllocation *allocs = (RsAllocation*)malloc((uint32_t)numIndices * sizeof(RsAllocation)); + uint32_t *prims= (uint32_t*)malloc((uint32_t)numIndices * sizeof(uint32_t)); + + rsMeshGetIndices(con, (RsMesh)mesh, allocs, prims, (uint32_t)numIndices); + + for(jint i = 0; i < numIndices; i ++) { + _env->SetIntArrayRegion(_idxIds, i, 1, (const jint*)&allocs[i]); + _env->SetIntArrayRegion(_primitives, i, 1, (const jint*)&prims[i]); + } + + free(allocs); + free(prims); } // --------------------------------------------------------------------------- @@ -1361,6 +1521,7 @@ static JNINativeMethod methods[] = { {"nDeviceSetConfig", "(III)V", (void*)nDeviceSetConfig }, {"nContextCreate", "(II)I", (void*)nContextCreate }, {"nContextCreateGL", "(IIZ)I", (void*)nContextCreateGL }, +{"nContextFinish", "()V", (void*)nContextFinish }, {"nContextSetPriority", "(I)V", (void*)nContextSetPriority }, {"nContextSetSurface", "(IILandroid/view/Surface;)V", (void*)nContextSetSurface }, {"nContextDestroy", "(I)V", (void*)nContextDestroy }, @@ -1368,6 +1529,7 @@ static JNINativeMethod methods[] = { {"nContextPause", "()V", (void*)nContextPause }, {"nContextResume", "()V", (void*)nContextResume }, {"nAssignName", "(I[B)V", (void*)nAssignName }, +{"nGetName", "(I)Ljava/lang/String;", (void*)nGetName }, {"nObjDestroy", "(I)V", (void*)nObjDestroy }, {"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB }, {"nContextGetMessage", "([IZ)I", (void*)nContextGetMessage }, @@ -1375,15 +1537,24 @@ static JNINativeMethod methods[] = { {"nContextDeinitToClient", "()V", (void*)nContextDeinitToClient }, {"nFileOpen", "([B)I", (void*)nFileOpen }, +{"nFileA3DCreateFromAssetStream", "(I)I", (void*)nFileA3DCreateFromAssetStream }, +{"nFileA3DGetNumIndexEntries", "(I)I", (void*)nFileA3DGetNumIndexEntries }, +{"nFileA3DGetIndexEntries", "(II[I[Ljava/lang/String;)V", (void*)nFileA3DGetIndexEntries }, +{"nFileA3DGetEntryByIndex", "(II)I", (void*)nFileA3DGetEntryByIndex }, + +{"nFontCreateFromFile", "(Ljava/lang/String;II)I", (void*)nFontCreateFromFile }, {"nElementCreate", "(IIZI)I", (void*)nElementCreate }, {"nElementCreate2", "([I[Ljava/lang/String;)I", (void*)nElementCreate2 }, +{"nElementGetNativeData", "(I[I)V", (void*)nElementGetNativeData }, +{"nElementGetSubElements", "(I[I[Ljava/lang/String;)V", (void*)nElementGetSubElements }, {"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 }, +{"nTypeGetNativeData", "(I[I)V", (void*)nTypeGetNativeData }, {"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped }, {"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap }, @@ -1402,6 +1573,7 @@ static JNINativeMethod methods[] = { {"nAllocationRead", "(I[F)V", (void*)nAllocationRead_f }, {"nAllocationSubDataFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubDataFromObject }, {"nAllocationSubReadFromObject", "(ILandroid/renderscript/Type;ILjava/lang/Object;)V", (void*)nAllocationSubReadFromObject }, +{"nAllocationGetType", "(I)I", (void*)nAllocationGetType}, {"nAdapter1DBindAllocation", "(II)V", (void*)nAdapter1DBindAllocation }, {"nAdapter1DSetConstraint", "(III)V", (void*)nAdapter1DSetConstraint }, @@ -1420,28 +1592,24 @@ static JNINativeMethod methods[] = { {"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 }, -{"nScriptSetInvokable", "(Ljava/lang/String;I)V", (void*)nScriptSetInvoke }, {"nScriptInvoke", "(II)V", (void*)nScriptInvoke }, +{"nScriptInvokeV", "(II[B)V", (void*)nScriptInvokeV }, +{"nScriptSetVarI", "(III)V", (void*)nScriptSetVarI }, +{"nScriptSetVarF", "(IIF)V", (void*)nScriptSetVarF }, +{"nScriptSetVarV", "(II[B)V", (void*)nScriptSetVarV }, {"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 }, +{"nProgramStoreBegin", "(II)V", (void*)nProgramStoreBegin }, +{"nProgramStoreDepthFunc", "(I)V", (void*)nProgramStoreDepthFunc }, +{"nProgramStoreDepthMask", "(Z)V", (void*)nProgramStoreDepthMask }, +{"nProgramStoreColorMask", "(ZZZZ)V", (void*)nProgramStoreColorMask }, +{"nProgramStoreBlendFunc", "(II)V", (void*)nProgramStoreBlendFunc }, +{"nProgramStoreDither", "(Z)V", (void*)nProgramStoreDither }, +{"nProgramStoreCreate", "()I", (void*)nProgramStoreCreate }, {"nProgramBindConstants", "(III)V", (void*)nProgramBindConstants }, {"nProgramBindTexture", "(III)V", (void*)nProgramBindTexture }, @@ -1450,9 +1618,9 @@ static JNINativeMethod methods[] = { {"nProgramFragmentCreate", "([I)I", (void*)nProgramFragmentCreate }, {"nProgramFragmentCreate2", "(Ljava/lang/String;[I)I", (void*)nProgramFragmentCreate2 }, -{"nProgramRasterCreate", "(IIZZZ)I", (void*)nProgramRasterCreate }, -{"nProgramRasterSetPointSize", "(IF)V", (void*)nProgramRasterSetPointSize }, +{"nProgramRasterCreate", "(ZZZ)I", (void*)nProgramRasterCreate }, {"nProgramRasterSetLineWidth", "(IF)V", (void*)nProgramRasterSetLineWidth }, +{"nProgramRasterSetCullMode", "(II)V", (void*)nProgramRasterSetCullMode }, {"nProgramVertexCreate", "(Z)I", (void*)nProgramVertexCreate }, {"nProgramVertexCreate2", "(Ljava/lang/String;[I)I", (void*)nProgramVertexCreate2 }, @@ -1465,7 +1633,7 @@ static JNINativeMethod methods[] = { {"nLightSetPosition", "(IFFF)V", (void*)nLightSetPosition }, {"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript }, -{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore }, +{"nContextBindProgramStore", "(I)V", (void*)nContextBindProgramStore }, {"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment }, {"nContextBindProgramVertex", "(I)V", (void*)nContextBindProgramVertex }, {"nContextBindProgramRaster", "(I)V", (void*)nContextBindProgramRaster }, @@ -1474,9 +1642,14 @@ static JNINativeMethod methods[] = { {"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 }, +{"nMeshCreate", "(II)I", (void*)nMeshCreate }, +{"nMeshBindVertex", "(III)V", (void*)nMeshBindVertex }, +{"nMeshBindIndex", "(IIII)V", (void*)nMeshBindIndex }, + +{"nMeshGetVertexBufferCount", "(I)I", (void*)nMeshGetVertexBufferCount }, +{"nMeshGetIndexCount", "(I)I", (void*)nMeshGetIndexCount }, +{"nMeshGetVertices", "(I[II)V", (void*)nMeshGetVertices }, +{"nMeshGetIndices", "(I[I[II)V", (void*)nMeshGetIndices }, }; @@ -1510,3 +1683,4 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) bail: return result; } + |