summaryrefslogtreecommitdiffstats
path: root/graphics/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java/android')
-rw-r--r--graphics/java/android/graphics/Bitmap.java110
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java29
-rw-r--r--graphics/java/android/graphics/BitmapRegionDecoder.java263
-rw-r--r--graphics/java/android/graphics/BitmapShader.java25
-rw-r--r--graphics/java/android/graphics/Canvas.java339
-rw-r--r--graphics/java/android/graphics/ColorFilter.java16
-rw-r--r--graphics/java/android/graphics/ColorMatrixColorFilter.java6
-rw-r--r--graphics/java/android/graphics/ComposeShader.java41
-rw-r--r--graphics/java/android/graphics/LightingColorFilter.java2
-rw-r--r--graphics/java/android/graphics/LinearGradient.java19
-rw-r--r--graphics/java/android/graphics/Matrix.java16
-rw-r--r--graphics/java/android/graphics/NinePatch.java47
-rw-r--r--graphics/java/android/graphics/Paint.java514
-rw-r--r--graphics/java/android/graphics/Path.java64
-rw-r--r--graphics/java/android/graphics/PorterDuff.java11
-rw-r--r--graphics/java/android/graphics/PorterDuffColorFilter.java9
-rw-r--r--graphics/java/android/graphics/PorterDuffXfermode.java6
-rw-r--r--graphics/java/android/graphics/RadialGradient.java13
-rw-r--r--graphics/java/android/graphics/Region.java22
-rw-r--r--graphics/java/android/graphics/Shader.java29
-rw-r--r--graphics/java/android/graphics/SweepGradient.java13
-rw-r--r--graphics/java/android/graphics/TemporaryBuffer.java16
-rw-r--r--graphics/java/android/graphics/Xfermode.java6
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java40
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java39
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java74
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java221
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java51
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java36
-rw-r--r--graphics/java/android/graphics/drawable/MipmapDrawable.java312
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java28
-rw-r--r--graphics/java/android/graphics/drawable/PaintDrawable.java1
-rw-r--r--graphics/java/android/graphics/drawable/RotateDrawable.java2
-rw-r--r--graphics/java/android/graphics/drawable/ScaleDrawable.java10
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java8
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java13
-rw-r--r--graphics/java/android/graphics/drawable/shapes/RoundRectShape.java15
-rw-r--r--graphics/java/android/graphics/utils/BoundaryPatch.java173
-rw-r--r--graphics/java/android/renderscript/Allocation.java339
-rw-r--r--graphics/java/android/renderscript/BaseObj.java84
-rw-r--r--graphics/java/android/renderscript/Byte2.java (renamed from graphics/java/android/renderscript/Vector2f.java)8
-rw-r--r--graphics/java/android/renderscript/Byte3.java (renamed from graphics/java/android/renderscript/Vector3f.java)10
-rw-r--r--graphics/java/android/renderscript/Byte4.java (renamed from graphics/java/android/renderscript/Vector4f.java)12
-rw-r--r--graphics/java/android/renderscript/Element.java588
-rw-r--r--graphics/java/android/renderscript/FieldPacker.java179
-rw-r--r--graphics/java/android/renderscript/FileA3D.java208
-rw-r--r--graphics/java/android/renderscript/Float2.java42
-rw-r--r--graphics/java/android/renderscript/Float3.java43
-rw-r--r--graphics/java/android/renderscript/Float4.java45
-rw-r--r--graphics/java/android/renderscript/Font.java165
-rw-r--r--graphics/java/android/renderscript/Int2.java37
-rw-r--r--graphics/java/android/renderscript/Int3.java38
-rw-r--r--graphics/java/android/renderscript/Int4.java38
-rw-r--r--graphics/java/android/renderscript/Light.java76
-rw-r--r--graphics/java/android/renderscript/Long2.java37
-rw-r--r--graphics/java/android/renderscript/Long3.java38
-rw-r--r--graphics/java/android/renderscript/Long4.java38
-rw-r--r--graphics/java/android/renderscript/Matrix2f.java51
-rw-r--r--graphics/java/android/renderscript/Matrix3f.java118
-rw-r--r--graphics/java/android/renderscript/Matrix4f.java79
-rw-r--r--graphics/java/android/renderscript/Mesh.java481
-rw-r--r--graphics/java/android/renderscript/Program.java138
-rw-r--r--graphics/java/android/renderscript/ProgramFragment.java140
-rw-r--r--graphics/java/android/renderscript/ProgramRaster.java100
-rw-r--r--graphics/java/android/renderscript/ProgramStore.java187
-rw-r--r--graphics/java/android/renderscript/ProgramVertex.java141
-rw-r--r--graphics/java/android/renderscript/RSDriverException.java32
-rw-r--r--graphics/java/android/renderscript/RSIllegalArgumentException.java31
-rw-r--r--graphics/java/android/renderscript/RSInvalidStateException.java32
-rw-r--r--graphics/java/android/renderscript/RSRuntimeException.java31
-rw-r--r--graphics/java/android/renderscript/RSSurfaceView.java61
-rw-r--r--graphics/java/android/renderscript/RenderScript.java868
-rw-r--r--graphics/java/android/renderscript/RenderScriptGL.java270
-rw-r--r--graphics/java/android/renderscript/Sampler.java143
-rw-r--r--graphics/java/android/renderscript/Script.java122
-rw-r--r--graphics/java/android/renderscript/ScriptC.java146
-rw-r--r--graphics/java/android/renderscript/Short2.java37
-rw-r--r--graphics/java/android/renderscript/Short3.java38
-rw-r--r--graphics/java/android/renderscript/Short4.java38
-rw-r--r--graphics/java/android/renderscript/SimpleMesh.java364
-rw-r--r--graphics/java/android/renderscript/Type.java268
81 files changed, 6624 insertions, 1956 deletions
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index dd83c3b..d283dea 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.
*/
@@ -428,28 +455,30 @@ public final class Bitmap implements Parcelable {
Rect srcR = new Rect(x, y, x + width, y + height);
RectF dstR = new RectF(0, 0, width, height);
+ final Config newConfig = source.getConfig() == Config.ARGB_8888 ?
+ Config.ARGB_8888 : Config.RGB_565;
+
if (m == null || m.isIdentity()) {
- bitmap = createBitmap(neww, newh,
- source.hasAlpha() ? Config.ARGB_8888 : Config.RGB_565);
+ bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());
paint = null; // not needed
} else {
- /* the dst should have alpha if the src does, or if our matrix
- doesn't preserve rectness
- */
- boolean hasAlpha = source.hasAlpha() || !m.rectStaysRect();
+ final boolean transformed = !m.rectStaysRect();
+
RectF deviceR = new RectF();
m.mapRect(deviceR, dstR);
+
neww = Math.round(deviceR.width());
newh = Math.round(deviceR.height());
- bitmap = createBitmap(neww, newh, hasAlpha ? Config.ARGB_8888 : Config.RGB_565);
- if (hasAlpha) {
- bitmap.eraseColor(0);
- }
+
+ bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
+ transformed || source.hasAlpha());
+
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(m);
+
paint = new Paint();
paint.setFilterBitmap(filter);
- if (!m.rectStaysRect()) {
+ if (transformed) {
paint.setAntiAlias(true);
}
}
@@ -474,8 +503,30 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the width or height are <= 0
*/
public static Bitmap createBitmap(int width, int height, Config config) {
+ return createBitmap(width, height, config, true);
+ }
+
+ /**
+ * Returns a mutable bitmap with the specified width and height. Its
+ * initial density is as per {@link #getDensity}.
+ *
+ * @param width The width of the bitmap
+ * @param height The height of the bitmap
+ * @param config The bitmap config to create.
+ * @param hasAlpha If the bitmap is ARGB_8888 this flag can be used to mark the
+ * bitmap as opaque. Doing so will clear the bitmap in black
+ * instead of transparent.
+ *
+ * @throws IllegalArgumentException if the width or height are <= 0
+ */
+ private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
- bm.eraseColor(0); // start with black/transparent pixels
+ if (config == Config.ARGB_8888 && !hasAlpha) {
+ bm.eraseColor(0xff000000);
+ nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
+ } else {
+ bm.eraseColor(0);
+ }
return bm;
}
@@ -1008,12 +1059,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);
}
}
@@ -1050,6 +1111,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
@@ -1065,7 +1127,7 @@ public final class Bitmap implements Parcelable {
private static native void nativePrepareToDraw(int nativeBitmap);
private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
private static native boolean nativeSameAs(int nb0, int nb1);
-
+
/* package */ final int ni() {
return mNativeBitmap;
}
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 7b49bc5..66f8f70 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -18,7 +18,6 @@ package android.graphics;
import android.content.res.AssetManager;
import android.content.res.Resources;
-import android.os.MemoryFile;
import android.util.DisplayMetrics;
import android.util.TypedValue;
@@ -84,7 +83,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.
@@ -206,10 +205,20 @@ public class BitmapFactory {
public boolean inNativeAlloc;
/**
+ * If inPreferQualityOverSpeed is set to true, the decoder will try to
+ * decode the reconstructed image to a higher quality even at the
+ * expense of the decoding speed. Currently the field only affects JPEG
+ * decode, in the case of which a more accurate, but slightly slower,
+ * IDCT method will be used instead.
+ */
+ public boolean inPreferQualityOverSpeed;
+
+ /**
* The resulting width of the bitmap, set independent of the state of
* inJustDecodeBounds. However, if there is an error trying to decode,
* outWidth will be set to -1.
*/
+
public int outWidth;
/**
@@ -507,9 +516,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);
@@ -530,18 +537,6 @@ public class BitmapFactory {
* @return the decoded bitmap, or null
*/
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
- try {
- if (MemoryFile.isMemoryFile(fd)) {
- int mappedlength = MemoryFile.getSize(fd);
- MemoryFile file = new MemoryFile(fd, mappedlength, "r");
- InputStream is = file.getInputStream();
- Bitmap bm = decodeStream(is, outPadding, opts);
- return finishDecode(bm, outPadding, opts);
- }
- } catch (IOException ex) {
- // invalid filedescriptor, no need to call nativeDecodeFileDescriptor()
- return null;
- }
Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
return finishDecode(bm, outPadding, opts);
}
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
new file mode 100644
index 0000000..454eb4a
--- /dev/null
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -0,0 +1,263 @@
+/* Copyright (C) 2010 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;
+
+import android.content.res.AssetManager;
+
+import java.io.BufferedInputStream;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * BitmapRegionDecoder can be used to decode a rectangle region from an image.
+ * BitmapRegionDecoder is particularly useful when an original image is large and
+ * you only need parts of the image.
+ *
+ * <p>To create a BitmapRegionDecoder, call newInstance(...).
+ * Given a BitmapRegionDecoder, users can call decodeRegion() repeatedly
+ * to get a decoded Bitmap of the specified region.
+ *
+ */
+public final class BitmapRegionDecoder {
+ private int mNativeBitmapRegionDecoder;
+ private boolean mRecycled;
+
+ /**
+ * Create a BitmapRegionDecoder from the specified byte array.
+ * Currently only the Jpeg format is supported.
+ *
+ * @param data byte array of compressed image data.
+ * @param offset offset into data for where the decoder should begin
+ * parsing.
+ * @param length the number of bytes, beginning at offset, to parse
+ * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
+ * shallow reference to the input. If this is false,
+ * then the BitmapRegionDecoder will explicitly make a copy of the
+ * input data, and keep that. Even if sharing is allowed,
+ * the implementation may still decide to make a deep
+ * copy of the input data. If an image is progressively encoded,
+ * allowing sharing may degrade the decoding speed.
+ * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ public static BitmapRegionDecoder newInstance(byte[] data,
+ int offset, int length, boolean isShareable) throws IOException {
+ if ((offset | length) < 0 || data.length < offset + length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return nativeNewInstance(data, offset, length, isShareable);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from the file descriptor.
+ * The position within the descriptor will not be changed when
+ * this returns, so the descriptor can be used again as is.
+ * Currently only the Jpeg format is supported.
+ *
+ * @param fd The file descriptor containing the data to decode
+ * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
+ * shallow reference to the input. If this is false,
+ * then the BitmapRegionDecoder will explicitly make a copy of the
+ * input data, and keep that. Even if sharing is allowed,
+ * the implementation may still decide to make a deep
+ * copy of the input data. If an image is progressively encoded,
+ * allowing sharing may degrade the decoding speed.
+ * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ public static BitmapRegionDecoder newInstance(
+ FileDescriptor fd, boolean isShareable) throws IOException {
+ return nativeNewInstance(fd, isShareable);
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from an input stream.
+ * The stream's position will be where ever it was after the encoded data
+ * was read.
+ * Currently only the Jpeg format is supported.
+ *
+ * @param is The input stream that holds the raw data to be decoded into a
+ * BitmapRegionDecoder.
+ * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
+ * shallow reference to the input. If this is false,
+ * then the BitmapRegionDecoder will explicitly make a copy of the
+ * input data, and keep that. Even if sharing is allowed,
+ * the implementation may still decide to make a deep
+ * copy of the input data. If an image is progressively encoded,
+ * allowing sharing may degrade the decoding speed.
+ * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ public static BitmapRegionDecoder newInstance(InputStream is,
+ boolean isShareable) throws IOException {
+ // we need mark/reset to work properly in JNI
+
+ if (!is.markSupported()) {
+ is = new BufferedInputStream(is, 16 * 1024);
+ }
+
+ if (is instanceof AssetManager.AssetInputStream) {
+ return nativeNewInstance(
+ ((AssetManager.AssetInputStream) is).getAssetInt(),
+ isShareable);
+ } else {
+ // pass some temp storage down to the native code. 1024 is made up,
+ // but should be large enough to avoid too many small calls back
+ // into is.read(...).
+ byte [] tempStorage = new byte[16 * 1024];
+ return nativeNewInstance(is, tempStorage, isShareable);
+ }
+ }
+
+ /**
+ * Create a BitmapRegionDecoder from a file path.
+ * Currently only the Jpeg format is supported.
+ *
+ * @param pathName complete path name for the file to be decoded.
+ * @param isShareable If this is true, then the BitmapRegionDecoder may keep a
+ * shallow reference to the input. If this is false,
+ * then the BitmapRegionDecoder will explicitly make a copy of the
+ * input data, and keep that. Even if sharing is allowed,
+ * the implementation may still decide to make a deep
+ * copy of the input data. If an image is progressively encoded,
+ * allowing sharing may degrade the decoding speed.
+ * @return BitmapRegionDecoder, or null if the image data could not be decoded.
+ * @throws IOException if the image format is not supported or can not be decoded.
+ */
+ public static BitmapRegionDecoder newInstance(String pathName,
+ boolean isShareable) throws IOException {
+ BitmapRegionDecoder decoder = null;
+ InputStream stream = null;
+
+ try {
+ stream = new FileInputStream(pathName);
+ decoder = newInstance(stream, isShareable);
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ // do nothing here
+ }
+ }
+ }
+ return decoder;
+ }
+
+ /* Private constructor that must receive an already allocated native
+ region decoder int (pointer).
+
+ This can be called from JNI code.
+ */
+ private BitmapRegionDecoder(int decoder) {
+ mNativeBitmapRegionDecoder = decoder;
+ mRecycled = false;
+ }
+
+ /**
+ * Decodes a rectangle region in the image specified by rect.
+ *
+ * @param rect The rectangle that specified the region to be decode.
+ * @param options null-ok; Options that control downsampling.
+ * inPurgeable is not supported.
+ * @return The decoded bitmap, or null if the image data could not be
+ * decoded.
+ */
+ public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
+ checkRecycled("decodeRegion called on recycled region decoder");
+ if (rect.left < 0 || rect.top < 0 || rect.right > getWidth()
+ || rect.bottom > getHeight())
+ throw new IllegalArgumentException("rectangle is not inside the image");
+ return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top, options);
+ }
+
+ /** Returns the original image's width */
+ public int getWidth() {
+ checkRecycled("getWidth called on recycled region decoder");
+ return nativeGetWidth(mNativeBitmapRegionDecoder);
+ }
+
+ /** Returns the original image's height */
+ public int getHeight() {
+ checkRecycled("getHeight called on recycled region decoder");
+ return nativeGetHeight(mNativeBitmapRegionDecoder);
+ }
+
+ /**
+ * Frees up the memory associated with this region decoder, and mark the
+ * region decoder as "dead", meaning it will throw an exception if decodeRegion(),
+ * getWidth() or getHeight() is called.
+ *
+ * <p>This operation cannot be reversed, so it should only be called if you are
+ * sure there are no further uses for the region decoder. This is an advanced call,
+ * and normally need not be called, since the normal GC process will free up this
+ * memory when there are no more references to this region decoder.
+ */
+ public void recycle() {
+ if (!mRecycled) {
+ nativeClean(mNativeBitmapRegionDecoder);
+ mRecycled = true;
+ }
+ }
+
+ /**
+ * Returns true if this region decoder has been recycled.
+ * If so, then it is an error to try use its method.
+ *
+ * @return true if the region decoder has been recycled
+ */
+ public final boolean isRecycled() {
+ return mRecycled;
+ }
+
+ /**
+ * Called by methods that want to throw an exception if the region decoder
+ * has already been recycled.
+ */
+ private void checkRecycled(String errorMessage) {
+ if (mRecycled) {
+ throw new IllegalStateException(errorMessage);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ recycle();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ private static native Bitmap nativeDecodeRegion(int lbm,
+ int start_x, int start_y, int width, int height,
+ BitmapFactory.Options options);
+ private static native int nativeGetWidth(int lbm);
+ private static native int nativeGetHeight(int lbm);
+ private static native void nativeClean(int lbm);
+
+ private static native BitmapRegionDecoder nativeNewInstance(
+ byte[] data, int offset, int length, boolean isShareable);
+ private static native BitmapRegionDecoder nativeNewInstance(
+ FileDescriptor fd, boolean isShareable);
+ private static native BitmapRegionDecoder nativeNewInstance(
+ InputStream is, byte[] storage, boolean isShareable);
+ private static native BitmapRegionDecoder nativeNewInstance(
+ int asset, boolean isShareable);
+}
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 612b0ab..4ba679b 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -16,10 +16,16 @@
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;
+ /**
+ * Prevent garbage collection.
+ */
+ @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+ private final Bitmap mBitmap;
/**
* Call this to create a new shader that will draw with a bitmap.
@@ -30,12 +36,13 @@ public class BitmapShader extends Shader {
*/
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 a587d0d..07fe66c 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);
@@ -442,6 +447,16 @@ public class Canvas {
public void getMatrix(Matrix ctm) {
native_getCTM(mNativeCanvas, ctm.native_instance);
}
+
+ /**
+ * Returns a pointer to an internal 4x4 native matrix. The returned
+ * pointer is a pointer to an array of 16 floats.
+ *
+ * @hide
+ */
+ public int getNativeMatrix() {
+ return 0;
+ }
/**
* Return a new matrix with a copy of the canvas' current transformation
@@ -621,7 +636,11 @@ public class Canvas {
EdgeType(int nativeInt) {
this.nativeInt = nativeInt;
}
- final int nativeInt;
+
+ /**
+ * @hide
+ */
+ public final int nativeInt;
}
/**
@@ -958,6 +977,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 +1280,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 +1293,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 +1314,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 +1336,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 +1497,7 @@ public class Canvas {
}
native_drawTextOnPath(mNativeCanvas, text, index, count,
path.ni(), hOffset, vOffset,
- paint.mNativePaint);
+ paint.mBidiFlags, paint.mNativePaint);
}
/**
@@ -1388,7 +1517,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);
}
}
@@ -1431,28 +1561,74 @@ public class Canvas {
drawPicture(picture);
restore();
}
-
+
+ /**
+ * <p>Acquires the Canvas context. After invoking this method, the Canvas
+ * context can be modified by the caller. For instance, if you acquire
+ * the context of an OpenGL Canvas you can reset the GL viewport, scissor,
+ * etc.</p>
+ *
+ * <p>A call to {@link #acquireContext()} should aways be followed by
+ * a call to {@link #releaseContext()}, preferrably using a try block:</p>
+ *
+ * <pre>
+ * try {
+ * if (canvas.acquireContext()) {
+ * // Use the canvas and/or its context
+ * }
+ * } finally {
+ * canvas.releaseContext();
+ * }
+ * </pre>
+ *
+ * <p>Acquiring the context can be an expensive operation and should not
+ * be done unless absolutely necessary.</p>
+ *
+ * <p>Applications should never invoke this method directly.</p>
+ *
+ * @return True if the context could be acquired successfully, false
+ * otherwise (if the context is already acquired for instance.)
+ *
+ * @see #releaseContext()
+ *
+ * @hide
+ */
+ public boolean acquireContext() {
+ return false;
+ }
+
+ /**
+ * <p>Release the context acquired with {@link #acquireContext()}.</p>
+ *
+ * @see #acquireContext()
+ *
+ * @hide
+ */
+ public void releaseContext() {
+ }
+
+ @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 +1731,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 +1755,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..4f32342 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(native_instance, colorMatrix);
}
/**
@@ -40,7 +42,9 @@ public class ColorMatrixColorFilter extends ColorFilter {
throw new ArrayIndexOutOfBoundsException();
}
native_instance = nativeColorMatrixFilter(array);
+ nativeColorFilter = nColorMatrixFilter(native_instance, array);
}
private static native int nativeColorMatrixFilter(float[] array);
+ private static native int nColorMatrixFilter(int nativeFilter, float[] array);
}
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index a06d30b..241ab17 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -20,32 +20,59 @@ 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".
+ "dst", and the result from shader B as its "src".
@param shaderA The colors from this shader are seen as the "dst" by the mode
@param shaderB The colors from this shader are seen as the "src" by the mode
@param mode The mode that combines the colors from the two shaders. If mode
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.
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".
+ "dst", and the result from shader B as its "src".
@param shaderA The colors from this shader are seen as the "dst" by the mode
@param shaderB The colors from this shader are seen as the "src" by the mode
@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..c621de6 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(native_instance, mul, add);
}
private static native int native_CreateLightingFilter(int mul, int add);
+ private static native int nCreateLightingFilter(int nativeFilter, 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..66ed104 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
@@ -419,6 +422,10 @@ public class Matrix {
* the transformed vectors into the array of vectors specified by dst. The
* two arrays represent their "vectors" as pairs of floats [x, y].
*
+ * Note: this method does not apply the translation associated with the matrix. Use
+ * {@link Matrix#mapPoints(float[], int, float[], int, int)} if you want the translation
+ * to be applied.
+ *
* @param dst The array of dst vectors (x,y pairs)
* @param dstIndex The index of the first [x,y] pair of dst floats
* @param src The array of src vectors (x,y pairs)
@@ -452,6 +459,9 @@ public class Matrix {
* the transformed vectors into the array of vectors specified by dst. The
* two arrays represent their "vectors" as pairs of floats [x, y].
*
+ * Note: this method does not apply the translation associated with the matrix. Use
+ * {@link Matrix#mapPoints(float[], float[])} if you want the translation to be applied.
+ *
* @param dst The array of dst vectors (x,y pairs)
* @param src The array of src vectors (x,y pairs)
*/
@@ -475,6 +485,10 @@ public class Matrix {
/**
* Apply this matrix to the array of 2D vectors, and write the transformed
* vectors back into the array.
+ *
+ * Note: this method does not apply the translation associated with the matrix. Use
+ * {@link Matrix#mapPoints(float[])} if you want the translation to be applied.
+ *
* @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform.
*/
public void mapVectors(float[] vecs) {
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 88dfd67..6de4d84 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, mPaint);
+ }
}
/**
@@ -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, mPaint);
+ }
}
/**
@@ -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..e3bb6eb 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,32 @@ public class Paint {
private boolean mHasCompatScaling;
private float mCompatScaling;
private float mInvCompatScaling;
+
+ /**
+ * @hide
+ */
+ public boolean hasShadow;
+ /**
+ * @hide
+ */
+ public float shadowDx;
+ /**
+ * @hide
+ */
+ public float shadowDy;
+ /**
+ * @hide
+ */
+ public float shadowRadius;
+ /**
+ * @hide
+ */
+ public int shadowColor;
+
+ /**
+ * @hide
+ */
+ public int mBidiFlags = BIDI_DEFAULT_LTR;
private static final Style[] sStyleArray = {
Style.FILL, Style.STROKE, Style.FILL_AND_STROKE
@@ -76,8 +106,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 +231,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 +348,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 +357,7 @@ public class Paint {
setFlags(DEFAULT_PAINT_FLAGS);
mHasCompatScaling = false;
mCompatScaling = mInvCompatScaling = 1;
+ mBidiFlags = BIDI_DEFAULT_LTR;
}
/**
@@ -238,6 +380,7 @@ public class Paint {
mHasCompatScaling = src.mHasCompatScaling;
mCompatScaling = src.mCompatScaling;
mInvCompatScaling = src.mInvCompatScaling;
+ mBidiFlags = src.mBidiFlags;
}
}
@@ -252,10 +395,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,18 +953,27 @@ 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 void setShadowLayer(float radius, float dx, float dy, int color) {
+ hasShadow = radius > 0.0f;
+ shadowRadius = radius;
+ shadowDx = dx;
+ shadowDy = dy;
+ shadowColor = color;
+ nSetShadowLayer(radius, dx, dy, color);
+ }
+
+ private native void nSetShadowLayer(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);
+ hasShadow = false;
+ nSetShadowLayer(0, 0, 0, 0);
}
/**
@@ -1232,10 +1407,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 +1457,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 +1752,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 +1774,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());
}
/**
@@ -1363,6 +1818,7 @@ public class Paint {
nativeGetCharArrayBounds(mNativePaint, text, index, count, bounds);
}
+ @Override
protected void finalize() throws Throwable {
finalizer(mNativePaint);
}
@@ -1404,9 +1860,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 +1883,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..1324431 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);
}
@@ -208,6 +236,7 @@ public class Path {
* @param y The y-coordinate of the end of a line
*/
public void lineTo(float x, float y) {
+ isSimplePath = false;
native_lineTo(mNativePath, x, y);
}
@@ -222,6 +251,7 @@ public class Path {
* this contour, to specify a line
*/
public void rLineTo(float dx, float dy) {
+ isSimplePath = false;
native_rLineTo(mNativePath, dx, dy);
}
@@ -236,6 +266,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 +285,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 +303,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 +314,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 +333,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 +349,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 +358,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 +388,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 +405,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 +423,7 @@ public class Path {
if (oval == null) {
throw new NullPointerException("need oval parameter");
}
+ isSimplePath = false;
native_addOval(mNativePath, oval, dir.nativeInt);
}
@@ -390,6 +436,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 +451,7 @@ public class Path {
if (oval == null) {
throw new NullPointerException("need oval parameter");
}
+ isSimplePath = false;
native_addArc(mNativePath, oval, startAngle, sweepAngle);
}
@@ -419,6 +467,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 +487,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 +498,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 +508,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 +518,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 +555,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 +591,8 @@ public class Path {
super.finalize();
}
}
-
- /*package*/ final int ni() {
+
+ final int ni() {
return mNativePath;
}
@@ -592,6 +646,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..ecc7c24 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -25,10 +25,11 @@ 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(native_instance, 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 nativeFilter, 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/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index b4e902d..897762c 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -40,6 +40,8 @@ public class RadialGradient extends Shader {
throw new IllegalArgumentException("color and position arrays must be of equal length");
}
native_instance = nativeCreate1(x, y, radius, colors, positions, tile.nativeInt);
+ native_shader = nativePostCreate1(native_instance, x, y, radius, colors, positions,
+ tile.nativeInt);
}
/** Create a shader that draws a radial gradient given the center and radius.
@@ -56,11 +58,18 @@ public class RadialGradient extends Shader {
throw new IllegalArgumentException("radius must be > 0");
}
native_instance = nativeCreate2(x, y, radius, color0, color1, tile.nativeInt);
+ native_shader = nativePostCreate2(native_instance, x, y, radius, color0, color1,
+ tile.nativeInt);
}
private static native int nativeCreate1(float x, float y, float radius,
- int colors[], float positions[], int tileMode);
+ int colors[], float positions[], int tileMode);
private static native int nativeCreate2(float x, float y, float radius,
- int color0, int color1, int tileMode);
+ int color0, int color1, int tileMode);
+
+ private static native int nativePostCreate1(int native_shader, float x, float y, float radius,
+ int colors[], float positions[], int tileMode);
+ private static native int nativePostCreate2(int native_shader, float x, float y, float radius,
+ int color0, int color1, int tileMode);
}
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..0400b5c 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,21 @@ 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 == null ? 0 : 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/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index 7456993..2afdd4d 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -42,6 +42,7 @@ public class SweepGradient extends Shader {
"color and position arrays must be of equal length");
}
native_instance = nativeCreate1(cx, cy, colors, positions);
+ native_shader = nativePostCreate1(native_instance, cx, cy, colors, positions);
}
/**
@@ -54,11 +55,15 @@ public class SweepGradient extends Shader {
*/
public SweepGradient(float cx, float cy, int color0, int color1) {
native_instance = nativeCreate2(cx, cy, color0, color1);
+ native_shader = nativePostCreate2(native_instance, cx, cy, color0, color1);
}
- private static native int nativeCreate1(float x, float y,
- int colors[], float positions[]);
- private static native int nativeCreate2(float x, float y,
- int color0, int color1);
+ private static native int nativeCreate1(float x, float y, int colors[], float positions[]);
+ private static native int nativeCreate2(float x, float y, int color0, int color1);
+
+ private static native int nativePostCreate1(int native_shader, float cx, float cy,
+ int[] colors, float[] positions);
+ private static native int nativePostCreate2(int native_shader, float cx, float cy,
+ int color0, int color1);
}
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/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 32111e8..032244f 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -174,11 +174,14 @@ public class BitmapDrawable extends Drawable {
}
private void setBitmap(Bitmap bitmap) {
- mBitmap = bitmap;
- if (bitmap != null) {
- computeBitmapSize();
- } else {
- mBitmapWidth = mBitmapHeight = -1;
+ if (bitmap != mBitmap) {
+ mBitmap = bitmap;
+ if (bitmap != null) {
+ computeBitmapSize();
+ } else {
+ mBitmapWidth = mBitmapHeight = -1;
+ }
+ invalidateSelf();
}
}
@@ -205,10 +208,7 @@ public class BitmapDrawable extends Drawable {
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(DisplayMetrics metrics) {
- mTargetDensity = metrics.densityDpi;
- if (mBitmap != null) {
- computeBitmapSize();
- }
+ setTargetDensity(metrics.densityDpi);
}
/**
@@ -220,9 +220,12 @@ public class BitmapDrawable extends Drawable {
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(int density) {
- mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
- if (mBitmap != null) {
- computeBitmapSize();
+ if (mTargetDensity != density) {
+ mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+ if (mBitmap != null) {
+ computeBitmapSize();
+ }
+ invalidateSelf();
}
}
@@ -239,22 +242,28 @@ public class BitmapDrawable extends Drawable {
* @param gravity the gravity
*/
public void setGravity(int gravity) {
- mBitmapState.mGravity = gravity;
- mApplyGravity = true;
+ if (mBitmapState.mGravity != gravity) {
+ mBitmapState.mGravity = gravity;
+ mApplyGravity = true;
+ invalidateSelf();
+ }
}
public void setAntiAlias(boolean aa) {
mBitmapState.mPaint.setAntiAlias(aa);
+ invalidateSelf();
}
@Override
public void setFilterBitmap(boolean filter) {
mBitmapState.mPaint.setFilterBitmap(filter);
+ invalidateSelf();
}
@Override
public void setDither(boolean dither) {
mBitmapState.mPaint.setDither(dither);
+ invalidateSelf();
}
public Shader.TileMode getTileModeX() {
@@ -280,6 +289,7 @@ public class BitmapDrawable extends Drawable {
state.mTileModeX = xmode;
state.mTileModeY = ymode;
mRebuildShader = true;
+ invalidateSelf();
}
}
@@ -336,11 +346,13 @@ public class BitmapDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
mBitmapState.mPaint.setAlpha(alpha);
+ invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter cf) {
mBitmapState.mPaint.setColorFilter(cf);
+ invalidateSelf();
}
/**
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 604c602..4d560be 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -26,10 +26,8 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
/**
- * A specialized Drawable that fills the Canvas with a specified color,
- * with respect to the clip region. Note that a ColorDrawable ignores the ColorFilter.
- * It also ignores the Bounds, meaning it will draw everywhere in the current clip,
- * even if setBounds(...) was called with a smaller area.
+ * A specialized Drawable that fills the Canvas with a specified color.
+ * Note that a ColorDrawable ignores the ColorFilter.
*
* <p>It can be defined in an XML file with the <code>&lt;color></code> element.</p>
*
@@ -37,6 +35,7 @@ import java.io.IOException;
*/
public class ColorDrawable extends Drawable {
private ColorState mState;
+ private final Paint mPaint = new Paint();
/**
* Creates a new black ColorDrawable.
@@ -52,7 +51,7 @@ public class ColorDrawable extends Drawable {
*/
public ColorDrawable(int color) {
this(null);
- mState.mBaseColor = mState.mUseColor = color;
+ setColor(color);
}
private ColorDrawable(ColorState state) {
@@ -66,7 +65,32 @@ public class ColorDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
- canvas.drawColor(mState.mUseColor);
+ if ((mState.mUseColor >>> 24) != 0) {
+ mPaint.setColor(mState.mUseColor);
+ canvas.drawRect(getBounds(), mPaint);
+ }
+ }
+
+ /**
+ * Gets the drawable's color value.
+ *
+ * @return int The color to draw.
+ */
+ public int getColor() {
+ return mState.mUseColor;
+ }
+
+ /**
+ * Sets the drawable's color value. This action will clobber the results of prior calls to
+ * {@link #setAlpha(int)} on this object, which side-affected the underlying color.
+ *
+ * @param color The color to draw.
+ */
+ public void setColor(int color) {
+ if (mState.mBaseColor != color || mState.mUseColor != color) {
+ invalidateSelf();
+ mState.mBaseColor = mState.mUseColor = color;
+ }
}
/**
@@ -88,6 +112,7 @@ public class ColorDrawable extends Drawable {
int baseAlpha = mState.mBaseColor >>> 24;
int useAlpha = baseAlpha * alpha >> 8;
mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24);
+ invalidateSelf();
}
/**
@@ -129,7 +154,7 @@ public class ColorDrawable extends Drawable {
}
final static class ColorState extends ConstantState {
- int mBaseColor; // initial color. never changes
+ int mBaseColor; // base color, independent of setAlpha()
int mUseColor; // basecolor modulated by setAlpha()
int mChangingConfigurations;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 3125321..6cdafdb 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
@@ -414,6 +423,13 @@ public abstract class Drawable {
}
/**
+ * If this Drawable does transition animations between states, ask that
+ * it immediately jump to the current state and skip any active animations.
+ */
+ public void jumpToCurrentState() {
+ }
+
+ /**
* @return The current drawable that will be used by this drawable. For simple drawables, this
* is just the drawable itself. For drawables that change state like
* {@link StateListDrawable} and {@link LevelListDrawable} this will be the child drawable
@@ -472,7 +488,10 @@ public abstract class Drawable {
*/
public boolean setVisible(boolean visible, boolean restart) {
boolean changed = mVisible != visible;
- mVisible = visible;
+ if (changed) {
+ mVisible = visible;
+ invalidateSelf();
+ }
return changed;
}
@@ -645,6 +664,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 +770,10 @@ public abstract class Drawable {
drawable = new StateListDrawable();
} else if (name.equals("level-list")) {
drawable = new LevelListDrawable();
+ /* Probably not doing this.
+ } else if (name.equals("mipmap")) {
+ drawable = new MipmapDrawable();
+ */
} else if (name.equals("layer-list")) {
drawable = new LayerDrawable();
} else if (name.equals("transition")) {
@@ -770,7 +795,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 +830,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 +841,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 +854,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 +893,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..e55a746 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -17,9 +17,20 @@
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;
+import android.os.SystemClock;
+
+/**
+ * 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 {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "DrawableContainer";
/**
* To be proper, we should have a getter for dither (and alpha, etc.)
@@ -40,6 +51,12 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
private int mCurIndex = -1;
private boolean mMutated;
+ // Animations.
+ private Runnable mAnimationRunnable;
+ private long mEnterAnimationEnd;
+ private long mExitAnimationEnd;
+ private Drawable mLastDrawable;
+
// overrides from Drawable
@Override
@@ -47,6 +64,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
if (mCurrDrawable != null) {
mCurrDrawable.draw(canvas);
}
+ if (mLastDrawable != null) {
+ mLastDrawable.draw(canvas);
+ }
}
@Override
@@ -75,7 +95,11 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
if (mAlpha != alpha) {
mAlpha = alpha;
if (mCurrDrawable != null) {
- mCurrDrawable.setAlpha(alpha);
+ if (mEnterAnimationEnd == 0) {
+ mCurrDrawable.setAlpha(alpha);
+ } else {
+ animate(false);
+ }
}
}
}
@@ -100,8 +124,29 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
}
+ /**
+ * Change the global fade duration when a new drawable is entering
+ * the scene.
+ * @param ms The amount of time to fade in milliseconds.
+ */
+ public void setEnterFadeDuration(int ms) {
+ mDrawableContainerState.mEnterFadeDuration = ms;
+ }
+
+ /**
+ * Change the global fade duration when a new drawable is leaving
+ * the scene.
+ * @param ms The amount of time to fade in milliseconds.
+ */
+ public void setExitFadeDuration(int ms) {
+ mDrawableContainerState.mExitFadeDuration = ms;
+ }
+
@Override
protected void onBoundsChange(Rect bounds) {
+ if (mLastDrawable != null) {
+ mLastDrawable.setBounds(bounds);
+ }
if (mCurrDrawable != null) {
mCurrDrawable.setBounds(bounds);
}
@@ -113,7 +158,34 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
@Override
+ public void jumpToCurrentState() {
+ boolean changed = false;
+ if (mLastDrawable != null) {
+ mLastDrawable.jumpToCurrentState();
+ mLastDrawable = null;
+ changed = true;
+ }
+ if (mCurrDrawable != null) {
+ mCurrDrawable.jumpToCurrentState();
+ }
+ if (mExitAnimationEnd != 0) {
+ mExitAnimationEnd = 0;
+ changed = true;
+ }
+ if (mEnterAnimationEnd != 0) {
+ mEnterAnimationEnd = 0;
+ changed = true;
+ }
+ if (changed) {
+ invalidateSelf();
+ }
+ }
+
+ @Override
protected boolean onStateChange(int[] state) {
+ if (mLastDrawable != null) {
+ return mLastDrawable.setState(state);
+ }
if (mCurrDrawable != null) {
return mCurrDrawable.setState(state);
}
@@ -122,6 +194,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
protected boolean onLevelChange(int level) {
+ if (mLastDrawable != null) {
+ return mLastDrawable.setLevel(level);
+ }
if (mCurrDrawable != null) {
return mCurrDrawable.setLevel(level);
}
@@ -160,22 +235,19 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
}
- public void invalidateDrawable(Drawable who)
- {
+ public void invalidateDrawable(Drawable who) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.invalidateDrawable(this);
}
}
- public void scheduleDrawable(Drawable who, Runnable what, long when)
- {
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.scheduleDrawable(this, what, when);
}
}
- public void unscheduleDrawable(Drawable who, Runnable what)
- {
+ public void unscheduleDrawable(Drawable who, Runnable what) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.unscheduleDrawable(this, what);
}
@@ -184,6 +256,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public boolean setVisible(boolean visible, boolean restart) {
boolean changed = super.setVisible(visible, restart);
+ if (mLastDrawable != null) {
+ mLastDrawable.setVisible(visible, restart);
+ }
if (mCurrDrawable != null) {
mCurrDrawable.setVisible(visible, restart);
}
@@ -196,21 +271,43 @@ 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;
}
- if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
- Drawable d = mDrawableContainerState.mDrawables[idx];
+
+ final long now = SystemClock.uptimeMillis();
+
+ if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx
+ + ": exit=" + mDrawableContainerState.mExitFadeDuration
+ + " enter=" + mDrawableContainerState.mEnterFadeDuration);
+
+ if (mDrawableContainerState.mExitFadeDuration > 0) {
+ if (mLastDrawable != null) {
+ mLastDrawable.setVisible(false, false);
+ }
if (mCurrDrawable != null) {
- mCurrDrawable.setVisible(false, false);
+ mLastDrawable = mCurrDrawable;
+ mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration;
+ } else {
+ mLastDrawable = null;
+ mExitAnimationEnd = 0;
}
+ } else if (mCurrDrawable != null) {
+ mCurrDrawable.setVisible(false, false);
+ }
+
+ if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
+ Drawable d = mDrawableContainerState.mDrawables[idx];
mCurrDrawable = d;
mCurIndex = idx;
if (d != null) {
+ if (mDrawableContainerState.mEnterFadeDuration > 0) {
+ mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
+ } else {
+ d.setAlpha(mAlpha);
+ }
d.setVisible(isVisible(), true);
- d.setAlpha(mAlpha);
d.setDither(mDrawableContainerState.mDither);
d.setColorFilter(mColorFilter);
d.setState(getState());
@@ -218,16 +315,72 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
d.setBounds(getBounds());
}
} else {
- if (mCurrDrawable != null) {
- mCurrDrawable.setVisible(false, false);
- }
mCurrDrawable = null;
mCurIndex = -1;
}
+
+ if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) {
+ if (mAnimationRunnable == null) {
+ mAnimationRunnable = new Runnable() {
+ @Override public void run() {
+ animate(true);
+ invalidateSelf();
+ }
+ };
+ } else {
+ unscheduleSelf(mAnimationRunnable);
+ }
+ // Compute first frame and schedule next animation.
+ animate(true);
+ }
+
invalidateSelf();
+
return true;
}
+ void animate(boolean schedule) {
+ final long now = SystemClock.uptimeMillis();
+ boolean animating = false;
+ if (mCurrDrawable != null) {
+ if (mEnterAnimationEnd != 0) {
+ if (mEnterAnimationEnd <= now) {
+ mCurrDrawable.setAlpha(mAlpha);
+ mEnterAnimationEnd = 0;
+ } else {
+ int animAlpha = (int)((mEnterAnimationEnd-now)*255)
+ / mDrawableContainerState.mEnterFadeDuration;
+ if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
+ mCurrDrawable.setAlpha(((255-animAlpha)*mAlpha)/255);
+ animating = true;
+ }
+ }
+ } else {
+ mEnterAnimationEnd = 0;
+ }
+ if (mLastDrawable != null) {
+ if (mExitAnimationEnd != 0) {
+ if (mExitAnimationEnd <= now) {
+ mLastDrawable.setVisible(false, false);
+ mLastDrawable = null;
+ mExitAnimationEnd = 0;
+ } else {
+ int animAlpha = (int)((mExitAnimationEnd-now)*255)
+ / mDrawableContainerState.mExitFadeDuration;
+ if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
+ mLastDrawable.setAlpha((animAlpha*mAlpha)/255);
+ animating = true;
+ }
+ }
+ } else {
+ mExitAnimationEnd = 0;
+ }
+
+ if (schedule && animating) {
+ scheduleSelf(mAnimationRunnable, now + 1000/60);
+ }
+ }
+
@Override
public Drawable getCurrent() {
return mCurrDrawable;
@@ -255,6 +408,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;
@@ -287,6 +446,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
boolean mDither = DEFAULT_DITHER;
+ int mEnterFadeDuration;
+ int mExitFadeDuration;
+
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
@@ -327,6 +489,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mDither = orig.mDither;
+ mEnterFadeDuration = orig.mEnterFadeDuration;
+ mExitFadeDuration = orig.mExitFadeDuration;
+
} else {
mDrawables = new Drawable[10];
mNumChildren = 0;
@@ -443,12 +608,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];
@@ -463,6 +628,22 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
}
+ public final void setEnterFadeDuration(int duration) {
+ mEnterFadeDuration = duration;
+ }
+
+ public final int getEnterFadeDuration() {
+ return mEnterFadeDuration;
+ }
+
+ public final void setExitFadeDuration(int duration) {
+ mExitFadeDuration = duration;
+ }
+
+ public final int getExitFadeDuration() {
+ return mExitFadeDuration;
+ }
+
public final int getOpacity() {
if (mHaveOpacity) {
return mOpacity;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 33ecbea..da8bb1b 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -126,7 +126,7 @@ public class GradientDrawable extends Drawable {
private boolean mRectIsDirty; // internal state
private boolean mMutated;
private Path mRingPath;
- private boolean mPathIsDirty;
+ private boolean mPathIsDirty = true;
/**
* Controls how the gradient is oriented relative to the drawable's bounds
@@ -179,6 +179,8 @@ public class GradientDrawable extends Drawable {
*/
public void setCornerRadii(float[] radii) {
mGradientState.setCornerRadii(radii);
+ mPathIsDirty = true;
+ invalidateSelf();
}
/**
@@ -187,6 +189,8 @@ public class GradientDrawable extends Drawable {
*/
public void setCornerRadius(float radius) {
mGradientState.setCornerRadius(radius);
+ mPathIsDirty = true;
+ invalidateSelf();
}
/**
@@ -212,32 +216,41 @@ public class GradientDrawable extends Drawable {
e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0);
}
mStrokePaint.setPathEffect(e);
+ invalidateSelf();
}
public void setSize(int width, int height) {
- mGradientState.setSize(width, height);
+ mGradientState.setSize(width, height);
+ mPathIsDirty = true;
+ invalidateSelf();
}
public void setShape(int shape) {
mRingPath = null;
+ mPathIsDirty = true;
mGradientState.setShape(shape);
+ invalidateSelf();
}
public void setGradientType(int gradient) {
mGradientState.setGradientType(gradient);
mRectIsDirty = true;
+ invalidateSelf();
}
public void setGradientCenter(float x, float y) {
mGradientState.setGradientCenter(x, y);
+ invalidateSelf();
}
public void setGradientRadius(float gradientRadius) {
mGradientState.setGradientRadius(gradientRadius);
+ invalidateSelf();
}
public void setUseLevel(boolean useLevel) {
mGradientState.mUseLevel = useLevel;
+ invalidateSelf();
}
private int modulateAlpha(int alpha) {
@@ -312,19 +325,20 @@ public class GradientDrawable extends Drawable {
switch (st.mShape) {
case RECTANGLE:
if (st.mRadiusArray != null) {
- mPath.reset();
- mPath.addRoundRect(mRect, st.mRadiusArray,
- Path.Direction.CW);
+ if (mPathIsDirty || mRectIsDirty) {
+ mPath.reset();
+ mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW);
+ mPathIsDirty = mRectIsDirty = false;
+ }
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 +349,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:
@@ -423,6 +442,7 @@ public class GradientDrawable extends Drawable {
public void setColor(int argb) {
mGradientState.setSolidColor(argb);
mFillPaint.setColor(argb);
+ invalidateSelf();
}
@Override
@@ -433,17 +453,26 @@ public class GradientDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
- mAlpha = alpha;
+ if (alpha != mAlpha) {
+ mAlpha = alpha;
+ invalidateSelf();
+ }
}
@Override
public void setDither(boolean dither) {
- mDither = dither;
+ if (dither != mDither) {
+ mDither = dither;
+ invalidateSelf();
+ }
}
@Override
public void setColorFilter(ColorFilter cf) {
- mColorFilter = cf;
+ if (cf != mColorFilter) {
+ mColorFilter = cf;
+ invalidateSelf();
+ }
}
@Override
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 8047dd4..09c041f 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -21,8 +21,12 @@ import org.xmlpull.v1.XmlPullParserException;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.*;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Slog;
import android.view.View;
import java.io.IOException;
@@ -46,6 +50,7 @@ import java.io.IOException;
public class LayerDrawable extends Drawable implements Drawable.Callback {
LayerState mLayerState;
+ private int mOpacityOverride = PixelFormat.UNKNOWN;
private int[] mPaddingL;
private int[] mPaddingT;
private int[] mPaddingR;
@@ -110,6 +115,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
int type;
+ TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.LayerDrawable);
+
+ mOpacityOverride = a.getInt(com.android.internal.R.styleable.LayerDrawable_opacity,
+ PixelFormat.UNKNOWN);
+
+ a.recycle();
+
final int innerDepth = parser.getDepth() + 1;
int depth;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -122,7 +134,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
continue;
}
- TypedArray a = r.obtainAttributes(attrs,
+ a = r.obtainAttributes(attrs,
com.android.internal.R.styleable.LayerDrawableItem);
int left = a.getDimensionPixelOffset(
@@ -266,6 +278,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) {
@@ -387,9 +400,28 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
array[i].mDrawable.setColorFilter(cf);
}
}
+
+ /**
+ * Sets the opacity of this drawable directly, instead of collecting the states from
+ * the layers
+ *
+ * @param opacity The opacity to use, or {@link PixelFormat#UNKNOWN PixelFormat.UNKNOWN}
+ * for the default behavior
+ *
+ * @see PixelFormat#UNKNOWN
+ * @see PixelFormat#TRANSLUCENT
+ * @see PixelFormat#TRANSPARENT
+ * @see PixelFormat#OPAQUE
+ */
+ public void setOpacity(int opacity) {
+ mOpacityOverride = opacity;
+ }
@Override
public int getOpacity() {
+ if (mOpacityOverride != PixelFormat.UNKNOWN) {
+ return mOpacityOverride;
+ }
return mLayerState.getOpacity();
}
diff --git a/graphics/java/android/graphics/drawable/MipmapDrawable.java b/graphics/java/android/graphics/drawable/MipmapDrawable.java
new file mode 100644
index 0000000..cd39719
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/MipmapDrawable.java
@@ -0,0 +1,312 @@
+/*
+ * 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;
+
+/**
+ * @hide -- we are probably moving to do MipMaps in another way (more integrated
+ * with the resource system).
+ *
+ * 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>&lt;mipmap></code> element.
+ * Each mipmap Drawable is defined in a nested <code>&lt;item></code>. For example:
+ * <pre>
+ * &lt;mipmap xmlns:android="http://schemas.android.com/apk/res/android">
+ * &lt;item android:drawable="@drawable/my_image_8" />
+ * &lt;item android:drawable="@drawable/my_image_32" />
+ * &lt;item android:drawable="@drawable/my_image_128" />
+ * &lt;/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 00416d8..35b8319 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -21,7 +21,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.TypedValue;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -99,7 +98,8 @@ public class NinePatchDrawable extends Drawable {
mPadding = state.mPadding;
mTargetDensity = res != null ? res.getDisplayMetrics().densityDpi
: state.mTargetDensity;
- if (DEFAULT_DITHER != state.mDither) {
+ //noinspection PointlessBooleanExpression
+ if (state.mDither != DEFAULT_DITHER) {
// avoid calling the setter unless we need to, since it does a
// lazy allocation of a paint
setDither(state.mDither);
@@ -132,10 +132,7 @@ public class NinePatchDrawable extends Drawable {
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(DisplayMetrics metrics) {
- mTargetDensity = metrics.densityDpi;
- if (mNinePatch != null) {
- computeBitmapSize();
- }
+ setTargetDensity(metrics.densityDpi);
}
/**
@@ -147,9 +144,12 @@ public class NinePatchDrawable extends Drawable {
* @see android.graphics.Bitmap#getDensity()
*/
public void setTargetDensity(int density) {
- mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
- if (mNinePatch != null) {
- computeBitmapSize();
+ if (density != mTargetDensity) {
+ mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+ if (mNinePatch != null) {
+ computeBitmapSize();
+ }
+ invalidateSelf();
}
}
@@ -177,16 +177,9 @@ public class NinePatchDrawable extends Drawable {
}
}
}
-
- // 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);
}
@@ -204,16 +197,19 @@ public class NinePatchDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
getPaint().setAlpha(alpha);
+ invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter cf) {
getPaint().setColorFilter(cf);
+ invalidateSelf();
}
@Override
public void setDither(boolean dither) {
getPaint().setDither(dither);
+ invalidateSelf();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/PaintDrawable.java b/graphics/java/android/graphics/drawable/PaintDrawable.java
index c86fc46..c71cda1 100644
--- a/graphics/java/android/graphics/drawable/PaintDrawable.java
+++ b/graphics/java/android/graphics/drawable/PaintDrawable.java
@@ -66,6 +66,7 @@ public class PaintDrawable extends ShapeDrawable {
} else {
setShape(new RoundRectShape(radii, null, null));
}
+ invalidateSelf();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 9c47dab..f3f3653 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -232,8 +232,6 @@ public class RotateDrawable extends Drawable implements Drawable.Callback {
float toDegrees = a.getFloat(
com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
- toDegrees = Math.max(fromDegrees, toDegrees);
-
int res = a.getResourceId(
com.android.internal.R.styleable.RotateDrawable_drawable, 0);
Drawable drawable = null;
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index b623d80..dcaf20b 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -95,6 +95,8 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
float sw = getPercent(a, com.android.internal.R.styleable.ScaleDrawable_scaleWidth);
float sh = getPercent(a, com.android.internal.R.styleable.ScaleDrawable_scaleHeight);
int g = a.getInt(com.android.internal.R.styleable.ScaleDrawable_scaleGravity, Gravity.LEFT);
+ boolean min = a.getBoolean(
+ com.android.internal.R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, false);
Drawable dr = a.getDrawable(com.android.internal.R.styleable.ScaleDrawable_drawable);
a.recycle();
@@ -116,6 +118,7 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
mScaleState.mScaleWidth = sw;
mScaleState.mScaleHeight = sh;
mScaleState.mGravity = g;
+ mScaleState.mUseIntrinsicSizeAsMin = min;
if (dr != null) {
dr.setCallback(this);
}
@@ -206,15 +209,16 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
@Override
protected void onBoundsChange(Rect bounds) {
final Rect r = mTmpRect;
+ final boolean min = mScaleState.mUseIntrinsicSizeAsMin;
int level = getLevel();
int w = bounds.width();
- final int iw = 0; //mScaleState.mDrawable.getIntrinsicWidth();
if (mScaleState.mScaleWidth > 0) {
+ final int iw = min ? mScaleState.mDrawable.getIntrinsicWidth() : 0;
w -= (int) ((w - iw) * (10000 - level) * mScaleState.mScaleWidth / 10000);
}
int h = bounds.height();
- final int ih = 0; //mScaleState.mDrawable.getIntrinsicHeight();
if (mScaleState.mScaleHeight > 0) {
+ final int ih = min ? mScaleState.mDrawable.getIntrinsicHeight() : 0;
h -= (int) ((h - ih) * (10000 - level) * mScaleState.mScaleHeight / 10000);
}
Gravity.apply(mScaleState.mGravity, w, h, bounds, r);
@@ -258,6 +262,7 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
float mScaleWidth;
float mScaleHeight;
int mGravity;
+ boolean mUseIntrinsicSizeAsMin;
private boolean mCheckedConstantState;
private boolean mCanConstantState;
@@ -273,6 +278,7 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
mScaleWidth = orig.mScaleWidth;
mScaleHeight = orig.mScaleHeight;
mGravity = orig.mGravity;
+ mUseIntrinsicSizeAsMin = orig.mUseIntrinsicSizeAsMin;
mCheckedConstantState = mCanConstantState = true;
}
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index be1892e..92252fc 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -129,6 +129,7 @@ public class ShapeDrawable extends Drawable {
}
mShapeState.mPadding.set(left, top, right, bottom);
}
+ invalidateSelf();
}
/**
@@ -144,6 +145,7 @@ public class ShapeDrawable extends Drawable {
}
mShapeState.mPadding.set(padding);
}
+ invalidateSelf();
}
/**
@@ -153,6 +155,7 @@ public class ShapeDrawable extends Drawable {
*/
public void setIntrinsicWidth(int width) {
mShapeState.mIntrinsicWidth = width;
+ invalidateSelf();
}
/**
@@ -162,6 +165,7 @@ public class ShapeDrawable extends Drawable {
*/
public void setIntrinsicHeight(int height) {
mShapeState.mIntrinsicHeight = height;
+ invalidateSelf();
}
@Override
@@ -236,11 +240,13 @@ public class ShapeDrawable extends Drawable {
*/
@Override public void setAlpha(int alpha) {
mShapeState.mAlpha = alpha;
+ invalidateSelf();
}
@Override
public void setColorFilter(ColorFilter cf) {
mShapeState.mPaint.setColorFilter(cf);
+ invalidateSelf();
}
@Override
@@ -264,6 +270,7 @@ public class ShapeDrawable extends Drawable {
@Override
public void setDither(boolean dither) {
mShapeState.mPaint.setDither(dither);
+ invalidateSelf();
}
@Override
@@ -344,6 +351,7 @@ public class ShapeDrawable extends Drawable {
mShapeState.mPaint.setShader(mShapeState.mShaderFactory.resize(w, h));
}
}
+ invalidateSelf();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 239be40..384ca81 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -20,6 +20,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.Arrays;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -44,6 +45,7 @@ import android.util.StateSet;
* @attr ref android.R.styleable#DrawableStates_state_checkable
* @attr ref android.R.styleable#DrawableStates_state_checked
* @attr ref android.R.styleable#DrawableStates_state_selected
+ * @attr ref android.R.styleable#DrawableStates_state_activated
* @attr ref android.R.styleable#DrawableStates_state_active
* @attr ref android.R.styleable#DrawableStates_state_single
* @attr ref android.R.styleable#DrawableStates_state_first
@@ -52,6 +54,9 @@ import android.util.StateSet;
* @attr ref android.R.styleable#DrawableStates_state_pressed
*/
public class StateListDrawable extends DrawableContainer {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "StateListDrawable";
+
/**
* To be proper, we should have a getter for dither (and alpha, etc.)
* so that proxy classes like this can save/restore their delegates'
@@ -93,6 +98,8 @@ public class StateListDrawable extends DrawableContainer {
@Override
protected boolean onStateChange(int[] stateSet) {
int idx = mStateListState.indexOfStateSet(stateSet);
+ if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
+ + Arrays.toString(stateSet) + " found " + idx);
if (idx < 0) {
idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
}
@@ -117,6 +124,10 @@ public class StateListDrawable extends DrawableContainer {
com.android.internal.R.styleable.StateListDrawable_variablePadding, false));
mStateListState.setConstantSize(a.getBoolean(
com.android.internal.R.styleable.StateListDrawable_constantSize, false));
+ mStateListState.setEnterFadeDuration(a.getInt(
+ com.android.internal.R.styleable.StateListDrawable_enterFadeDuration, 0));
+ mStateListState.setExitFadeDuration(a.getInt(
+ com.android.internal.R.styleable.StateListDrawable_exitFadeDuration, 0));
setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither,
DEFAULT_DITHER));
@@ -251,7 +262,7 @@ public class StateListDrawable extends DrawableContainer {
}
static final class StateListState extends DrawableContainerState {
- private int[][] mStateSets;
+ int[][] mStateSets;
StateListState(StateListState orig, StateListDrawable owner, Resources res) {
super(orig, owner, res);
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/graphics/utils/BoundaryPatch.java b/graphics/java/android/graphics/utils/BoundaryPatch.java
deleted file mode 100644
index 1cd5e13..0000000
--- a/graphics/java/android/graphics/utils/BoundaryPatch.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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.graphics.utils;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Shader;
-import android.graphics.Xfermode;
-
-/**
- * @hide
- */
-public class BoundaryPatch {
- private Paint mPaint;
- private Bitmap mTexture;
- private int mRows;
- private int mCols;
- private float[] mCubicPoints;
- private boolean mDirty;
- // these are the computed output of the native code
- private float[] mVerts;
- private short[] mIndices;
-
- public BoundaryPatch() {
- mRows = mCols = 2; // default minimum
- mCubicPoints = new float[24];
- mPaint = new Paint();
- mPaint.setDither(true);
- mPaint.setFilterBitmap(true);
- mDirty = true;
- }
-
- /**
- * Set the boundary to be 4 cubics. This takes a single array of floats,
- * and picks up the 12 pairs starting at offset, and treats them as
- * the x,y coordinates of the cubic control points. The points wrap around
- * a patch, as follows. For documentation purposes, pts[i] will mean the
- * x,y pair of floats, as if pts[] were an array of "points".
- *
- * Top: pts[0..3]
- * Right: pts[3..6]
- * Bottom: pts[6..9]
- * Right: pts[9..11], pts[0]
- *
- * The coordinates are copied from the input array, so subsequent changes
- * to pts[] will not be reflected in the boundary.
- *
- * @param pts The src array of x,y pairs for the boundary cubics
- * @param offset The index into pts of the first pair
- * @param rows The number of points across to approximate the boundary.
- * Must be >= 2, though very large values may slow down drawing
- * @param cols The number of points down to approximate the boundary.
- * Must be >= 2, though very large values may slow down drawing
- */
- public void setCubicBoundary(float[] pts, int offset, int rows, int cols) {
- if (rows < 2 || cols < 2) {
- throw new RuntimeException("rows and cols must be >= 2");
- }
- System.arraycopy(pts, offset, mCubicPoints, 0, 24);
- if (mRows != rows || mCols != cols) {
- mRows = rows;
- mCols = cols;
- }
- mDirty = true;
- }
-
- /**
- * Reference a bitmap texture to be mapped onto the patch.
- */
- public void setTexture(Bitmap texture) {
- if (mTexture != texture) {
- if (mTexture == null ||
- mTexture.getWidth() != texture.getWidth() ||
- mTexture.getHeight() != texture.getHeight()) {
- // need to recompute texture coordinates
- mDirty = true;
- }
- mTexture = texture;
- mPaint.setShader(new BitmapShader(texture,
- Shader.TileMode.CLAMP,
- Shader.TileMode.CLAMP));
- }
- }
-
- /**
- * Return the paint flags for the patch
- */
- public int getPaintFlags() {
- return mPaint.getFlags();
- }
-
- /**
- * Set the paint flags for the patch
- */
- public void setPaintFlags(int flags) {
- mPaint.setFlags(flags);
- }
-
- /**
- * Set the xfermode for the patch
- */
- public void setXfermode(Xfermode mode) {
- mPaint.setXfermode(mode);
- }
-
- /**
- * Set the alpha for the patch
- */
- public void setAlpha(int alpha) {
- mPaint.setAlpha(alpha);
- }
-
- /**
- * Draw the patch onto the canvas.
- *
- * setCubicBoundary() and setTexture() must be called before drawing.
- */
- public void draw(Canvas canvas) {
- if (mDirty) {
- buildCache();
- mDirty = false;
- }
-
- // cut the count in half, since mVerts.length is really the length of
- // the verts[] and tex[] arrays combined
- // (tex[] are stored after verts[])
- int vertCount = mVerts.length >> 1;
- canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertCount,
- mVerts, 0, mVerts, vertCount, null, 0,
- mIndices, 0, mIndices.length,
- mPaint);
- }
-
- private void buildCache() {
- // we need mRows * mCols points, for verts and another set for textures
- // so *2 for going from points -> floats, and *2 for verts and textures
- int vertCount = mRows * mCols * 4;
- if (mVerts == null || mVerts.length != vertCount) {
- mVerts = new float[vertCount];
- }
-
- int indexCount = (mRows - 1) * (mCols - 1) * 6;
- if (mIndices == null || mIndices.length != indexCount) {
- mIndices = new short[indexCount];
- }
-
- nativeComputeCubicPatch(mCubicPoints,
- mTexture.getWidth(), mTexture.getHeight(),
- mRows, mCols, mVerts, mIndices);
- }
-
- private static native
- void nativeComputeCubicPatch(float[] cubicPoints,
- int texW, int texH, int rows, int cols,
- float[] verts, short[] indices);
-}
-
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index b27c7f5..074e423 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -34,145 +34,242 @@ public class Allocation extends BaseObj {
Type mType;
Bitmap mBitmap;
+ public enum CubemapLayout {
+ VERTICAL_FACE_LIST (0),
+ HORIZONTAL_FACE_LIST (1),
+ VERTICAL_CROSS (2),
+ HORIZONTAL_CROSS (3);
+
+ int mID;
+ CubemapLayout(int id) {
+ mID = id;
+ }
+ }
+
Allocation(int id, RenderScript rs, Type t) {
- super(rs);
- mID = id;
+ super(id, rs);
mType = t;
}
+ Allocation(int id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ @Override
+ void updateFromNative() {
+ super.updateFromNative();
+ int typeID = mRS.nAllocationGetType(getID());
+ if(typeID != 0) {
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
+ }
+ }
+
public Type getType() {
return mType;
}
public void uploadToTexture(int baseMipLevel) {
mRS.validate();
- mRS.nAllocationUploadToTexture(mID, false, baseMipLevel);
+ mRS.nAllocationUploadToTexture(getID(), false, baseMipLevel);
}
public void uploadToTexture(boolean genMips, int baseMipLevel) {
mRS.validate();
- mRS.nAllocationUploadToTexture(mID, genMips, baseMipLevel);
+ mRS.nAllocationUploadToTexture(getID(), genMips, baseMipLevel);
}
public void uploadToBufferObject() {
mRS.validate();
- mRS.nAllocationUploadToBufferObject(mID);
+ mRS.nAllocationUploadToBufferObject(getID());
}
- public void data(int[] d) {
+
+ public void copyFrom(BaseObj[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ if (d.length != mType.getCount()) {
+ throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
+ mType.getCount() + ", array length = " + d.length);
+ }
+ int i[] = new int[d.length];
+ for (int ct=0; ct < d.length; ct++) {
+ i[ct] = d[ct].getID();
+ }
+ subData1D(0, mType.getCount(), i);
+ }
+
+ public void copyFrom(int[] d) {
+ mRS.validate();
+ subData1D(0, mType.getCount(), d);
+ }
+ public void copyFrom(short[] d) {
+ mRS.validate();
+ subData1D(0, mType.getCount(), d);
}
- public void data(short[] d) {
+ public void copyFrom(byte[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ subData1D(0, mType.getCount(), d);
}
- public void data(byte[] d) {
+ public void copyFrom(float[] d) {
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ subData1D(0, mType.getCount(), d);
}
- public void data(float[] d) {
+
+ public void copyFrom(Bitmap b) {
+
mRS.validate();
- subData1D(0, mType.getElementCount(), d);
+ if(mType.getX() != b.getWidth() ||
+ mType.getY() != b.getHeight()) {
+ throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
+ }
+
+ mRS.nAllocationUpdateFromBitmap(getID(), b);
+ }
+
+ public void subData(int xoff, FieldPacker fp) {
+ int eSize = mType.mElement.getSizeBytes();
+ final byte[] data = fp.getData();
+
+ int count = data.length / eSize;
+ if ((eSize * count) != data.length) {
+ throw new RSIllegalArgumentException("Field packer length " + data.length +
+ " not divisible by element size " + eSize + ".");
+ }
+ data1DChecks(xoff, count, data.length, data.length);
+ mRS.nAllocationSubData1D(getID(), xoff, count, data, data.length);
+ }
+
+
+ public void subElementData(int xoff, int component_number, FieldPacker fp) {
+ if (component_number >= mType.mElement.mElements.length) {
+ throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ throw new RSIllegalArgumentException("Offset must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+
+ if (data.length != eSize) {
+ throw new RSIllegalArgumentException("Field packer sizelength " + data.length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationSubElementData1D(getID(), xoff, component_number, 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 RSIllegalArgumentException("Offset must be >= 0.");
+ }
+ if(count < 1) {
+ throw new RSIllegalArgumentException("Count must be >= 1.");
+ }
+ if((off + count) > mType.getCount()) {
+ throw new RSIllegalArgumentException("Overflow, Available count " + mType.getCount() +
+ ", got " + count + " at offset " + off + ".");
}
if((len) < dataSize) {
- throw new IllegalArgumentException("Array too small for allocation type.");
+ throw new RSIllegalArgumentException("Array too small for allocation type.");
}
}
public void subData1D(int off, int count, int[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationSubData1D(getID(), off, count, d, dataSize);
}
public void subData1D(int off, int count, short[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 2, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationSubData1D(getID(), off, count, d, dataSize);
}
public void subData1D(int off, int count, byte[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationSubData1D(getID(), off, count, d, dataSize);
}
public void subData1D(int off, int count, float[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
- mRS.nAllocationSubData1D(mID, off, count, d, dataSize);
+ mRS.nAllocationSubData1D(getID(), off, count, d, dataSize);
}
-
public void subData2D(int xoff, int yoff, int w, int h, int[] d) {
mRS.validate();
- mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
+ mRS.nAllocationSubData2D(getID(), xoff, yoff, w, h, d, d.length * 4);
}
public void subData2D(int xoff, int yoff, int w, int h, float[] d) {
mRS.validate();
- mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4);
+ mRS.nAllocationSubData2D(getID(), xoff, yoff, w, h, d, d.length * 4);
}
public void readData(int[] d) {
mRS.validate();
- mRS.nAllocationRead(mID, d);
+ mRS.nAllocationRead(getID(), d);
}
public void readData(float[] d) {
mRS.validate();
- mRS.nAllocationRead(mID, d);
+ mRS.nAllocationRead(getID(), d);
}
- public void data(Object o) {
- mRS.validate();
- mRS.nAllocationSubDataFromObject(mID, mType, 0, o);
- }
+ public synchronized void resize(int dimX) {
+ if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+ throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
+ }
+ mRS.nAllocationResize1D(getID(), dimX);
+ mRS.finish(); // Necessary because resize is fifoed and update is async.
- public void read(Object o) {
- mRS.validate();
- mRS.nAllocationSubReadFromObject(mID, mType, 0, o);
+ int typeID = mRS.nAllocationGetType(getID());
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
}
- public void subData(int offset, Object o) {
- mRS.validate();
- mRS.nAllocationSubDataFromObject(mID, mType, offset, o);
+ /*
+ public void resize(int dimX, int dimY) {
+ if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
+ throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
+ }
+ if (mType.getY() == 0) {
+ throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
+ }
+ mRS.nAllocationResize2D(getID(), dimX, dimY);
}
+ */
public class Adapter1D extends BaseObj {
Adapter1D(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
public void setConstraint(Dimension dim, int value) {
mRS.validate();
- mRS.nAdapter1DSetConstraint(mID, dim.mID, value);
+ mRS.nAdapter1DSetConstraint(getID(), dim.mID, value);
}
public void data(int[] d) {
mRS.validate();
- mRS.nAdapter1DData(mID, d);
+ mRS.nAdapter1DData(getID(), d);
}
public void data(float[] d) {
mRS.validate();
- mRS.nAdapter1DData(mID, d);
+ mRS.nAdapter1DData(getID(), d);
}
public void subData(int off, int count, int[] d) {
mRS.validate();
- mRS.nAdapter1DSubData(mID, off, count, d);
+ mRS.nAdapter1DSubData(getID(), off, count, d);
}
public void subData(int off, int count, float[] d) {
mRS.validate();
- mRS.nAdapter1DSubData(mID, off, count, d);
+ mRS.nAdapter1DSubData(getID(), off, count, d);
}
}
@@ -180,42 +277,41 @@ public class Allocation extends BaseObj {
mRS.validate();
int id = mRS.nAdapter1DCreate();
if(id == 0) {
- throw new IllegalStateException("allocation failed.");
+ throw new RSRuntimeException("Adapter creation failed.");
}
- mRS.nAdapter1DBindAllocation(id, mID);
+ mRS.nAdapter1DBindAllocation(id, getID());
return new Adapter1D(id, mRS);
}
public class Adapter2D extends BaseObj {
Adapter2D(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
public void setConstraint(Dimension dim, int value) {
mRS.validate();
- mRS.nAdapter2DSetConstraint(mID, dim.mID, value);
+ mRS.nAdapter2DSetConstraint(getID(), dim.mID, value);
}
public void data(int[] d) {
mRS.validate();
- mRS.nAdapter2DData(mID, d);
+ mRS.nAdapter2DData(getID(), d);
}
public void data(float[] d) {
mRS.validate();
- mRS.nAdapter2DData(mID, d);
+ mRS.nAdapter2DData(getID(), d);
}
public void subData(int xoff, int yoff, int w, int h, int[] d) {
mRS.validate();
- mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+ mRS.nAdapter2DSubData(getID(), xoff, yoff, w, h, d);
}
public void subData(int xoff, int yoff, int w, int h, float[] d) {
mRS.validate();
- mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+ mRS.nAdapter2DSubData(getID(), xoff, yoff, w, h, d);
}
}
@@ -223,9 +319,12 @@ public class Allocation extends BaseObj {
mRS.validate();
int id = mRS.nAdapter2DCreate();
if(id == 0) {
- throw new IllegalStateException("allocation failed.");
+ throw new RSRuntimeException("allocation failed.");
+ }
+ mRS.nAdapter2DBindAllocation(id, getID());
+ if(id == 0) {
+ throw new RSRuntimeException("Adapter creation failed.");
}
- mRS.nAdapter2DBindAllocation(id, mID);
return new Adapter2D(id, mRS);
}
@@ -237,14 +336,16 @@ public class Allocation extends BaseObj {
mBitmapOptions.inScaled = false;
}
- static public Allocation createTyped(RenderScript rs, Type type)
- throws IllegalArgumentException {
+ static public Allocation createTyped(RenderScript rs, Type type) {
rs.validate();
- if(type.mID == 0) {
- throw new IllegalStateException("Bad Type");
+ if(type.getID() == 0) {
+ throw new RSInvalidStateException("Bad Type");
+ }
+ int id = rs.nAllocationCreateTyped(type.getID());
+ if(id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
}
- int id = rs.nAllocationCreateTyped(type.mID);
return new Allocation(id, rs, type);
}
@@ -253,12 +354,12 @@ public class Allocation extends BaseObj {
rs.validate();
Type.Builder b = new Type.Builder(rs, e);
- b.add(Dimension.X, count);
+ b.setX(count);
Type t = b.create();
- int id = rs.nAllocationCreateTyped(t.mID);
+ int id = rs.nAllocationCreateTyped(t.getID());
if(id == 0) {
- throw new IllegalStateException("Bad element.");
+ throw new RSRuntimeException("Allocation creation failed.");
}
return new Allocation(id, rs, t);
}
@@ -277,39 +378,75 @@ public class Allocation extends BaseObj {
if (bc == Bitmap.Config.RGB_565) {
return Element.RGB_565(rs);
}
- throw new IllegalStateException("Bad bitmap type.");
+ throw new RSInvalidStateException("Bad bitmap type: " + bc);
}
- static private Type typeFromBitmap(RenderScript rs, Bitmap b) {
+ static private Type typeFromBitmap(RenderScript rs, Bitmap b, boolean mip) {
Element e = elementFromBitmap(rs, b);
Type.Builder tb = new Type.Builder(rs, e);
- tb.add(Dimension.X, b.getWidth());
- tb.add(Dimension.Y, b.getHeight());
+ tb.setX(b.getWidth());
+ tb.setY(b.getHeight());
+ tb.setMipmaps(mip);
return tb.create();
}
- static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
+ static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
+ Element dstFmt, boolean genMips) {
+ rs.validate();
+ Type t = typeFromBitmap(rs, b, genMips);
+
+ int id = rs.nAllocationCreateFromBitmap(dstFmt.getID(), genMips, b);
+ if(id == 0) {
+ throw new RSRuntimeException("Load failed.");
+ }
+ return new Allocation(id, rs, t);
+ }
+ static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
+ Element dstFmt,
+ boolean genMips,
+ CubemapLayout layout) {
rs.validate();
- Type t = typeFromBitmap(rs, b);
+ int height = b.getHeight();
+ int width = b.getWidth();
+
+ if (layout != CubemapLayout.VERTICAL_FACE_LIST) {
+ throw new RSIllegalArgumentException("Only vertical face list supported");
+ }
+ if (height % 6 != 0) {
+ throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
+ }
+ if (height / 6 != width) {
+ throw new RSIllegalArgumentException("Only square cobe map faces supported");
+ }
+ boolean isPow2 = (width & (width - 1)) == 0;
+ if (!isPow2) {
+ throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+ }
+
+ Element e = elementFromBitmap(rs, b);
+ Type.Builder tb = new Type.Builder(rs, e);
+ tb.setX(width);
+ tb.setY(width);
+ tb.setFaces(true);
+ tb.setMipmaps(genMips);
+ Type t = tb.create();
- int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b);
+ int id = rs.nAllocationCubeCreateFromBitmap(dstFmt.getID(), genMips, b);
if(id == 0) {
- throw new IllegalStateException("Load failed.");
+ throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
}
return new Allocation(id, rs, t);
}
- static public Allocation createBitmapRef(RenderScript rs, Bitmap b)
- throws IllegalArgumentException {
+ static public Allocation createBitmapRef(RenderScript rs, Bitmap b) {
rs.validate();
- Type t = typeFromBitmap(rs, b);
+ Type t = typeFromBitmap(rs, b, false);
int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
if(id == 0) {
- throw new IllegalStateException("Load failed.");
+ throw new RSRuntimeException("Load failed.");
}
Allocation a = new Allocation(id, rs, t);
@@ -317,19 +454,7 @@ public class Allocation extends BaseObj {
return a;
}
- static Allocation createFromBitmapBoxed(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
-
- rs.validate();
- int id = rs.nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b);
- if(id == 0) {
- throw new IllegalStateException("Load failed.");
- }
- return new Allocation(id, rs, null);
- }
-
- static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
+ static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips) {
rs.validate();
InputStream is = null;
@@ -338,15 +463,14 @@ public class Allocation extends BaseObj {
is = res.openRawResource(id, value);
int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
- int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips,
- asset);
+ int aId = rs.nAllocationCreateFromAssetStream(dstFmt.getID(), genMips, asset);
- if(allocationId == 0) {
- throw new IllegalStateException("Load failed.");
+ if (aId == 0) {
+ throw new RSRuntimeException("Load failed.");
}
- return new Allocation(allocationId, rs, null);
- } catch (Exception e) {
- // Ignore
+ Allocation alloc = new Allocation(aId, rs, null);
+ alloc.updateFromNative();
+ return alloc;
} finally {
if (is != null) {
try {
@@ -356,26 +480,19 @@ public class Allocation extends BaseObj {
}
}
}
-
- return null;
}
- static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
- throws IllegalArgumentException {
-
- mBitmapOptions.inPreferredConfig = null;
- if (dstFmt == rs.mElement_RGBA_8888) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
- } else if (dstFmt == rs.mElement_RGB_888) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
- } else if (dstFmt == rs.mElement_RGBA_4444) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;
- } else if (dstFmt == rs.mElement_RGB_565) {
- mBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
+ static public Allocation createFromString(RenderScript rs, String str) {
+ byte[] allocArray = null;
+ try {
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length);
+ alloc.copyFrom(allocArray);
+ return alloc;
+ }
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
}
-
- Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
- return createFromBitmapBoxed(rs, b, dstFmt, genMips);
}
}
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 002fc78..c02435f 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -21,48 +21,79 @@ import android.util.Log;
/**
* @hide
*
+ * BaseObj is the base class for interfacing with native renderscript objects.
+ * It primarly contains code for tracking the native object ID and forcably
+ * disconecting the object from the native allocation for early cleanup.
+ *
**/
class BaseObj {
-
- BaseObj(RenderScript rs) {
+ BaseObj(int id, RenderScript rs) {
rs.validate();
mRS = rs;
- mID = 0;
+ mID = id;
mDestroyed = false;
}
- public int getID() {
+ void setID(int id) {
+ if (mID != 0) {
+ throw new RSRuntimeException("Internal Error, reset of object ID.");
+ }
+ mID = id;
+ }
+
+ /**
+ * Lookup the native object ID for this object. Primarily used by the
+ * generated reflected code.
+ *
+ *
+ * @return int
+ */
+ int getID() {
+ if (mDestroyed) {
+ throw new RSInvalidStateException("using a destroyed object.");
+ }
return mID;
}
- int mID;
- boolean mDestroyed;
- String mName;
+ void checkValid() {
+ if (mID == 0) {
+ throw new RSIllegalArgumentException("Invalid object.");
+ }
+ }
+
+ private int mID;
+ private boolean mDestroyed;
+ private String mName;
RenderScript mRS;
- public void setName(String s) throws IllegalStateException, IllegalArgumentException
- {
- if(s.length() < 1) {
- throw new IllegalArgumentException("setName does not accept a zero length string.");
+ /**
+ * setName assigns a name to an object. This object can later be looked up
+ * by this name. This name will also be retained if the object is written
+ * to an A3D file.
+ *
+ * @param name The name to assign to the object.
+ */
+ public void setName(String name) {
+ if(name.length() < 1) {
+ throw new RSIllegalArgumentException("setName does not accept a zero length string.");
}
if(mName != null) {
- throw new IllegalArgumentException("setName object already has a name.");
+ throw new RSIllegalArgumentException("setName object already has a name.");
}
try {
- byte[] bytes = s.getBytes("UTF-8");
+ byte[] bytes = name.getBytes("UTF-8");
mRS.nAssignName(mID, bytes);
- mName = s;
+ mName = name;
} catch (java.io.UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
- protected void finalize() throws Throwable
- {
+ protected void finalize() throws Throwable {
if (!mDestroyed) {
if(mID != 0 && mRS.isAlive()) {
- mRS.nObjDestroyOOB(mID);
+ mRS.nObjDestroy(mID);
}
mRS = null;
mID = 0;
@@ -73,13 +104,28 @@ class BaseObj {
super.finalize();
}
- public void destroy() {
+ /**
+ * destroy disconnects the object from the native object effectivly
+ * rendering this java object dead. The primary use is to force immediate
+ * cleanup of resources when its believed the GC will not respond quickly
+ * enough.
+ */
+ synchronized public void destroy() {
if(mDestroyed) {
- throw new IllegalStateException("Object already destroyed.");
+ throw new RSInvalidStateException("Object already destroyed.");
}
mDestroyed = true;
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() {
+ mRS.validate();
+ mName = mRS.nGetName(getID());
+ }
+
}
diff --git a/graphics/java/android/renderscript/Vector2f.java b/graphics/java/android/renderscript/Byte2.java
index 567d57f..95cf88c 100644
--- a/graphics/java/android/renderscript/Vector2f.java
+++ b/graphics/java/android/renderscript/Byte2.java
@@ -24,12 +24,12 @@ import android.util.Log;
* @hide
*
**/
-public class Vector2f {
- public Vector2f() {
+public class Byte2 {
+ public Byte2() {
}
- public float x;
- public float y;
+ public byte x;
+ public byte y;
}
diff --git a/graphics/java/android/renderscript/Vector3f.java b/graphics/java/android/renderscript/Byte3.java
index f2842f3..a6c0ca9 100644
--- a/graphics/java/android/renderscript/Vector3f.java
+++ b/graphics/java/android/renderscript/Byte3.java
@@ -24,13 +24,13 @@ import android.util.Log;
* @hide
*
**/
-public class Vector3f {
- public Vector3f() {
+public class Byte3 {
+ public Byte3() {
}
- public float x;
- public float y;
- public float z;
+ public byte x;
+ public byte y;
+ public byte z;
}
diff --git a/graphics/java/android/renderscript/Vector4f.java b/graphics/java/android/renderscript/Byte4.java
index fabd959..a5bfc61 100644
--- a/graphics/java/android/renderscript/Vector4f.java
+++ b/graphics/java/android/renderscript/Byte4.java
@@ -24,14 +24,14 @@ import android.util.Log;
* @hide
*
**/
-public class Vector4f {
- public Vector4f() {
+public class Byte4 {
+ public Byte4() {
}
- public float x;
- public float y;
- public float z;
- public float w;
+ 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..7e89a56 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -17,15 +17,36 @@
package android.renderscript;
import java.lang.reflect.Field;
+import android.util.Log;
/**
* @hide
*
+ * Element is the basic data type of RenderScript. An element can be of 2
+ * forms. Basic elements contain a single component of data. This can be of
+ * any of the legal RS types. Examples of basic element types.
+ * Single float value
+ * 4 element float vector
+ * single RGB-565 color
+ * single unsigned int 16
+ *
+ * Complex elements will contain a list of sub-elements and names. This in
+ * effect represents a structure of data. The fields can be accessed by name
+ * from a script or shader. The memory layout is defined and ordered. Data
+ * alignment is determinied by the most basic primitive type. i.e. a float4
+ * vector will be alligned to sizeof(float) and not sizeof(float4). The
+ * ordering of elements in memory will be the order in which they were added
+ * with each component aligned as necessary. No re-ordering will be done.
+ *
+ * The primary source of elements will be from scripts. A script that exports a
+ * bind point for a data structure will generate a RS element to represent the
+ * data exported by the script.
**/
public class Element extends BaseObj {
int mSize;
Element[] mElements;
String[] mElementNames;
+ int[] mArraySizes;
DataType mType;
DataKind mKind;
@@ -34,33 +55,54 @@ public class Element extends BaseObj {
int getSizeBytes() {return mSize;}
+
+ /**
+ * DataType represents the basic type information for a basic element. The
+ * naming convention follows. For numeric types its FLOAT, SIGNED, UNSIGNED
+ * followed by the _BITS where BITS is the size of the data. BOOLEAN is a
+ * true / false (1,0) represented in an 8 bit container. The UNSIGNED
+ * variants with multiple bit definitions are for packed graphical data
+ * formats and represents vectors with per vector member sizes which are
+ * treated as a single unit for packing and alignment purposes.
+ *
+ * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+ * as 32 bits for alignment purposes.
+ *
+ * RS_* objects. 32 bit opaque handles.
+ */
public enum DataType {
//FLOAT_16 (1, 2),
FLOAT_32 (2, 4),
- //FLOAT_64 (3, 8),
+ FLOAT_64 (3, 8),
SIGNED_8 (4, 1),
SIGNED_16 (5, 2),
SIGNED_32 (6, 4),
- //SIGNED_64 (7, 8),
+ SIGNED_64 (7, 8),
UNSIGNED_8 (8, 1),
UNSIGNED_16 (9, 2),
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);
+ UNSIGNED_64 (11, 8),
+
+ BOOLEAN(12, 1),
+
+ UNSIGNED_5_6_5 (13, 2),
+ UNSIGNED_5_5_5_1 (14, 2),
+ UNSIGNED_4_4_4_4 (15, 2),
+
+ MATRIX_4X4 (16, 64),
+ MATRIX_3X3 (17, 36),
+ MATRIX_2X2 (18, 16),
+
+ RS_ELEMENT (1000, 4),
+ RS_TYPE (1001, 4),
+ RS_ALLOCATION (1002, 4),
+ RS_SAMPLER (1003, 4),
+ RS_SCRIPT (1004, 4),
+ RS_MESH (1005, 4),
+ RS_PROGRAM_FRAGMENT (1006, 4),
+ RS_PROGRAM_VERTEX (1007, 4),
+ RS_PROGRAM_RASTER (1008, 4),
+ RS_PROGRAM_STORE (1009, 4);
int mID;
int mSize;
@@ -70,14 +112,14 @@ public class Element extends BaseObj {
}
}
+ /**
+ * The special interpretation of the data if required. This is primarly
+ * useful for graphical data. USER indicates no special interpretation is
+ * expected. PIXEL is used in conjunction with the standard data types for
+ * representing texture formats.
+ */
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 +133,193 @@ 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);
+ /**
+ * Return if a element is too complex for use as a data source for a Mesh or
+ * a Program.
+ *
+ * @return boolean
+ */
+ public boolean isComplex() {
+ if (mElements == null) {
+ return false;
+ }
+ for (int ct=0; ct < mElements.length; ct++) {
+ if (mElements[ct].mElements != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single Boolean.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ public static Element BOOLEAN(RenderScript rs) {
+ if(rs.mElement_BOOLEAN == null) {
+ rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
+ }
+ return rs.mElement_BOOLEAN;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single UNSIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ public static Element U8(RenderScript rs) {
+ if(rs.mElement_U8 == null) {
+ rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
+ }
+ return rs.mElement_U8;
+ }
+
+ /**
+ * Utility function for returning an Element containing a single SIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
+ 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_USER_U8;
+ return rs.mElement_U32;
}
- 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 I32(RenderScript rs) {
+ if(rs.mElement_I32 == null) {
+ rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
}
- return rs.mElement_USER_I8;
+ return rs.mElement_I32;
}
- 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 U64(RenderScript rs) {
+ if(rs.mElement_U64 == null) {
+ rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
}
- return rs.mElement_USER_U32;
+ return rs.mElement_U64;
}
- 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 I64(RenderScript rs) {
+ if(rs.mElement_I64 == null) {
+ rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
}
- return rs.mElement_USER_I32;
+ return rs.mElement_I64;
}
- 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 F32(RenderScript rs) {
+ if(rs.mElement_F32 == null) {
+ rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
}
- return rs.mElement_USER_F32;
+ return rs.mElement_F32;
}
+ public static Element F64(RenderScript rs) {
+ if(rs.mElement_F64 == null) {
+ rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
+ }
+ return rs.mElement_F64;
+ }
+
+ 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_MESH;
+ }
+
+ 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_PROGRAM_FRAGMENT;
+ }
+
+ 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_PROGRAM_VERTEX;
+ }
+
+ 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_PROGRAM_RASTER;
+ }
+
+ 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_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,192 +362,192 @@ 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);
+ 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_INDEX_16;
+ return rs.mElement_FLOAT_2;
}
- 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_3(RenderScript rs) {
+ if(rs.mElement_FLOAT_3 == null) {
+ rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
}
- return rs.mElement_POSITION_2;
+ return rs.mElement_FLOAT_3;
}
- 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_4(RenderScript rs) {
+ if(rs.mElement_FLOAT_4 == null) {
+ rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
}
- return rs.mElement_POSITION_3;
+ return rs.mElement_FLOAT_4;
}
- 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 U8_4(RenderScript rs) {
+ if(rs.mElement_UCHAR_4 == null) {
+ rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
}
- return rs.mElement_TEXTURE_2;
+ return rs.mElement_UCHAR_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 MATRIX_4X4(RenderScript rs) {
+ if(rs.mElement_MATRIX_4X4 == null) {
+ rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
}
- return rs.mElement_NORMAL_3;
+ return rs.mElement_MATRIX_4X4;
+ }
+ public static Element MATRIX4X4(RenderScript rs) {
+ return MATRIX_4X4(rs);
}
- 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);
+ public static Element MATRIX_3X3(RenderScript rs) {
+ if(rs.mElement_MATRIX_3X3 == null) {
+ rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
}
- return rs.mElement_COLOR_U8_4;
+ return rs.mElement_MATRIX_4X4;
}
- 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);
+ public static Element MATRIX_2X2(RenderScript rs) {
+ if(rs.mElement_MATRIX_2X2 == null) {
+ rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
}
- return rs.mElement_COLOR_F32_4;
+ return rs.mElement_MATRIX_2X2;
}
- Element(RenderScript rs, Element[] e, String[] n) {
- super(rs);
+ Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) {
+ super(id, rs);
mSize = 0;
mElements = e;
mElementNames = n;
- int[] ids = new int[mElements.length];
+ mArraySizes = as;
for (int ct = 0; ct < mElements.length; ct++ ) {
- mSize += mElements[ct].mSize;
- ids[ct] = mElements[ct].mID;
+ mSize += mElements[ct].mSize * mArraySizes[ct];
}
- mID = rs.nElementCreate2(ids, mElementNames);
}
- Element(RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
- super(rs);
+ Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
+ super(id, rs);
mSize = dt.mSize * size;
mType = dt;
mKind = dk;
mNormalized = norm;
mVectorSize = size;
- mID = rs.nElementCreate(dt.mID, dk.mID, norm, size);
- }
-
- public void destroy() throws IllegalStateException {
- super.destroy();
- }
-
- 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");
- }
- }
- return b.create();
}
-
- /////////////////////////////////////////
- public static Element createUser(RenderScript rs, DataType dt) {
- return new Element(rs, dt, DataKind.USER, false, 1);
+ Element(int id, RenderScript rs) {
+ super(id, rs);
}
- public static Element createVector(RenderScript rs, DataType dt, int size) {
- if (size < 2 || size > 4) {
- throw new IllegalArgumentException("Bad size");
- }
- return new Element(rs, dt, DataKind.USER, false, size);
- }
+ @Override
+ void updateFromNative() {
+ super.updateFromNative();
- public static Element createIndex(RenderScript rs) {
- return new Element(rs, DataType.UNSIGNED_16, DataKind.INDEX, false, 1);
- }
+ // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
+ int[] dataBuffer = new int[5];
+ mRS.nElementGetNativeData(getID(), dataBuffer);
- 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");
+ mNormalized = dataBuffer[2] == 1 ? true : false;
+ mVectorSize = dataBuffer[3];
+ mSize = 0;
+ for (DataType dt: DataType.values()) {
+ if(dt.mID == dataBuffer[0]){
+ mType = dt;
+ mSize = mType.mSize * mVectorSize;
+ }
}
-
- 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");
+ for (DataKind dk: DataKind.values()) {
+ if(dk.mID == dataBuffer[1]){
+ mKind = dk;
+ }
}
- 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");
+ int numSubElements = dataBuffer[4];
+ if(numSubElements > 0) {
+ mElements = new Element[numSubElements];
+ mElementNames = new String[numSubElements];
+
+ int[] subElementIds = new int[numSubElements];
+ mRS.nElementGetSubElements(getID(), subElementIds, mElementNames);
+ for(int i = 0; i < numSubElements; i ++) {
+ mElements[i] = new Element(subElementIds[i], mRS);
+ mElements[i].updateFromNative();
+ mSize += mElements[i].mSize;
+ }
}
+ }
+
+ /**
+ * Create a custom Element of the specified DataType. The DataKind will be
+ * set to USER and the vector size to 1 indicating non-vector.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @return Element
+ */
+ static Element createUser(RenderScript rs, DataType dt) {
+ DataKind dk = DataKind.USER;
boolean norm = false;
- if (dk == DataKind.COLOR && dt == DataType.UNSIGNED_8) {
- norm = true;
- }
+ int vecSize = 1;
+ int id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
+ return new Element(id, rs, dt, dk, norm, vecSize);
+ }
- return new Element(rs, dt, dk, norm, size);
+ /**
+ * Create a custom vector element of the specified DataType and vector size.
+ * DataKind will be set to USER.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @param size Vector size for the new Element. Range 2-4 inclusive
+ * supported.
+ *
+ * @return Element
+ */
+ public static Element createVector(RenderScript rs, DataType dt, int size) {
+ if (size < 2 || size > 4) {
+ throw new RSIllegalArgumentException("Vector size out of range 2-4.");
+ }
+ DataKind dk = DataKind.USER;
+ boolean norm = false;
+ int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+ return new Element(id, rs, dt, dk, norm, size);
}
+ /**
+ * Create a new pixel Element type. A matching DataType and DataKind must
+ * be provided. The DataType and DataKind must contain the same number of
+ * components. Vector size will be set to 1.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @param dk The DataKind to specify the mapping of each component in the
+ * DataType.
+ *
+ * @return Element
+ */
public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
if (!(dk == DataKind.PIXEL_L ||
dk == DataKind.PIXEL_A ||
dk == DataKind.PIXEL_LA ||
dk == DataKind.PIXEL_RGB ||
dk == DataKind.PIXEL_RGBA)) {
- throw new IllegalArgumentException("Unsupported DataKind");
+ throw new RSIllegalArgumentException("Unsupported DataKind");
}
if (!(dt == DataType.UNSIGNED_8 ||
dt == DataType.UNSIGNED_5_6_5 ||
dt == DataType.UNSIGNED_4_4_4_4 ||
dt == DataType.UNSIGNED_5_5_5_1)) {
- throw new IllegalArgumentException("Unsupported DataType");
+ throw new RSIllegalArgumentException("Unsupported DataType");
}
if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
- throw new IllegalArgumentException("Bad kind and type combo");
+ throw new RSIllegalArgumentException("Bad kind and type combo");
}
if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
- throw new IllegalArgumentException("Bad kind and type combo");
+ throw new RSIllegalArgumentException("Bad kind and type combo");
}
if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
- throw new IllegalArgumentException("Bad kind and type combo");
+ throw new RSIllegalArgumentException("Bad kind and type combo");
}
int size = 1;
@@ -367,43 +561,97 @@ public class Element extends BaseObj {
size = 4;
}
- return new Element(rs, dt, dk, true, size);
+ boolean norm = true;
+ int id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+ return new Element(id, rs, dt, dk, norm, size);
}
+ /**
+ * Builder class for producing complex elements with matching field and name
+ * pairs. The builder starts empty. The order in which elements are added
+ * is retained for the layout in memory.
+ *
+ */
public static class Builder {
RenderScript mRS;
Element[] mElements;
String[] mElementNames;
+ int[] mArraySizes;
int mCount;
+ /**
+ * Create a builder object.
+ *
+ * @param rs
+ */
public Builder(RenderScript rs) {
mRS = rs;
mCount = 0;
mElements = new Element[8];
mElementNames = new String[8];
- }
-
- public void add(Element element, String name) {
+ mArraySizes = new int[8];
+ }
+
+ /**
+ * Add an array of elements to this element.
+ *
+ * @param element
+ * @param name
+ * @param arraySize
+ */
+ public Builder add(Element element, String name, int arraySize) {
+ if (arraySize < 1) {
+ throw new RSIllegalArgumentException("Array size cannot be less than 1.");
+ }
if(mCount == mElements.length) {
Element[] e = new Element[mCount + 8];
String[] s = new String[mCount + 8];
+ int[] as = new int[mCount + 8];
System.arraycopy(mElements, 0, e, 0, mCount);
System.arraycopy(mElementNames, 0, s, 0, mCount);
+ System.arraycopy(mArraySizes, 0, as, 0, mCount);
mElements = e;
mElementNames = s;
+ mArraySizes = as;
}
mElements[mCount] = element;
mElementNames[mCount] = name;
+ mArraySizes[mCount] = arraySize;
mCount++;
+ return this;
+ }
+
+ /**
+ * Add a single element to this Element.
+ *
+ * @param element
+ * @param name
+ */
+ public Builder add(Element element, String name) {
+ return add(element, name, 1);
}
+ /**
+ * Create the element from this builder.
+ *
+ *
+ * @return Element
+ */
public Element create() {
mRS.validate();
Element[] ein = new Element[mCount];
String[] sin = new String[mCount];
+ int[] asin = new int[mCount];
java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
- return new Element(mRS, ein, sin);
+ java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
+
+ int[] ids = new int[ein.length];
+ for (int ct = 0; ct < ein.length; ct++ ) {
+ ids[ct] = ein[ct].getID();
+ }
+ int id = mRS.nElementCreate2(ids, sin, asin);
+ return new Element(id, mRS, ein, sin, asin);
}
}
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index b26e47d..ff3e22b 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,15 +74,17 @@ public class FieldPacker {
mData[mPos++] = (byte)((v >> 56) & 0xff);
}
- void addU8(short v) {
+ public void addU8(short v) {
if ((v < 0) || (v > 0xff)) {
+ android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
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)) {
+ android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
throw new IllegalArgumentException("Saving value out of range for type");
}
align(2);
@@ -83,8 +92,9 @@ public class FieldPacker {
mData[mPos++] = (byte)(v >> 8);
}
- void addU32(long v) {
- if ((v < 0) || (v > 0xffffffff)) {
+ public void addU32(long v) {
+ if ((v < 0) || (v > 0xffffffffL)) {
+ android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
throw new IllegalArgumentException("Saving value out of range for type");
}
align(4);
@@ -94,8 +104,9 @@ public class FieldPacker {
mData[mPos++] = (byte)((v >> 24) & 0xff);
}
- void addU64(long v) {
+ public void addU64(long v) {
if (v < 0) {
+ android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
throw new IllegalArgumentException("Saving value out of range for type");
}
align(8);
@@ -109,15 +120,157 @@ 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(double 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 addObj(Matrix4f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public void addObj(Matrix3f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ public void addObj(Matrix2f v) {
+ for (int i=0; i < v.mMat.length; i++) {
+ addF32(v.mMat[i]);
+ }
+ }
+
+ 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..af85d8e
--- /dev/null
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -0,0 +1,208 @@
+/*
+ * 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,
+ 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 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;
+ InputStream mInputStream;
+
+ FileA3D(int id, RenderScript rs, InputStream stream) {
+ super(id, rs);
+ mInputStream = stream;
+ }
+
+ private void initEntries() {
+ int numFileEntries = mRS.nFileA3DGetNumIndexEntries(getID());
+ if(numFileEntries <= 0) {
+ return;
+ }
+
+ mFileEntries = new IndexEntry[numFileEntries];
+ int[] ids = new int[numFileEntries];
+ String[] names = new String[numFileEntries];
+
+ mRS.nFileA3DGetIndexEntries(getID(), numFileEntries, ids, names);
+
+ for(int i = 0; i < numFileEntries; i ++) {
+ mFileEntries[i] = new IndexEntry(mRS, i, getID(), 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, is);
+ fa3d.initEntries();
+ return fa3d;
+
+ } catch (Exception e) {
+ // Ignore
+ }
+
+ return null;
+ }
+}
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
new file mode 100644
index 0000000..889bf7b
--- /dev/null
+++ b/graphics/java/android/renderscript/Float2.java
@@ -0,0 +1,42 @@
+/*
+ * 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 Float2 {
+ public Float2() {
+ }
+
+ public Float2(float initX, float initY) {
+ x = initX;
+ y = initY;
+ }
+
+ public float x;
+ public float y;
+}
+
+
+
+
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
new file mode 100644
index 0000000..ebe140d
--- /dev/null
+++ b/graphics/java/android/renderscript/Float3.java
@@ -0,0 +1,43 @@
+/*
+ * 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 Float3 {
+ public Float3() {
+ }
+ public Float3(float initX, float initY, float initZ) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ }
+
+ public float x;
+ public float y;
+ public float z;
+}
+
+
+
+
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
new file mode 100644
index 0000000..847732f
--- /dev/null
+++ b/graphics/java/android/renderscript/Float4.java
@@ -0,0 +1,45 @@
+/*
+ * 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 Float4 {
+ public Float4() {
+ }
+
+ public Float4(float initX, float initY, float initZ, float initW) {
+ x = initX;
+ y = initY;
+ z = initZ;
+ w = initW;
+ }
+
+ public float x;
+ public float y;
+ public float z;
+ public float w;
+}
+
+
+
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
new file mode 100644
index 0000000..de25014
--- /dev/null
+++ b/graphics/java/android/renderscript/Font.java
@@ -0,0 +1,165 @@
+/*
+ * 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 java.util.Map;
+import java.util.HashMap;
+
+import android.content.res.Resources;
+import android.content.res.AssetManager;
+import android.util.Log;
+import android.util.TypedValue;
+
+/**
+ * @hide
+ *
+ **/
+public class Font extends BaseObj {
+
+ //These help us create a font by family name
+ private static final String[] sSansNames = {
+ "sans-serif", "arial", "helvetica", "tahoma", "verdana"
+ };
+
+ private static final String[] sSerifNames = {
+ "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
+ "goudy", "fantasy", "cursive", "ITC Stone Serif"
+ };
+
+ private static final String[] sMonoNames = {
+ "monospace", "courier", "courier new", "monaco"
+ };
+
+ private static class FontFamily {
+ String[] mNames;
+ String mNormalFileName;
+ String mBoldFileName;
+ String mItalicFileName;
+ String mBoldItalicFileName;
+ }
+
+ private static Map<String, FontFamily> sFontFamilyMap;
+
+ public enum Style {
+ NORMAL,
+ BOLD,
+ ITALIC,
+ BOLD_ITALIC;
+ }
+
+ private static void addFamilyToMap(FontFamily family) {
+ for(int i = 0; i < family.mNames.length; i ++) {
+ sFontFamilyMap.put(family.mNames[i], family);
+ }
+ }
+
+ private static void initFontFamilyMap() {
+ sFontFamilyMap = new HashMap<String, FontFamily>();
+
+ FontFamily sansFamily = new FontFamily();
+ sansFamily.mNames = sSansNames;
+ sansFamily.mNormalFileName = "DroidSans.ttf";
+ sansFamily.mBoldFileName = "DroidSans-Bold.ttf";
+ sansFamily.mItalicFileName = "DroidSans.ttf";
+ sansFamily.mBoldItalicFileName = "DroidSans-Bold.ttf";
+ addFamilyToMap(sansFamily);
+
+ FontFamily serifFamily = new FontFamily();
+ serifFamily.mNames = sSerifNames;
+ serifFamily.mNormalFileName = "DroidSerif-Regular.ttf";
+ serifFamily.mBoldFileName = "DroidSerif-Bold.ttf";
+ serifFamily.mItalicFileName = "DroidSerif-Italic.ttf";
+ serifFamily.mBoldItalicFileName = "DroidSerif-BoldItalic.ttf";
+ addFamilyToMap(serifFamily);
+
+ FontFamily monoFamily = new FontFamily();
+ monoFamily.mNames = sMonoNames;
+ monoFamily.mNormalFileName = "DroidSansMono.ttf";
+ monoFamily.mBoldFileName = "DroidSansMono.ttf";
+ monoFamily.mItalicFileName = "DroidSansMono.ttf";
+ monoFamily.mBoldItalicFileName = "DroidSansMono.ttf";
+ addFamilyToMap(monoFamily);
+ }
+
+ static {
+ initFontFamilyMap();
+ }
+
+ static String getFontFileName(String familyName, Style style) {
+ FontFamily family = sFontFamilyMap.get(familyName);
+ if(family != null) {
+ switch(style) {
+ case NORMAL:
+ return family.mNormalFileName;
+ case BOLD:
+ return family.mBoldFileName;
+ case ITALIC:
+ return family.mItalicFileName;
+ case BOLD_ITALIC:
+ return family.mBoldItalicFileName;
+ }
+ }
+ // Fallback if we could not find the desired family
+ return "DroidSans.ttf";
+ }
+
+ Font(int id, RenderScript rs) {
+ super(id, rs);
+ }
+
+ /**
+ * Takes a specific file name as an argument
+ */
+ 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("Failed loading a font");
+ }
+ Font rsFont = new Font(fontId, rs);
+
+ return rsFont;
+
+ } catch (Exception e) {
+ // Ignore
+ }
+
+ return null;
+ }
+
+ /**
+ * Accepts one of the following family names as an argument
+ * and will attemp to produce the best match with a system font
+ * "sans-serif" "arial" "helvetica" "tahoma" "verdana"
+ * "serif" "times" "times new roman" "palatino" "georgia" "baskerville"
+ * "goudy" "fantasy" "cursive" "ITC Stone Serif"
+ * "monospace" "courier" "courier new" "monaco"
+ * Returns default font if no match could be found
+ */
+ static public Font createFromFamily(RenderScript rs, Resources res, String familyName, Style fontStyle, int size)
+ throws IllegalArgumentException {
+ String fileName = getFontFileName(familyName, fontStyle);
+ return create(rs, res, fileName, size);
+ }
+}
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/Light.java b/graphics/java/android/renderscript/Light.java
deleted file mode 100644
index aab656f..0000000
--- a/graphics/java/android/renderscript/Light.java
+++ /dev/null
@@ -1,76 +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 Light extends BaseObj {
- Light(int id, RenderScript rs) {
- super(rs);
- mID = id;
- }
-
- public void setColor(float r, float g, float b) {
- mRS.validate();
- mRS.nLightSetColor(mID, r, g, b);
- }
-
- public void setPosition(float x, float y, float z) {
- mRS.validate();
- mRS.nLightSetPosition(mID, x, y, z);
- }
-
- public static class Builder {
- RenderScript mRS;
- boolean mIsMono;
- boolean mIsLocal;
-
- public Builder(RenderScript rs) {
- mRS = rs;
- mIsMono = false;
- mIsLocal = false;
- }
-
- public void lightSetIsMono(boolean isMono) {
- mIsMono = isMono;
- }
-
- public void lightSetIsLocal(boolean isLocal) {
- mIsLocal = isLocal;
- }
-
- static synchronized Light internalCreate(RenderScript rs, Builder b) {
- rs.nSamplerBegin();
- rs.nLightSetIsMono(b.mIsMono);
- rs.nLightSetIsLocal(b.mIsLocal);
- int id = rs.nLightCreate();
- return new Light(id, rs);
- }
-
- public Light create() {
- mRS.validate();
- return internalCreate(mRS, this);
- }
- }
-
-}
-
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..9176bc8
--- /dev/null
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -0,0 +1,481 @@
+/*
+ * 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(id, rs);
+ }
+
+ 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() {
+ super.updateFromNative();
+ int vtxCount = mRS.nMeshGetVertexBufferCount(getID());
+ int idxCount = mRS.nMeshGetIndexCount(getID());
+
+ int[] vtxIDs = new int[vtxCount];
+ int[] idxIDs = new int[idxCount];
+ int[] primitives = new int[idxCount];
+
+ mRS.nMeshGetVertices(getID(), vtxIDs, vtxCount);
+ mRS.nMeshGetIndices(getID(), idxIDs, primitives, idxCount);
+
+ 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.setX(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;
+ }
+ rs.nMeshInitVertexAttribs(id);
+
+ 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.getID(), ct);
+ newMesh.mVertexBuffers[ct] = entry.a;
+ }
+ rs.nMeshInitVertexAttribs(id);
+
+ 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).copyFrom(mVtxData);
+ if(uploadToBufferObject) {
+ sm.getVertexAllocation(0).uploadToBufferObject();
+ }
+
+ sm.getIndexAllocation(0).copyFrom(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..c3536c3 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -17,6 +17,11 @@
package android.renderscript;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import android.content.res.Resources;
import android.util.Config;
import android.util.Log;
@@ -31,39 +36,75 @@ public class Program extends BaseObj {
public static final int MAX_CONSTANT = 8;
public static final int MAX_TEXTURE = 8;
+ public enum TextureType {
+ TEXTURE_2D (0),
+ TEXTURE_CUBE (1);
+
+ int mID;
+ TextureType(int id) {
+ mID = id;
+ }
+ }
+
+ enum ProgramParam {
+ INPUT (0),
+ OUTPUT (1),
+ CONSTANT (2),
+ TEXTURE_TYPE (3);
+
+ int mID;
+ ProgramParam(int id) {
+ mID = id;
+ }
+ };
+
Element mInputs[];
Element mOutputs[];
Type mConstants[];
+ TextureType mTextures[];
int mTextureCount;
String mShader;
Program(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
public void bindConstants(Allocation a, int slot) {
- mRS.nProgramBindConstants(mID, slot, a.mID);
+ if (slot < 0 || slot >= mConstants.length) {
+ throw new IllegalArgumentException("Slot ID out of range.");
+ }
+ if (a != null &&
+ a.getType().getID() != mConstants[slot].getID()) {
+ throw new IllegalArgumentException("Allocation type does not match slot type.");
+ }
+ int id = a != null ? a.getID() : 0;
+ mRS.nProgramBindConstants(getID(), slot, id);
}
public void bindTexture(Allocation va, int slot)
throws IllegalArgumentException {
mRS.validate();
- if((slot < 0) || (slot >= mTextureCount)) {
+ if ((slot < 0) || (slot >= mTextureCount)) {
throw new IllegalArgumentException("Slot ID out of range.");
}
+ if (va != null && va.getType().hasFaces() &&
+ mTextures[slot] != TextureType.TEXTURE_CUBE) {
+ throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
+ }
- mRS.nProgramBindTexture(mID, slot, va.mID);
+ int id = va != null ? va.getID() : 0;
+ mRS.nProgramBindTexture(getID(), slot, id);
}
public void bindSampler(Sampler vs, int slot)
throws IllegalArgumentException {
mRS.validate();
- if((slot < 0) || (slot >= mTextureCount)) {
+ if ((slot < 0) || (slot >= mTextureCount)) {
throw new IllegalArgumentException("Slot ID out of range.");
}
- mRS.nProgramBindSampler(mID, slot, vs.mID);
+ int id = vs != null ? vs.getID() : 0;
+ mRS.nProgramBindSampler(getID(), slot, id);
}
@@ -73,6 +114,7 @@ public class Program extends BaseObj {
Element mOutputs[];
Type mConstants[];
Type mTextures[];
+ TextureType mTextureTypes[];
int mInputCount;
int mOutputCount;
int mConstantCount;
@@ -89,16 +131,59 @@ public class Program extends BaseObj {
mOutputCount = 0;
mConstantCount = 0;
mTextureCount = 0;
+ mTextureTypes = new TextureType[MAX_TEXTURE];
}
- public void setShader(String s) {
+ public BaseProgramBuilder setShader(String s) {
mShader = s;
+ return this;
+ }
+
+ public BaseProgramBuilder setShader(Resources resources, int resourceID) {
+ byte[] str;
+ int strLength;
+ InputStream is = resources.openRawResource(resourceID);
+ try {
+ try {
+ str = new byte[1024];
+ strLength = 0;
+ while(true) {
+ int bytesLeft = str.length - strLength;
+ if (bytesLeft == 0) {
+ byte[] buf2 = new byte[str.length * 2];
+ System.arraycopy(str, 0, buf2, 0, str.length);
+ str = buf2;
+ bytesLeft = str.length - strLength;
+ }
+ int bytesRead = is.read(str, strLength, bytesLeft);
+ if (bytesRead <= 0) {
+ break;
+ }
+ strLength += bytesRead;
+ }
+ } finally {
+ is.close();
+ }
+ } catch(IOException e) {
+ throw new Resources.NotFoundException();
+ }
+
+ try {
+ mShader = new String(str, 0, strLength, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ Log.e("Renderscript shader creation", "Could not decode shader string");
+ }
+
+ return this;
}
public void addInput(Element e) throws IllegalStateException {
// Should check for consistant and non-conflicting names...
if(mInputCount >= MAX_INPUT) {
- throw new IllegalArgumentException("Max input count exceeded.");
+ throw new RSIllegalArgumentException("Max input count exceeded.");
+ }
+ if (e.isComplex()) {
+ throw new RSIllegalArgumentException("Complex elements not allowed.");
}
mInputs[mInputCount++] = e;
}
@@ -106,26 +191,51 @@ public class Program extends BaseObj {
public void addOutput(Element e) throws IllegalStateException {
// Should check for consistant and non-conflicting names...
if(mOutputCount >= MAX_OUTPUT) {
- throw new IllegalArgumentException("Max output count exceeded.");
+ throw new RSIllegalArgumentException("Max output count exceeded.");
+ }
+ if (e.isComplex()) {
+ throw new RSIllegalArgumentException("Complex elements not allowed.");
}
mOutputs[mOutputCount++] = e;
}
+ void resetConstant() {
+ mConstantCount = 0;
+ for(int i = 0; i < MAX_CONSTANT; i ++) {
+ mConstants[i] = null;
+ }
+ }
+
public int addConstant(Type t) throws IllegalStateException {
// Should check for consistant and non-conflicting names...
if(mConstantCount >= MAX_CONSTANT) {
- throw new IllegalArgumentException("Max input count exceeded.");
+ throw new RSIllegalArgumentException("Max input count exceeded.");
+ }
+ if (t.getElement().isComplex()) {
+ throw new RSIllegalArgumentException("Complex elements not allowed.");
}
mConstants[mConstantCount] = t;
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) {
+ if(count >= MAX_TEXTURE) {
throw new IllegalArgumentException("Max texture count exceeded.");
}
mTextureCount = count;
+ for (int i = 0; i < mTextureCount; i ++) {
+ mTextureTypes[i] = TextureType.TEXTURE_2D;
+ }
+ return this;
+ }
+
+ public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
+ if(mTextureCount >= MAX_TEXTURE) {
+ throw new IllegalArgumentException("Max texture count exceeded.");
+ }
+ mTextureTypes[mTextureCount ++] = texType;
+ return this;
}
protected void initProgram(Program p) {
@@ -136,6 +246,8 @@ public class Program extends BaseObj {
p.mConstants = new Type[mConstantCount];
System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
p.mTextureCount = mTextureCount;
+ p.mTextures = new TextureType[mTextureCount];
+ System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
}
}
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 5e04f0c..074c393 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -37,35 +37,38 @@ public class ProgramFragment extends Program {
public ProgramFragment create() {
mRS.validate();
- int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + 1) * 2];
+ int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
int idx = 0;
for (int i=0; i < mInputCount; i++) {
- tmp[idx++] = 0;
- tmp[idx++] = mInputs[i].mID;
+ tmp[idx++] = ProgramParam.INPUT.mID;
+ tmp[idx++] = mInputs[i].getID();
}
for (int i=0; i < mOutputCount; i++) {
- tmp[idx++] = 1;
- tmp[idx++] = mOutputs[i].mID;
+ tmp[idx++] = ProgramParam.OUTPUT.mID;
+ tmp[idx++] = mOutputs[i].getID();
}
for (int i=0; i < mConstantCount; i++) {
- tmp[idx++] = 2;
- tmp[idx++] = mConstants[i].mID;
+ tmp[idx++] = ProgramParam.CONSTANT.mID;
+ tmp[idx++] = mConstants[i].getID();
+ }
+ for (int i=0; i < mTextureCount; i++) {
+ tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
+ tmp[idx++] = mTextureTypes[i].mID;
}
- tmp[idx++] = 3;
- tmp[idx++] = mTextureCount;
- int id = mRS.nProgramFragmentCreate2(mShader, tmp);
+ int id = mRS.nProgramFragmentCreate(mShader, tmp);
ProgramFragment pf = new ProgramFragment(id, mRS);
initProgram(pf);
return pf;
}
}
- public static class Builder {
+ public static class Builder extends ShaderBuilder {
public static final int MAX_TEXTURE = 2;
- RenderScript mRS;
+ int mNumTextures;
boolean mPointSpriteEnable;
+ boolean mVaryingColorEnable;
public enum EnvMode {
REPLACE (1),
@@ -100,39 +103,126 @@ public class ProgramFragment extends Program {
}
Slot[] mSlots;
+ private void buildShaderString() {
+ mShader = "//rs_shader_internal\n";
+ mShader += "varying lowp vec4 varColor;\n";
+ mShader += "varying vec2 varTex0;\n";
+
+ mShader += "void main() {\n";
+ if (mVaryingColorEnable) {
+ mShader += " lowp vec4 col = varColor;\n";
+ } else {
+ mShader += " lowp vec4 col = UNI_Color;\n";
+ }
+
+ if (mNumTextures != 0) {
+ if (mPointSpriteEnable) {
+ mShader += " vec2 t0 = gl_PointCoord;\n";
+ } else {
+ mShader += " vec2 t0 = varTex0.xy;\n";
+ }
+ }
+
+ for(int i = 0; i < mNumTextures; i ++) {
+ switch(mSlots[i].env) {
+ case REPLACE:
+ switch (mSlots[i].format) {
+ case ALPHA:
+ mShader += " col.a = texture2D(UNI_Tex0, t0).a;\n";
+ break;
+ case LUMINANCE_ALPHA:
+ mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
+ break;
+ case RGB:
+ mShader += " col.rgb = texture2D(UNI_Tex0, t0).rgb;\n";
+ break;
+ case RGBA:
+ mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
+ break;
+ }
+ break;
+ case MODULATE:
+ switch (mSlots[i].format) {
+ case ALPHA:
+ mShader += " col.a *= texture2D(UNI_Tex0, t0).a;\n";
+ break;
+ case LUMINANCE_ALPHA:
+ mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
+ break;
+ case RGB:
+ mShader += " col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n";
+ break;
+ case RGBA:
+ mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
+ break;
+ }
+ break;
+ case DECAL:
+ mShader += " col = texture2D(UNI_Tex0, t0);\n";
+ break;
+ }
+ }
+
+ mShader += " gl_FragColor = col;\n";
+ mShader += "}\n";
+ }
+
public Builder(RenderScript rs) {
+ super(rs);
mRS = rs;
mSlots = new Slot[MAX_TEXTURE];
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;
}
+ @Override
public ProgramFragment create() {
- mRS.validate();
- int[] tmp = new int[MAX_TEXTURE * 2 + 1];
- if (mSlots[0] != null) {
- tmp[0] = mSlots[0].env.mID;
- tmp[1] = mSlots[0].format.mID;
+ mNumTextures = 0;
+ for(int i = 0; i < MAX_TEXTURE; i ++) {
+ if(mSlots[i] != null) {
+ mNumTextures ++;
+ }
}
- if (mSlots[1] != null) {
- tmp[2] = mSlots[1].env.mID;
- tmp[3] = mSlots[1].format.mID;
+ resetConstant();
+ buildShaderString();
+ Type constType = null;
+ if (!mVaryingColorEnable) {
+ Element.Builder b = new Element.Builder(mRS);
+ b.add(Element.F32_4(mRS), "Color");
+ Type.Builder typeBuilder = new Type.Builder(mRS, b.create());
+ typeBuilder.setX(1);
+ constType = typeBuilder.create();
+ addConstant(constType);
}
- tmp[4] = mPointSpriteEnable ? 1 : 0;
- int id = mRS.nProgramFragmentCreate(tmp);
- ProgramFragment pf = new ProgramFragment(id, mRS);
+ setTextureCount(mNumTextures);
+
+ ProgramFragment pf = super.create();
pf.mTextureCount = MAX_TEXTURE;
+ if (!mVaryingColorEnable) {
+ Allocation constantData = Allocation.createTyped(mRS,constType);
+ float[] data = new float[4];
+ data[0] = data[1] = data[2] = data[3] = 1.0f;
+ constantData.copyFrom(data);
+ pf.bindConstants(constantData, 0);
+ }
return pf;
}
}
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 56f9bf4..5b55015 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -26,76 +26,113 @@ 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;
+ super(id, rs);
- mPointSize = 1.0f;
mLineWidth = 1.0f;
mPointSmooth = false;
mLineSmooth = false;
mPointSprite = false;
+
+ mCullMode = CullMode.BACK;
}
- public void setLineWidth(float w) {
+ void setLineWidth(float w) {
mRS.validate();
mLineWidth = w;
- mRS.nProgramRasterSetLineWidth(mID, w);
+ mRS.nProgramRasterSetLineWidth(getID(), w);
}
- public void setPointSize(float s) {
+ void setCullMode(CullMode m) {
mRS.validate();
- mPointSize = s;
- mRS.nProgramRasterSetPointSize(mID, s);
+ mCullMode = m;
+ mRS.nProgramRasterSetCullMode(getID(), m.mID);
}
- void internalInit() {
- int inID = 0;
- int outID = 0;
- if (mIn != null) {
- inID = mIn.mID;
+ public static ProgramRaster CULL_BACK(RenderScript rs) {
+ if(rs.mProgramRaster_CULL_BACK == null) {
+ ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+ builder.setCullMode(CullMode.BACK);
+ rs.mProgramRaster_CULL_BACK = builder.create();
}
- if (mOut != null) {
- outID = mOut.mID;
+ return rs.mProgramRaster_CULL_BACK;
+ }
+
+ public static ProgramRaster CULL_FRONT(RenderScript rs) {
+ if(rs.mProgramRaster_CULL_FRONT == null) {
+ ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+ builder.setCullMode(CullMode.FRONT);
+ rs.mProgramRaster_CULL_FRONT = builder.create();
}
- mID = mRS.nProgramRasterCreate(inID, outID, mPointSmooth, mLineSmooth, mPointSprite);
+ return rs.mProgramRaster_CULL_FRONT;
}
+ public static ProgramRaster CULL_NONE(RenderScript rs) {
+ if(rs.mProgramRaster_CULL_NONE == null) {
+ ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
+ builder.setCullMode(CullMode.NONE);
+ rs.mProgramRaster_CULL_NONE = builder.create();
+ }
+ return rs.mProgramRaster_CULL_NONE;
+ }
public static class Builder {
RenderScript mRS;
- ProgramRaster mPR;
+ boolean mPointSprite;
+ boolean mPointSmooth;
+ boolean mLineSmooth;
+ CullMode mCullMode;
- 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;
+ mCullMode = CullMode.BACK;
}
- 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;
}
+ public Builder setCullMode(CullMode m) {
+ mCullMode = m;
+ 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);
+ pr.setCullMode(b.mCullMode);
return pr;
}
@@ -111,3 +148,4 @@ public class ProgramRaster extends BaseObj {
+
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index 69be245..d191b06 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -76,11 +76,143 @@ public class ProgramStore extends BaseObj {
ProgramStore(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
+ public static ProgramStore BLEND_NONE_DEPTH_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_NONE_DEPTH_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_NONE_DEPTH_TEST = builder.create();
+ }
+ return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
+ }
+ public static ProgramStore BLEND_NONE_DEPTH_NO_DEPTH(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH = builder.create();
+ }
+ return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
+ }
+ public static ProgramStore BLEND_NONE_DEPTH_NO_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST = builder.create();
+ }
+ return rs.mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
+ }
+ public static ProgramStore BLEND_NONE_DEPTH_NO_WRITE(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE = builder.create();
+ }
+ return rs.mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
+ }
+
+ public static ProgramStore BLEND_ALPHA_DEPTH_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
+ }
+ public static ProgramStore BLEND_ALPHA_DEPTH_NO_DEPTH(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
+ }
+ public static ProgramStore BLEND_ALPHA_DEPTH_NO_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
+ }
+ public static ProgramStore BLEND_ALPHA_DEPTH_NO_WRITE(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
+ }
+ public static ProgramStore BLEND_ADD_DEPTH_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ADD_DEPTH_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.LESS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_ADD_DEPTH_TEST = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ADD_DEPTH_TEST;
+ }
+ public static ProgramStore BLEND_ADD_DEPTH_NO_DEPTH(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
+ }
+ public static ProgramStore BLEND_ADD_DEPTH_NO_TEST(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(true);
+ rs.mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
+ }
+ public static ProgramStore BLEND_ADD_DEPTH_NO_WRITE(RenderScript rs) {
+ if(rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE == null) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
+ builder.setDitherEnable(false);
+ builder.setDepthMask(false);
+ rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE = builder.create();
+ }
+ return rs.mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
+ }
public static class Builder {
RenderScript mRS;
@@ -110,54 +242,63 @@ public class ProgramStore extends BaseObj {
mColorMaskA = true;
mBlendSrc = BlendSrcFunc.ONE;
mBlendDst = BlendDstFunc.ZERO;
+ }
-
+ public Builder(RenderScript rs) {
+ mRS = rs;
+ mIn = null;
+ mOut = null;
+ mDepthFunc = DepthFunc.ALWAYS;
+ mDepthMask = false;
+ mColorMaskR = true;
+ mColorMaskG = true;
+ mColorMaskB = true;
+ mColorMaskA = true;
+ mBlendSrc = BlendSrcFunc.ONE;
+ mBlendDst = BlendDstFunc.ZERO;
}
- 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) {
- int inID = 0;
- int outID = 0;
- if (b.mIn != null) {
- inID = b.mIn.mID;
- }
- if (b.mOut != null) {
- outID = b.mOut.mID;
- }
- rs.nProgramFragmentStoreBegin(inID, outID);
- rs.nProgramFragmentStoreDepthFunc(b.mDepthFunc.mID);
- rs.nProgramFragmentStoreDepthMask(b.mDepthMask);
- rs.nProgramFragmentStoreColorMask(b.mColorMaskR,
+ rs.nProgramStoreBegin(0, 0);
+ 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..5d41f63 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -17,6 +17,7 @@
package android.renderscript;
+import android.graphics.Matrix;
import android.util.Config;
import android.util.Log;
@@ -38,25 +39,6 @@ public class ProgramVertex extends Program {
bindConstants(va.mAlloc, 0);
}
-
- public static class Builder {
- RenderScript mRS;
- boolean mTextureMatrixEnable;
-
- public Builder(RenderScript rs, Element in, Element out) {
- mRS = rs;
- }
-
- public void setTextureMatrixEnable(boolean enable) {
- mTextureMatrixEnable = enable;
- }
-
- public ProgramVertex create() {
- int id = mRS.nProgramVertexCreate(mTextureMatrixEnable);
- return new ProgramVertex(id, mRS);
- }
- }
-
public static class ShaderBuilder extends BaseProgramBuilder {
public ShaderBuilder(RenderScript rs) {
super(rs);
@@ -64,31 +46,95 @@ public class ProgramVertex extends Program {
public ProgramVertex create() {
mRS.validate();
- int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2];
+ int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
int idx = 0;
for (int i=0; i < mInputCount; i++) {
- tmp[idx++] = 0;
- tmp[idx++] = mInputs[i].mID;
+ tmp[idx++] = ProgramParam.INPUT.mID;
+ tmp[idx++] = mInputs[i].getID();
}
for (int i=0; i < mOutputCount; i++) {
- tmp[idx++] = 1;
- tmp[idx++] = mOutputs[i].mID;
+ tmp[idx++] = ProgramParam.OUTPUT.mID;
+ tmp[idx++] = mOutputs[i].getID();
}
for (int i=0; i < mConstantCount; i++) {
- tmp[idx++] = 2;
- tmp[idx++] = mConstants[i].mID;
+ tmp[idx++] = ProgramParam.CONSTANT.mID;
+ tmp[idx++] = mConstants[i].getID();
+ }
+ for (int i=0; i < mTextureCount; i++) {
+ tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
+ tmp[idx++] = mTextureTypes[i].mID;
}
- tmp[idx++] = 3;
- tmp[idx++] = mTextureCount;
- int id = mRS.nProgramVertexCreate2(mShader, tmp);
+ int id = mRS.nProgramVertexCreate(mShader, tmp);
ProgramVertex pv = new ProgramVertex(id, mRS);
initProgram(pv);
return pv;
}
}
+ public static class Builder extends ShaderBuilder {
+ boolean mTextureMatrixEnable;
+
+ public Builder(RenderScript rs, Element in, Element out) {
+ super(rs);
+ }
+ public Builder(RenderScript rs) {
+ super(rs);
+ }
+
+ public Builder setTextureMatrixEnable(boolean enable) {
+ mTextureMatrixEnable = enable;
+ return this;
+ }
+ static Type getConstantInputType(RenderScript rs) {
+ Element.Builder b = new Element.Builder(rs);
+ b.add(Element.MATRIX4X4(rs), "MV");
+ b.add(Element.MATRIX4X4(rs), "P");
+ b.add(Element.MATRIX4X4(rs), "TexMatrix");
+ b.add(Element.MATRIX4X4(rs), "MVP");
+
+ Type.Builder typeBuilder = new Type.Builder(rs, b.create());
+ typeBuilder.setX(1);
+ return typeBuilder.create();
+ }
+
+ private void buildShaderString() {
+
+ mShader = "//rs_shader_internal\n";
+ mShader += "varying vec4 varColor;\n";
+ mShader += "varying vec2 varTex0;\n";
+
+ mShader += "void main() {\n";
+ mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n";
+ mShader += " gl_PointSize = 1.0;\n";
+
+ mShader += " varColor = ATTRIB_color;\n";
+ if (mTextureMatrixEnable) {
+ mShader += " varTex0 = (UNI_TexMatrix * vec4(ATTRIB_texture0, 0.0, 1.0)).xy;\n";
+ } else {
+ mShader += " varTex0 = ATTRIB_texture0;\n";
+ }
+ mShader += "}\n";
+ }
+
+ @Override
+ public ProgramVertex create() {
+ buildShaderString();
+
+ addConstant(getConstantInputType(mRS));
+
+ Element.Builder b = new Element.Builder(mRS);
+ b.add(Element.F32_4(mRS), "position");
+ b.add(Element.F32_4(mRS), "color");
+ b.add(Element.F32_3(mRS), "normal");
+ b.add(Element.F32_2(mRS), "texture0");
+ addInput(b.create());
+
+ return super.create();
+ }
+ }
+
public static class MatrixAllocation {
@@ -101,16 +147,17 @@ public class ProgramVertex extends Program {
Matrix4f mTexture;
public Allocation mAlloc;
+ private FieldPacker mIOBuffer;
public MatrixAllocation(RenderScript rs) {
- mModel = new Matrix4f();
- mProjection = new Matrix4f();
- mTexture = new Matrix4f();
-
- mAlloc = Allocation.createSized(rs, Element.createUser(rs, Element.DataType.FLOAT_32), 48);
- mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat);
- mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
- mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat);
+ Type constInputType = ProgramVertex.Builder.getConstantInputType(rs);
+ mAlloc = Allocation.createTyped(rs, constInputType);
+ int bufferSize = constInputType.getElement().getSizeBytes()*
+ constInputType.getCount();
+ mIOBuffer = new FieldPacker(bufferSize);
+ loadModelview(new Matrix4f());
+ loadProjection(new Matrix4f());
+ loadTexture(new Matrix4f());
}
public void destroy() {
@@ -118,24 +165,32 @@ public class ProgramVertex extends Program {
mAlloc = null;
}
+ private void addToBuffer(int offset, Matrix4f m) {
+ mIOBuffer.reset(offset);
+ for(int i = 0; i < 16; i ++) {
+ mIOBuffer.addF32(m.mMat[i]);
+ }
+ mAlloc.copyFrom(mIOBuffer.getData());
+ }
+
public void loadModelview(Matrix4f m) {
mModel = m;
- mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat);
+ addToBuffer(MODELVIEW_OFFSET*4, m);
}
public void loadProjection(Matrix4f m) {
mProjection = m;
- mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat);
+ addToBuffer(PROJECTION_OFFSET*4, m);
}
public void loadTexture(Matrix4f m) {
mTexture = m;
- mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat);
+ addToBuffer(TEXTURE_OFFSET*4, m);
}
public void setupOrthoWindow(int w, int h) {
mProjection.loadOrtho(0,w, h,0, -1,1);
- mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ addToBuffer(PROJECTION_OFFSET*4, mProjection);
}
public void setupOrthoNormalized(int w, int h) {
@@ -147,7 +202,7 @@ public class ProgramVertex extends Program {
float aspect = ((float)h) / w;
mProjection.loadOrtho(-1,1, -aspect,aspect, -1,1);
}
- mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ addToBuffer(PROJECTION_OFFSET*4, mProjection);
}
public void setupProjectionNormalized(int w, int h) {
@@ -173,7 +228,7 @@ public class ProgramVertex extends Program {
m1.loadMultiply(m1, m2);
mProjection = m1;
- mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ addToBuffer(PROJECTION_OFFSET*4, mProjection);
}
}
diff --git a/graphics/java/android/renderscript/RSDriverException.java b/graphics/java/android/renderscript/RSDriverException.java
new file mode 100644
index 0000000..61787e6
--- /dev/null
+++ b/graphics/java/android/renderscript/RSDriverException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSDriverException extends RSRuntimeException {
+ public RSDriverException(String string) {
+ super(string);
+ }
+}
+
+
+
diff --git a/graphics/java/android/renderscript/RSIllegalArgumentException.java b/graphics/java/android/renderscript/RSIllegalArgumentException.java
new file mode 100644
index 0000000..8d67a8d
--- /dev/null
+++ b/graphics/java/android/renderscript/RSIllegalArgumentException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 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;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSIllegalArgumentException extends RSRuntimeException {
+ public RSIllegalArgumentException(String string) {
+ super(string);
+ }
+}
+
+
diff --git a/graphics/java/android/renderscript/RSInvalidStateException.java b/graphics/java/android/renderscript/RSInvalidStateException.java
new file mode 100644
index 0000000..53b9479
--- /dev/null
+++ b/graphics/java/android/renderscript/RSInvalidStateException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSInvalidStateException extends RSRuntimeException {
+ public RSInvalidStateException(String string) {
+ super(string);
+ }
+}
+
+
+
diff --git a/graphics/java/android/renderscript/RSRuntimeException.java b/graphics/java/android/renderscript/RSRuntimeException.java
new file mode 100644
index 0000000..4c97937
--- /dev/null
+++ b/graphics/java/android/renderscript/RSRuntimeException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 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;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * Renderscript
+ * @hide
+ */
+public class RSRuntimeException
+ extends java.lang.RuntimeException {
+ public RSRuntimeException(String string) {
+ super(string);
+ }
+}
+
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index f05e84c..0211a4a 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -25,7 +25,6 @@ import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
-import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -70,7 +69,6 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
* not normally called or subclassed by clients of RSSurfaceView.
*/
public void surfaceCreated(SurfaceHolder holder) {
- Log.v(RenderScript.LOG_TAG, "surfaceCreated");
mSurfaceHolder = holder;
}
@@ -80,9 +78,8 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
*/
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return
- Log.v(RenderScript.LOG_TAG, "surfaceDestroyed");
if (mRS != null) {
- mRS.contextSetSurface(0, 0, null);
+ mRS.setSurface(null, 0, 0);
}
}
@@ -91,23 +88,21 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
* not normally called or subclassed by clients of RSSurfaceView.
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- Log.v(RenderScript.LOG_TAG, "surfaceChanged");
if (mRS != null) {
- mRS.contextSetSurface(w, h, holder.getSurface());
+ mRS.setSurface(holder, w, h);
}
}
- /**
+ /**
* Inform the view that the activity is paused. The owner of this view must
* call this method when the activity is paused. Calling this method will
* pause the rendering thread.
* Must not be called before a renderer has been set.
*/
- public void onPause() {
+ public void pause() {
if(mRS != null) {
mRS.pause();
}
- //Log.v(RenderScript.LOG_TAG, "onPause");
}
/**
@@ -117,53 +112,29 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
* thread.
* Must not be called before a renderer has been set.
*/
- public void onResume() {
+ public void resume() {
if(mRS != null) {
mRS.resume();
}
- //Log.v(RenderScript.LOG_TAG, "onResume");
- }
-
- /**
- * Queue a runnable to be run on the GL rendering thread. This can be used
- * to communicate with the Renderer on the rendering thread.
- * Must not be called before a renderer has been set.
- * @param r the runnable to be run on the GL rendering thread.
- */
- public void queueEvent(Runnable r) {
- //Log.v(RenderScript.LOG_TAG, "queueEvent");
- }
-
- /**
- * This method is used as part of the View class and is not normally
- * called or subclassed by clients of RSSurfaceView.
- * Must not be called before a renderer has been set.
- */
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- }
-
- // ----------------------------------------------------------------------
-
- public RenderScriptGL createRenderScript(boolean useDepth, boolean forceSW) {
- Log.v(RenderScript.LOG_TAG, "createRenderScript");
- mRS = new RenderScriptGL(useDepth, forceSW);
- return mRS;
}
- public RenderScriptGL createRenderScript(boolean useDepth) {
- return createRenderScript(useDepth, false);
+ public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) {
+ RenderScriptGL rs = new RenderScriptGL(sc);
+ setRenderScriptGL(rs);
+ return rs;
}
- public void destroyRenderScript() {
- Log.v(RenderScript.LOG_TAG, "destroyRenderScript");
+ public void destroyRenderScriptGL() {
mRS.destroy();
mRS = null;
}
-
- public void createRenderScript(RenderScriptGL rs) {
+
+ public void setRenderScriptGL(RenderScriptGL rs) {
mRS = rs;
}
+
+ public RenderScriptGL getRenderScriptGL() {
+ return mRS;
+ }
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index a935243..6ff894d 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -28,12 +28,19 @@ import android.view.Surface;
/**
* @hide
*
+ * RenderScript base master class. An instance of this class creates native
+ * worker threads for processing commands from this object. This base class
+ * does not provide any extended capabilities beyond simple data processing.
+ * For extended capabilities use derived classes such as RenderScriptGL.
+ *
+ *
+ *
**/
public class RenderScript {
static final String LOG_TAG = "RenderScript_jni";
- protected static final boolean DEBUG = false;
+ static final boolean DEBUG = false;
@SuppressWarnings({"UnusedDeclaration", "deprecation"})
- protected static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+ static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
@@ -42,8 +49,8 @@ public class RenderScript {
* field offsets.
*/
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
- protected static boolean sInitialized;
- native protected static void _nInit();
+ static boolean sInitialized;
+ native static void _nInit();
static {
@@ -57,151 +64,494 @@ public class RenderScript {
}
}
+ // Non-threadsafe functions.
native void nInitElements(int a8, int rgba4444, int rgba8888, int rgb565);
-
native int nDeviceCreate();
native void nDeviceDestroy(int dev);
native void nDeviceSetConfig(int dev, int param, int value);
- native int nContextCreateGL(int dev, int ver, boolean useDepth);
- native int nContextCreate(int dev, int ver);
- native void nContextDestroy(int con);
- native void nContextSetSurface(int w, int h, Surface sur);
- native void nContextSetPriority(int p);
- native void nContextDump(int bits);
-
- native void nContextBindRootScript(int script);
- native void nContextBindSampler(int sampler, int slot);
- native void nContextBindProgramFragmentStore(int pfs);
- native void nContextBindProgramFragment(int pf);
- native void nContextBindProgramVertex(int pf);
- native void nContextBindProgramRaster(int pr);
- native void nContextPause();
- native void nContextResume();
- native int nContextGetMessage(int[] data, boolean wait);
- native void nContextInitToClient();
- native void nContextDeinitToClient();
-
- native void nAssignName(int obj, byte[] name);
- native void nObjDestroy(int id);
- native void nObjDestroyOOB(int id);
- native int nFileOpen(byte[] name);
-
-
- native int nElementCreate(int type, int kind, boolean norm, int vecSize);
- native int nElementCreate2(int[] elements, 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 int nAllocationCreateTyped(int type);
- native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
- native int nAllocationCreateBitmapRef(int type, Bitmap bmp);
- native int nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
- native int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
-
- native void nAllocationUploadToTexture(int alloc, boolean genMips, int baseMioLevel);
- native void nAllocationUploadToBufferObject(int alloc);
-
- native void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes);
- native void nAllocationSubData1D(int id, int off, int count, short[] d, int sizeBytes);
- native void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes);
- native void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes);
-
- native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes);
- native void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes);
- native void nAllocationRead(int id, int[] d);
- native void nAllocationRead(int id, float[] d);
- native void nAllocationSubDataFromObject(int id, Type t, int offset, Object o);
- native void nAllocationSubReadFromObject(int id, Type t, int offset, Object o);
-
- native void nAdapter1DBindAllocation(int ad, int alloc);
- native void nAdapter1DSetConstraint(int ad, int dim, int value);
- native void nAdapter1DData(int ad, int[] d);
- native void nAdapter1DData(int ad, float[] d);
- native void nAdapter1DSubData(int ad, int off, int count, int[] d);
- native void nAdapter1DSubData(int ad, int off, int count, float[] d);
- native int nAdapter1DCreate();
-
- native void nAdapter2DBindAllocation(int ad, int alloc);
- native void nAdapter2DSetConstraint(int ad, int dim, int value);
- native void nAdapter2DData(int ad, int[] d);
- native void nAdapter2DData(int ad, float[] d);
- native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, int[] d);
- native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, float[] d);
- native int nAdapter2DCreate();
-
- native void nScriptBindAllocation(int script, int alloc, int slot);
- native void nScriptSetClearColor(int script, float r, float g, float b, float a);
- native void nScriptSetClearDepth(int script, float depth);
- native void nScriptSetClearStencil(int script, int stencil);
- native void nScriptSetTimeZone(int script, byte[] timeZone);
- native void nScriptSetType(int type, boolean writable, String name, int slot);
- native void nScriptSetRoot(boolean isRoot);
- native void nScriptSetInvokable(String name, int slot);
- native void nScriptInvoke(int id, int slot);
-
- 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 int nProgramRasterCreate(int in, int out, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
- native void nProgramRasterSetLineWidth(int pr, float v);
- native void nProgramRasterSetPointSize(int pr, float v);
-
- native void nProgramBindConstants(int pv, int slot, int mID);
- native void nProgramBindTexture(int vpf, int slot, int a);
- native void nProgramBindSampler(int vpf, int slot, int s);
-
- native int nProgramFragmentCreate(int[] params);
- native int nProgramFragmentCreate2(String shader, int[] params);
-
- native int nProgramVertexCreate(boolean texMat);
- native int nProgramVertexCreate2(String shader, int[] params);
-
- native void nLightBegin();
- native void nLightSetIsMono(boolean isMono);
- native void nLightSetIsLocal(boolean isLocal);
- native int nLightCreate();
- native void nLightSetColor(int l, float r, float g, float b);
- native void nLightSetPosition(int l, float x, float y, float z);
-
- native int nSimpleMeshCreate(int batchID, int idxID, int[] vtxID, int prim);
- native void nSimpleMeshBindVertex(int id, int alloc, int slot);
- native void nSimpleMeshBindIndex(int id, int alloc);
-
- native void nAnimationBegin(int attribCount, int keyframeCount);
- native void nAnimationAdd(float time, float[] attribs);
- native int nAnimationCreate();
-
- protected int mDev;
- protected int mContext;
- @SuppressWarnings({"FieldCanBeLocal"})
- protected MessageThread mMessageThread;
+ native void nContextGetUserMessage(int con, int[] data);
+ native String nContextGetErrorMessage(int con);
+ native int nContextPeekMessage(int con, int[] subID, boolean wait);
+ native void nContextInitToClient(int con);
+ native void nContextDeinitToClient(int con);
+
+
+ // Methods below are wrapped to protect the non-threadsafe
+ // lockless fifo.
+ native int rsnContextCreateGL(int dev, int ver,
+ int colorMin, int colorPref,
+ int alphaMin, int alphaPref,
+ int depthMin, int depthPref,
+ int stencilMin, int stencilPref,
+ int samplesMin, int samplesPref, float samplesQ);
+ synchronized int nContextCreateGL(int dev, int ver,
+ int colorMin, int colorPref,
+ int alphaMin, int alphaPref,
+ int depthMin, int depthPref,
+ int stencilMin, int stencilPref,
+ int samplesMin, int samplesPref, float samplesQ) {
+ return rsnContextCreateGL(dev, ver, colorMin, colorPref,
+ alphaMin, alphaPref, depthMin, depthPref,
+ stencilMin, stencilPref,
+ samplesMin, samplesPref, samplesQ);
+ }
+ native int rsnContextCreate(int dev, int ver);
+ synchronized int nContextCreate(int dev, int ver) {
+ return rsnContextCreate(dev, ver);
+ }
+ native void rsnContextDestroy(int con);
+ synchronized void nContextDestroy() {
+ rsnContextDestroy(mContext);
+ }
+ native void rsnContextSetSurface(int con, int w, int h, Surface sur);
+ synchronized void nContextSetSurface(int w, int h, Surface sur) {
+ rsnContextSetSurface(mContext, w, h, sur);
+ }
+ native void rsnContextSetPriority(int con, int p);
+ synchronized void nContextSetPriority(int p) {
+ rsnContextSetPriority(mContext, p);
+ }
+ native void rsnContextDump(int con, int bits);
+ synchronized void nContextDump(int bits) {
+ rsnContextDump(mContext, bits);
+ }
+ native void rsnContextFinish(int con);
+ synchronized void nContextFinish() {
+ rsnContextFinish(mContext);
+ }
+
+ native void rsnContextBindRootScript(int con, int script);
+ synchronized void nContextBindRootScript(int script) {
+ rsnContextBindRootScript(mContext, script);
+ }
+ native void rsnContextBindSampler(int con, int sampler, int slot);
+ synchronized void nContextBindSampler(int sampler, int slot) {
+ rsnContextBindSampler(mContext, sampler, slot);
+ }
+ native void rsnContextBindProgramStore(int con, int pfs);
+ synchronized void nContextBindProgramStore(int pfs) {
+ rsnContextBindProgramStore(mContext, pfs);
+ }
+ native void rsnContextBindProgramFragment(int con, int pf);
+ synchronized void nContextBindProgramFragment(int pf) {
+ rsnContextBindProgramFragment(mContext, pf);
+ }
+ native void rsnContextBindProgramVertex(int con, int pv);
+ synchronized void nContextBindProgramVertex(int pv) {
+ rsnContextBindProgramVertex(mContext, pv);
+ }
+ native void rsnContextBindProgramRaster(int con, int pr);
+ synchronized void nContextBindProgramRaster(int pr) {
+ rsnContextBindProgramRaster(mContext, pr);
+ }
+ native void rsnContextPause(int con);
+ synchronized void nContextPause() {
+ rsnContextPause(mContext);
+ }
+ native void rsnContextResume(int con);
+ synchronized void nContextResume() {
+ rsnContextResume(mContext);
+ }
+
+ native void rsnAssignName(int con, int obj, byte[] name);
+ synchronized void nAssignName(int obj, byte[] name) {
+ rsnAssignName(mContext, obj, name);
+ }
+ native String rsnGetName(int con, int obj);
+ synchronized String nGetName(int obj) {
+ return rsnGetName(mContext, obj);
+ }
+ native void rsnObjDestroy(int con, int id);
+ synchronized void nObjDestroy(int id) {
+ rsnObjDestroy(mContext, id);
+ }
+
+ native int rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
+ synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
+ return rsnElementCreate(mContext, type, kind, norm, vecSize);
+ }
+ native int rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
+ synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+ return rsnElementCreate2(mContext, elements, names, arraySizes);
+ }
+ native void rsnElementGetNativeData(int con, int id, int[] elementData);
+ synchronized void nElementGetNativeData(int id, int[] elementData) {
+ rsnElementGetNativeData(mContext, id, elementData);
+ }
+ native void rsnElementGetSubElements(int con, int id, int[] IDs, String[] names);
+ synchronized void nElementGetSubElements(int id, int[] IDs, String[] names) {
+ rsnElementGetSubElements(mContext, id, IDs, names);
+ }
+
+ native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
+ synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces) {
+ return rsnTypeCreate(mContext, eid, x, y, z, mips, faces);
+ }
+ native void rsnTypeGetNativeData(int con, int id, int[] typeData);
+ synchronized void nTypeGetNativeData(int id, int[] typeData) {
+ rsnTypeGetNativeData(mContext, id, typeData);
+ }
+
+ native int rsnAllocationCreateTyped(int con, int type);
+ synchronized int nAllocationCreateTyped(int type) {
+ return rsnAllocationCreateTyped(mContext, type);
+ }
+ native void rsnAllocationUpdateFromBitmap(int con, int alloc, Bitmap bmp);
+ synchronized void nAllocationUpdateFromBitmap(int alloc, Bitmap bmp) {
+ rsnAllocationUpdateFromBitmap(mContext, alloc, bmp);
+ }
+ native int rsnAllocationCreateFromBitmap(int con, int dstFmt, boolean genMips, Bitmap bmp);
+ synchronized int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp) {
+ return rsnAllocationCreateFromBitmap(mContext, dstFmt, genMips, bmp);
+ }
+ native int rsnAllocationCubeCreateFromBitmap(int con, int dstFmt, boolean genMips, Bitmap bmp);
+ synchronized int nAllocationCubeCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp) {
+ return rsnAllocationCubeCreateFromBitmap(mContext, dstFmt, genMips, bmp);
+ }
+ native int rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
+ synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
+ return rsnAllocationCreateBitmapRef(mContext, type, bmp);
+ }
+ native int rsnAllocationCreateFromAssetStream(int con, int dstFmt, boolean genMips, int assetStream);
+ synchronized int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream) {
+ return rsnAllocationCreateFromAssetStream(mContext, dstFmt, genMips, assetStream);
+ }
+
+ native void rsnAllocationUploadToTexture(int con, int alloc, boolean genMips, int baseMioLevel);
+ synchronized void nAllocationUploadToTexture(int alloc, boolean genMips, int baseMioLevel) {
+ rsnAllocationUploadToTexture(mContext, alloc, genMips, baseMioLevel);
+ }
+ native void rsnAllocationUploadToBufferObject(int con, int alloc);
+ synchronized void nAllocationUploadToBufferObject(int alloc) {
+ rsnAllocationUploadToBufferObject(mContext, alloc);
+ }
+
+ native void rsnAllocationSubData1D(int con, int id, int off, int count, int[] d, int sizeBytes);
+ synchronized void nAllocationSubData1D(int id, int off, int count, int[] d, int sizeBytes) {
+ rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
+ }
+ native void rsnAllocationSubData1D(int con, int id, int off, int count, short[] d, int sizeBytes);
+ synchronized void nAllocationSubData1D(int id, int off, int count, short[] d, int sizeBytes) {
+ rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
+ }
+ native void rsnAllocationSubData1D(int con, int id, int off, int count, byte[] d, int sizeBytes);
+ synchronized void nAllocationSubData1D(int id, int off, int count, byte[] d, int sizeBytes) {
+ rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
+ }
+ native void rsnAllocationSubElementData1D(int con, int id, int xoff, int compIdx, byte[] d, int sizeBytes);
+ synchronized void nAllocationSubElementData1D(int id, int xoff, int compIdx, byte[] d, int sizeBytes) {
+ rsnAllocationSubElementData1D(mContext, id, xoff, compIdx, d, sizeBytes);
+ }
+ native void rsnAllocationSubData1D(int con, int id, int off, int count, float[] d, int sizeBytes);
+ synchronized void nAllocationSubData1D(int id, int off, int count, float[] d, int sizeBytes) {
+ rsnAllocationSubData1D(mContext, id, off, count, d, sizeBytes);
+ }
+
+ native void rsnAllocationSubData2D(int con, int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes);
+ synchronized void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, int[] d, int sizeBytes) {
+ rsnAllocationSubData2D(mContext, id, xoff, yoff, w, h, d, sizeBytes);
+ }
+ native void rsnAllocationSubData2D(int con, int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes);
+ synchronized void nAllocationSubData2D(int id, int xoff, int yoff, int w, int h, float[] d, int sizeBytes) {
+ rsnAllocationSubData2D(mContext, id, xoff, yoff, w, h, d, sizeBytes);
+ }
+ native void rsnAllocationRead(int con, int id, int[] d);
+ synchronized void nAllocationRead(int id, int[] d) {
+ rsnAllocationRead(mContext, id, d);
+ }
+ native void rsnAllocationRead(int con, int id, float[] d);
+ synchronized void nAllocationRead(int id, float[] d) {
+ rsnAllocationRead(mContext, id, d);
+ }
+ native int rsnAllocationGetType(int con, int id);
+ synchronized int nAllocationGetType(int id) {
+ return rsnAllocationGetType(mContext, id);
+ }
+
+ native void rsnAllocationResize1D(int con, int id, int dimX);
+ synchronized void nAllocationResize1D(int id, int dimX) {
+ rsnAllocationResize1D(mContext, id, dimX);
+ }
+ native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
+ synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
+ rsnAllocationResize2D(mContext, id, dimX, dimY);
+ }
+
+ native int rsnFileA3DCreateFromAssetStream(int con, int assetStream);
+ synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
+ return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
+ }
+ native int rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
+ synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
+ return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
+ }
+ native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
+ synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
+ rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
+ }
+ native int rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
+ synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
+ return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
+ }
+
+ native int rsnFontCreateFromFile(int con, String fileName, int size, int dpi);
+ synchronized int nFontCreateFromFile(String fileName, int size, int dpi) {
+ return rsnFontCreateFromFile(mContext, fileName, size, dpi);
+ }
+
+ native void rsnAdapter1DBindAllocation(int con, int ad, int alloc);
+ synchronized void nAdapter1DBindAllocation(int ad, int alloc) {
+ rsnAdapter1DBindAllocation(mContext, ad, alloc);
+ }
+ native void rsnAdapter1DSetConstraint(int con, int ad, int dim, int value);
+ synchronized void nAdapter1DSetConstraint(int ad, int dim, int value) {
+ rsnAdapter1DSetConstraint(mContext, ad, dim, value);
+ }
+ native void rsnAdapter1DData(int con, int ad, int[] d);
+ synchronized void nAdapter1DData(int ad, int[] d) {
+ rsnAdapter1DData(mContext, ad, d);
+ }
+ native void rsnAdapter1DData(int con, int ad, float[] d);
+ synchronized void nAdapter1DData(int ad, float[] d) {
+ rsnAdapter1DData(mContext, ad, d);
+ }
+ native void rsnAdapter1DSubData(int con, int ad, int off, int count, int[] d);
+ synchronized void nAdapter1DSubData(int ad, int off, int count, int[] d) {
+ rsnAdapter1DSubData(mContext, ad, off, count, d);
+ }
+ native void rsnAdapter1DSubData(int con, int ad, int off, int count, float[] d);
+ synchronized void nAdapter1DSubData(int ad, int off, int count, float[] d) {
+ rsnAdapter1DSubData(mContext, ad, off, count, d);
+ }
+ native int rsnAdapter1DCreate(int con);
+ synchronized int nAdapter1DCreate() {
+ return rsnAdapter1DCreate(mContext);
+ }
+
+ native void rsnAdapter2DBindAllocation(int con, int ad, int alloc);
+ synchronized void nAdapter2DBindAllocation(int ad, int alloc) {
+ rsnAdapter2DBindAllocation(mContext, ad, alloc);
+ }
+ native void rsnAdapter2DSetConstraint(int con, int ad, int dim, int value);
+ synchronized void nAdapter2DSetConstraint(int ad, int dim, int value) {
+ rsnAdapter2DSetConstraint(mContext, ad, dim, value);
+ }
+ native void rsnAdapter2DData(int con, int ad, int[] d);
+ synchronized void nAdapter2DData(int ad, int[] d) {
+ rsnAdapter2DData(mContext, ad, d);
+ }
+ native void rsnAdapter2DData(int con, int ad, float[] d);
+ synchronized void nAdapter2DData(int ad, float[] d) {
+ rsnAdapter2DData(mContext, ad, d);
+ }
+ native void rsnAdapter2DSubData(int con, int ad, int xoff, int yoff, int w, int h, int[] d);
+ synchronized void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, int[] d) {
+ rsnAdapter2DSubData(mContext, ad, xoff, yoff, w, h, d);
+ }
+ native void rsnAdapter2DSubData(int con, int ad, int xoff, int yoff, int w, int h, float[] d);
+ synchronized void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, float[] d) {
+ rsnAdapter2DSubData(mContext, ad, xoff, yoff, w, h, d);
+ }
+ native int rsnAdapter2DCreate(int con);
+ synchronized int nAdapter2DCreate() {
+ return rsnAdapter2DCreate(mContext);
+ }
+
+ native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
+ synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
+ rsnScriptBindAllocation(mContext, script, alloc, slot);
+ }
+ native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
+ synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
+ rsnScriptSetTimeZone(mContext, script, timeZone);
+ }
+ native void rsnScriptInvoke(int con, int id, int slot);
+ synchronized void nScriptInvoke(int id, int slot) {
+ rsnScriptInvoke(mContext, id, slot);
+ }
+ native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
+ synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
+ rsnScriptInvokeV(mContext, id, slot, params);
+ }
+ native void rsnScriptSetVarI(int con, int id, int slot, int val);
+ synchronized void nScriptSetVarI(int id, int slot, int val) {
+ rsnScriptSetVarI(mContext, id, slot, val);
+ }
+ native void rsnScriptSetVarJ(int con, int id, int slot, long val);
+ synchronized void nScriptSetVarJ(int id, int slot, long val) {
+ rsnScriptSetVarJ(mContext, id, slot, val);
+ }
+ native void rsnScriptSetVarF(int con, int id, int slot, float val);
+ synchronized void nScriptSetVarF(int id, int slot, float val) {
+ rsnScriptSetVarF(mContext, id, slot, val);
+ }
+ native void rsnScriptSetVarD(int con, int id, int slot, double val);
+ synchronized void nScriptSetVarD(int id, int slot, double val) {
+ rsnScriptSetVarD(mContext, id, slot, val);
+ }
+ native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
+ synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
+ rsnScriptSetVarV(mContext, id, slot, val);
+ }
+ native void rsnScriptSetVarObj(int con, int id, int slot, int val);
+ synchronized void nScriptSetVarObj(int id, int slot, int val) {
+ rsnScriptSetVarObj(mContext, id, slot, val);
+ }
+
+ native void rsnScriptCBegin(int con);
+ synchronized void nScriptCBegin() {
+ rsnScriptCBegin(mContext);
+ }
+ native void rsnScriptCSetScript(int con, byte[] script, int offset, int length);
+ synchronized void nScriptCSetScript(byte[] script, int offset, int length) {
+ rsnScriptCSetScript(mContext, script, offset, length);
+ }
+ native int rsnScriptCCreate(int con, String val);
+ synchronized int nScriptCCreate(String val) {
+ return rsnScriptCCreate(mContext, val);
+ }
+
+ native void rsnSamplerBegin(int con);
+ synchronized void nSamplerBegin() {
+ rsnSamplerBegin(mContext);
+ }
+ native void rsnSamplerSet(int con, int param, int value);
+ synchronized void nSamplerSet(int param, int value) {
+ rsnSamplerSet(mContext, param, value);
+ }
+ native void rsnSamplerSet2(int con, int param, float value);
+ synchronized void nSamplerSet2(int param, float value) {
+ rsnSamplerSet2(mContext, param, value);
+ }
+ native int rsnSamplerCreate(int con);
+ synchronized int nSamplerCreate() {
+ return rsnSamplerCreate(mContext);
+ }
+
+ native void rsnProgramStoreBegin(int con, int in, int out);
+ synchronized void nProgramStoreBegin(int in, int out) {
+ rsnProgramStoreBegin(mContext, in, out);
+ }
+ native void rsnProgramStoreDepthFunc(int con, int func);
+ synchronized void nProgramStoreDepthFunc(int func) {
+ rsnProgramStoreDepthFunc(mContext, func);
+ }
+ native void rsnProgramStoreDepthMask(int con, boolean enable);
+ synchronized void nProgramStoreDepthMask(boolean enable) {
+ rsnProgramStoreDepthMask(mContext, enable);
+ }
+ native void rsnProgramStoreColorMask(int con, boolean r, boolean g, boolean b, boolean a);
+ synchronized void nProgramStoreColorMask(boolean r, boolean g, boolean b, boolean a) {
+ rsnProgramStoreColorMask(mContext, r, g, b, a);
+ }
+ native void rsnProgramStoreBlendFunc(int con, int src, int dst);
+ synchronized void nProgramStoreBlendFunc(int src, int dst) {
+ rsnProgramStoreBlendFunc(mContext, src, dst);
+ }
+ native void rsnProgramStoreDither(int con, boolean enable);
+ synchronized void nProgramStoreDither(boolean enable) {
+ rsnProgramStoreDither(mContext, enable);
+ }
+ native int rsnProgramStoreCreate(int con);
+ synchronized int nProgramStoreCreate() {
+ return rsnProgramStoreCreate(mContext);
+ }
+
+ native int rsnProgramRasterCreate(int con, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
+ synchronized int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth, boolean pointSprite) {
+ return rsnProgramRasterCreate(mContext, pointSmooth, lineSmooth, pointSprite);
+ }
+ native void rsnProgramRasterSetLineWidth(int con, int pr, float v);
+ synchronized void nProgramRasterSetLineWidth(int pr, float v) {
+ rsnProgramRasterSetLineWidth(mContext, pr, v);
+ }
+ native void rsnProgramRasterSetCullMode(int con, int pr, int mode);
+ synchronized void nProgramRasterSetCullMode(int pr, int mode) {
+ rsnProgramRasterSetCullMode(mContext, pr, mode);
+ }
+
+ native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
+ synchronized void nProgramBindConstants(int pv, int slot, int mID) {
+ rsnProgramBindConstants(mContext, pv, slot, mID);
+ }
+ native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
+ synchronized void nProgramBindTexture(int vpf, int slot, int a) {
+ rsnProgramBindTexture(mContext, vpf, slot, a);
+ }
+ native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
+ synchronized void nProgramBindSampler(int vpf, int slot, int s) {
+ rsnProgramBindSampler(mContext, vpf, slot, s);
+ }
+ native int rsnProgramFragmentCreate(int con, String shader, int[] params);
+ synchronized int nProgramFragmentCreate(String shader, int[] params) {
+ return rsnProgramFragmentCreate(mContext, shader, params);
+ }
+ native int rsnProgramVertexCreate(int con, String shader, int[] params);
+ synchronized int nProgramVertexCreate(String shader, int[] params) {
+ return rsnProgramVertexCreate(mContext, shader, params);
+ }
+
+ native int rsnMeshCreate(int con, int vtxCount, int indexCount);
+ synchronized int nMeshCreate(int vtxCount, int indexCount) {
+ return rsnMeshCreate(mContext, vtxCount, indexCount);
+ }
+ native void rsnMeshBindVertex(int con, int id, int alloc, int slot);
+ synchronized void nMeshBindVertex(int id, int alloc, int slot) {
+ rsnMeshBindVertex(mContext, id, alloc, slot);
+ }
+ native void rsnMeshBindIndex(int con, int id, int alloc, int prim, int slot);
+ synchronized void nMeshBindIndex(int id, int alloc, int prim, int slot) {
+ rsnMeshBindIndex(mContext, id, alloc, prim, slot);
+ }
+ native void rsnMeshInitVertexAttribs(int con, int id);
+ synchronized void nMeshInitVertexAttribs(int id) {
+ rsnMeshInitVertexAttribs(mContext, id);
+ }
+ native int rsnMeshGetVertexBufferCount(int con, int id);
+ synchronized int nMeshGetVertexBufferCount(int id) {
+ return rsnMeshGetVertexBufferCount(mContext, id);
+ }
+ native int rsnMeshGetIndexCount(int con, int id);
+ synchronized int nMeshGetIndexCount(int id) {
+ return rsnMeshGetIndexCount(mContext, id);
+ }
+ native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
+ synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
+ rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
+ }
+ native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
+ synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
+ rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
+ }
- 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;
+
+ int mDev;
+ int mContext;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ MessageThread mMessageThread;
+
+ Element mElement_U8;
+ Element mElement_I8;
+ Element mElement_U16;
+ Element mElement_I16;
+ Element mElement_U32;
+ Element mElement_I32;
+ Element mElement_U64;
+ Element mElement_I64;
+ Element mElement_F32;
+ Element mElement_F64;
+ 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,26 +560,109 @@ 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;
+
+ Element mElement_MATRIX_4X4;
+ Element mElement_MATRIX_3X3;
+ Element mElement_MATRIX_2X2;
+
+ 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;
+
+ ProgramStore mProgramStore_BLEND_NONE_DEPTH_TEST;
+ ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
+ ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_TEST;
+ ProgramStore mProgramStore_BLEND_NONE_DEPTH_NO_WRITE;
+ ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_TEST;
+ ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
+ ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_TEST;
+ ProgramStore mProgramStore_BLEND_ALPHA_DEPTH_NO_WRITE;
+ ProgramStore mProgramStore_BLEND_ADD_DEPTH_TEST;
+ ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_DEPTH;
+ ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_TEST;
+ ProgramStore mProgramStore_BLEND_ADD_DEPTH_NO_WRITE;
+
+ ProgramRaster mProgramRaster_CULL_BACK;
+ ProgramRaster mProgramRaster_CULL_FRONT;
+ ProgramRaster mProgramRaster_CULL_NONE;
///////////////////////////////////////////////////////////////////////////////////
//
- public static class RSMessage implements Runnable {
+ /**
+ * Base class application should derive from for handling RS messages
+ * comming from their scripts. When a script calls sendToClient the data
+ * fields will be filled in and then the run method called by a message
+ * handling thread. This will occur some time after sendToClient completes
+ * in the script.
+ *
+ */
+ public static class RSMessageHandler implements Runnable {
protected int[] mData;
protected int mID;
+ protected int mLength;
public void run() {
}
}
- public RSMessage mMessageCallback = null;
+ /**
+ * If an application is expecting messages it should set this field to an
+ * instance of RSMessage. This instance will receive all the user messages
+ * sent from sendToClient by scripts from this context.
+ *
+ */
+ RSMessageHandler mMessageCallback = null;
+ public void setMessageHandler(RSMessageHandler msg) {
+ mMessageCallback = msg;
+ }
+ public RSMessageHandler getMessageHandler() {
+ return mMessageCallback;
+ }
+
+ /**
+ * Runtime error base class. An application should derive from this class
+ * if it wishes to install an error handler. When errors occur at runtime
+ * the fields in this class will be filled and the run method called.
+ *
+ */
+ public static class RSErrorHandler implements Runnable {
+ protected String mErrorMessage;
+ protected int mErrorNum;
+ public void run() {
+ }
+ }
+
+ /**
+ * Application Error handler. All runtime errors will be dispatched to the
+ * instance of RSAsyncError set here. If this field is null a
+ * RSRuntimeException will instead be thrown with details about the error.
+ * This will cause program termaination.
+ *
+ */
+ RSErrorHandler mErrorCallback = null;
+
+ public void setErrorHandler(RSErrorHandler msg) {
+ mErrorCallback = msg;
+ }
+ public RSErrorHandler getErrorHandler() {
+ return mErrorCallback;
+ }
+
+ /**
+ * RenderScript worker threads priority enumeration. The default value is
+ * NORMAL. Applications wishing to do background processing such as
+ * wallpapers should set their priority to LOW to avoid starving forground
+ * processes.
+ */
public enum Priority {
+ // Remap these numbers to opaque...
LOW (5), //ANDROID_PRIORITY_BACKGROUND + 5
NORMAL (-4); //ANDROID_PRIORITY_DISPLAY
@@ -241,18 +674,33 @@ public class RenderScript {
void validate() {
if (mContext == 0) {
- throw new IllegalStateException("Calling RS with no Context active.");
+ throw new RSInvalidStateException("Calling RS with no Context active.");
}
}
- public void contextSetPriority(Priority p) {
+
+ /**
+ * Change the priority of the worker threads for this context.
+ *
+ * @param p New priority to be set.
+ */
+ public void setPriority(Priority p) {
validate();
nContextSetPriority(p.mID);
}
- protected static class MessageThread extends Thread {
+ static class MessageThread extends Thread {
RenderScript mRS;
boolean mRun = true;
+ int[] mAuxData = new int[2];
+
+ static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
+ static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
+ static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
+ static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
+ static final int RS_MESSAGE_TO_CLIENT_USER = 4;
+
+ static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
MessageThread(RenderScript rs) {
super("RSMessageThread");
@@ -264,33 +712,69 @@ public class RenderScript {
// This function is a temporary solution. The final solution will
// used typed allocations where the message id is the type indicator.
int[] rbuf = new int[16];
- mRS.nContextInitToClient();
+ mRS.nContextInitToClient(mRS.mContext);
while(mRun) {
- int msg = mRS.nContextGetMessage(rbuf, true);
- if (msg == 0) {
- // Should only happen during teardown.
- // But we want to avoid starving other threads during
- // teardown by yielding until the next line in the destructor
- // can execute to set mRun = false
- try {
- sleep(1, 0);
- } catch(InterruptedException e) {
+ rbuf[0] = 0;
+ int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData, true);
+ int size = mAuxData[1];
+ int subID = mAuxData[0];
+
+ if (msg == RS_MESSAGE_TO_CLIENT_USER) {
+ if ((size>>2) >= rbuf.length) {
+ rbuf = new int[(size + 3) >> 2];
+ }
+ mRS.nContextGetUserMessage(mRS.mContext, rbuf);
+
+ if(mRS.mMessageCallback != null) {
+ mRS.mMessageCallback.mData = rbuf;
+ mRS.mMessageCallback.mID = subID;
+ mRS.mMessageCallback.mLength = size;
+ mRS.mMessageCallback.run();
+ } else {
+ throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
}
+ continue;
}
- if(mRS.mMessageCallback != null) {
- mRS.mMessageCallback.mData = rbuf;
- mRS.mMessageCallback.mID = msg;
- mRS.mMessageCallback.run();
+
+ if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
+ String e = mRS.nContextGetErrorMessage(mRS.mContext);
+
+ if (subID >= RS_ERROR_FATAL_UNKNOWN) {
+ throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
+ }
+
+ if(mRS.mErrorCallback != null) {
+ mRS.mErrorCallback.mErrorMessage = e;
+ mRS.mErrorCallback.mErrorNum = subID;
+ mRS.mErrorCallback.run();
+ } else {
+ //throw new RSRuntimeException("Received error num " + subID + ", details: " + e);
+ }
+ continue;
+ }
+
+ // 2: teardown.
+ // But we want to avoid starving other threads during
+ // teardown by yielding until the next line in the destructor
+ // can execute to set mRun = false
+ try {
+ sleep(1, 0);
+ } catch(InterruptedException e) {
}
- //Log.d(LOG_TAG, "MessageThread msg " + msg + " v1 " + rbuf[0] + " v2 " + rbuf[1] + " v3 " +rbuf[2]);
}
Log.d(LOG_TAG, "MessageThread exiting.");
}
}
- protected RenderScript() {
+ RenderScript() {
}
+ /**
+ * Create a basic RenderScript context.
+ *
+ *
+ * @return RenderScript
+ */
public static RenderScript create() {
RenderScript rs = new RenderScript();
@@ -302,17 +786,40 @@ public class RenderScript {
return rs;
}
- public void contextDump(int bits) {
+ /**
+ * Print the currently available debugging information about the state of
+ * the RS context to the log.
+ *
+ */
+ public void contextDump() {
validate();
- nContextDump(bits);
+ nContextDump(0);
}
+ /**
+ * Wait for any commands in the fifo between the java bindings and native to
+ * be processed.
+ *
+ */
+ public void finish() {
+ nContextFinish();
+ }
+
+ /**
+ * Destroy this renderscript context. Once this function is called its no
+ * longer legal to use this or any objects created by this context.
+ *
+ */
public void destroy() {
validate();
- nContextDeinitToClient();
+ nContextDeinitToClient(mContext);
mMessageThread.mRun = false;
+ try {
+ mMessageThread.join();
+ } catch(InterruptedException e) {
+ }
- nContextDestroy(mContext);
+ nContextDestroy();
mContext = 0;
nDeviceDestroy(mDev);
@@ -323,15 +830,10 @@ public class RenderScript {
return mContext != 0;
}
- ///////////////////////////////////////////////////////////////////////////////////
- // Root state
-
- protected int safeID(BaseObj o) {
+ int safeID(BaseObj o) {
if(o != null) {
- return o.mID;
+ return o.getID();
}
return 0;
}
}
-
-
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index d1df23d..4a1c40a 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -18,110 +18,292 @@ package android.renderscript;
import java.lang.reflect.Field;
+import android.graphics.PixelFormat;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Config;
import android.util.Log;
import android.view.Surface;
-
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
/**
* @hide
*
+ * The Graphics derivitive of RenderScript. Extends the basic context to add a
+ * root script which is the display window for graphical output. When the
+ * system needs to update the display the currently bound root script will be
+ * called. This script is expected to issue the rendering commands to repaint
+ * the screen.
**/
public class RenderScriptGL extends RenderScript {
private Surface mSurface;
int mWidth;
int mHeight;
+ /**
+ * Class which is used to describe a pixel format for a graphical buffer.
+ * This is used to describe the intended format of the display surface.
+ *
+ * The configuration is described by pairs of minimum and preferred bit
+ * depths for each component within the config and additional structural
+ * information.
+ */
+ public static class SurfaceConfig {
+ int mDepthMin = 0;
+ int mDepthPref = 0;
+ int mStencilMin = 0;
+ int mStencilPref = 0;
+ int mColorMin = 8;
+ int mColorPref = 8;
+ int mAlphaMin = 0;
+ int mAlphaPref = 0;
+ int mSamplesMin = 1;
+ int mSamplesPref = 1;
+ float mSamplesQ = 1.f;
+
+ public SurfaceConfig() {
+ }
+
+ public SurfaceConfig(SurfaceConfig sc) {
+ mDepthMin = sc.mDepthMin;
+ mDepthPref = sc.mDepthPref;
+ mStencilMin = sc.mStencilMin;
+ mStencilPref = sc.mStencilPref;
+ mColorMin = sc.mColorMin;
+ mColorPref = sc.mColorPref;
+ mAlphaMin = sc.mAlphaMin;
+ mAlphaPref = sc.mAlphaPref;
+ mSamplesMin = sc.mSamplesMin;
+ mSamplesPref = sc.mSamplesPref;
+ mSamplesQ = sc.mSamplesQ;
+ }
+
+ private void validateRange(int umin, int upref, int rmin, int rmax) {
+ if (umin < rmin || umin > rmax) {
+ throw new RSIllegalArgumentException("Minimum value provided out of range.");
+ }
+ if (upref < umin) {
+ throw new RSIllegalArgumentException("preferred must be >= Minimum.");
+ }
+ }
+
+ /**
+ * Set the per-component bit depth for color (red, green, blue). This
+ * configures the surface for an unsigned integer buffer type.
+ *
+ * @param minimum
+ * @param preferred
+ */
+ public void setColor(int minimum, int preferred) {
+ validateRange(minimum, preferred, 5, 8);
+ mColorMin = minimum;
+ mColorPref = preferred;
+ }
+
+ /**
+ * Set the bit depth for alpha. This configures the surface for
+ * an unsigned integer buffer type.
+ *
+ * @param minimum
+ * @param preferred
+ */
+ public void setAlpha(int minimum, int preferred) {
+ validateRange(minimum, preferred, 0, 8);
+ mAlphaMin = minimum;
+ mAlphaPref = preferred;
+ }
+
+ /**
+ * Set the bit depth for the depth buffer. This configures the
+ * surface for an unsigned integer buffer type. If a minimum of 0
+ * is specified then its possible no depth buffer will be
+ * allocated.
+ *
+ * @param minimum
+ * @param preferred
+ */
+ public void setDepth(int minimum, int preferred) {
+ validateRange(minimum, preferred, 0, 24);
+ mDepthMin = minimum;
+ mDepthPref = preferred;
+ }
+
+ /**
+ * Configure the multisample rendering.
+ *
+ * @param minimum The required number of samples, must be at least 1.
+ * @param preferred The targe number of samples, must be at least
+ * minimum
+ * @param Q The quality of samples, range 0-1. Used to decide between
+ * different formats which have the same number of samples but
+ * different rendering quality.
+ */
+ public void setSamples(int minimum, int preferred, float Q) {
+ validateRange(minimum, preferred, 1, 32);
+ if (Q < 0.0f || Q > 1.0f) {
+ throw new RSIllegalArgumentException("Quality out of 0-1 range.");
+ }
+ mSamplesMin = minimum;
+ mSamplesPref = preferred;
+ mSamplesQ = Q;
+ }
+ };
+
+ SurfaceConfig mSurfaceConfig;
+/*
+ // Keep?
+ public void configureSurface(SurfaceHolder sh) {
+ if (mSurfaceConfig.mAlphaMin > 1) {
+ sh.setFormat(PixelFormat.RGBA_8888);
+ } else {
+ sh.setFormat(PixelFormat.RGBX_8888);
+ }
+ }
+
+ public void checkSurface(SurfaceHolder sh) {
+ }
+*/
+
+ /**
+ * Construct a new RenderScriptGL context.
+ *
+ *
+ * @param sc The desired format of the primart rendering surface.
+ */
+ public RenderScriptGL(SurfaceConfig sc) {
+ mSurfaceConfig = new SurfaceConfig(sc);
- public RenderScriptGL(boolean useDepth, boolean forceSW) {
mSurface = null;
mWidth = 0;
mHeight = 0;
mDev = nDeviceCreate();
- if(forceSW) {
- nDeviceSetConfig(mDev, 0, 1);
+ mContext = nContextCreateGL(mDev, 0,
+ mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref,
+ mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref,
+ mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref,
+ mSurfaceConfig.mStencilMin, mSurfaceConfig.mStencilPref,
+ mSurfaceConfig.mSamplesMin, mSurfaceConfig.mSamplesPref,
+ mSurfaceConfig.mSamplesQ);
+ if (mContext == 0) {
+ throw new RSDriverException("Failed to create RS context.");
}
- mContext = nContextCreateGL(mDev, 0, useDepth);
mMessageThread = new MessageThread(this);
mMessageThread.start();
Element.initPredefined(this);
}
- public void contextSetSurface(int w, int h, Surface sur) {
- mSurface = sur;
+ /**
+ * Bind an os surface
+ *
+ *
+ * @param w
+ * @param h
+ * @param sur
+ */
+ public void setSurface(SurfaceHolder sur, int w, int h) {
+ validate();
+ if (sur != null) {
+ mSurface = sur.getSurface();
+ } else {
+ mSurface = null;
+ }
mWidth = w;
mHeight = h;
- validate();
nContextSetSurface(w, h, mSurface);
}
+ /**
+ * return the height of the last set surface.
+ *
+ * @return int
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * return the width of the last set surface.
+ *
+ * @return int
+ */
+ public int getWidth() {
+ return mWidth;
+ }
- void pause() {
+ /**
+ * Temporarly halt calls to the root rendering script.
+ *
+ */
+ public void pause() {
validate();
nContextPause();
}
- void resume() {
+ /**
+ * Resume calls to the root rendering script.
+ *
+ */
+ public void resume() {
validate();
nContextResume();
}
- public void contextBindRootScript(Script s) {
+ /**
+ * Set the script to handle calls to render the primary surface.
+ *
+ * @param s Graphics script to process rendering requests.
+ */
+ public void bindRootScript(Script s) {
validate();
nContextBindRootScript(safeID(s));
}
- public void contextBindProgramFragmentStore(ProgramStore p) {
+ /**
+ * Set the default ProgramStore object seen as the parent state by the root
+ * rendering script.
+ *
+ * @param p
+ */
+ public void bindProgramStore(ProgramStore p) {
validate();
- nContextBindProgramFragmentStore(safeID(p));
+ nContextBindProgramStore(safeID(p));
}
- public void contextBindProgramFragment(ProgramFragment p) {
+ /**
+ * Set the default ProgramFragment object seen as the parent state by the
+ * root rendering script.
+ *
+ * @param p
+ */
+ public void bindProgramFragment(ProgramFragment p) {
validate();
nContextBindProgramFragment(safeID(p));
}
- public void contextBindProgramRaster(ProgramRaster p) {
+ /**
+ * Set the default ProgramRaster object seen as the parent state by the
+ * root rendering script.
+ *
+ * @param p
+ */
+ public void bindProgramRaster(ProgramRaster p) {
validate();
nContextBindProgramRaster(safeID(p));
}
- public void contextBindProgramVertex(ProgramVertex p) {
+ /**
+ * Set the default ProgramVertex object seen as the parent state by the
+ * root rendering script.
+ *
+ * @param p
+ */
+ public void bindProgramVertex(ProgramVertex p) {
validate();
nContextBindProgramVertex(safeID(p));
}
-
-
-
- //////////////////////////////////////////////////////////////////////////////////
- // File
-
- public class File extends BaseObj {
- File(int id) {
- super(RenderScriptGL.this);
- mID = id;
- }
- }
-
- public File fileOpen(String s) throws IllegalStateException, IllegalArgumentException
- {
- if(s.length() < 1) {
- throw new IllegalArgumentException("fileOpen does not accept a zero length string.");
- }
-
- try {
- byte[] bytes = s.getBytes("UTF-8");
- int id = nFileOpen(bytes);
- return new File(id);
- } catch (java.io.UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-
}
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 40ba722..9fbc09a 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -31,6 +31,9 @@ import android.graphics.BitmapFactory;
/**
* @hide
*
+ * Sampler object which defines how data is extracted from textures. Samplers
+ * are attached to Program objects (currently only fragment) when those objects
+ * need to access texture data.
**/
public class Sampler extends BaseObj {
public enum Value {
@@ -47,10 +50,135 @@ public class Sampler extends BaseObj {
}
Sampler(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * clamp.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to linear and wrap modes set to
+ * clamp.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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;
+ }
+
+ /**
+ * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
+ * to and wrap modes set to clamp.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
+ }
+ return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * wrap.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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;
+ }
+
+ /**
+ * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+ * wrap.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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;
+ }
+
+ /**
+ * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
+ * to and wrap modes set to wrap.
+ *
+ * @param rs
+ *
+ * @return Sampler
+ */
+ 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);
+ b.setWrapS(Value.WRAP);
+ b.setWrapT(Value.WRAP);
+ rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
+ }
+ return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
+ }
+
+
+ /**
+ * Builder for creating non-standard samplers. Usefull if mix and match of
+ * wrap modes is necesary or if anisotropic filtering is desired.
+ *
+ */
public static class Builder {
RenderScript mRS;
Value mMin;
@@ -58,6 +186,7 @@ public class Sampler extends BaseObj {
Value mWrapS;
Value mWrapT;
Value mWrapR;
+ float mAniso;
public Builder(RenderScript rs) {
mRS = rs;
@@ -66,6 +195,7 @@ public class Sampler extends BaseObj {
mWrapS = Value.WRAP;
mWrapT = Value.WRAP;
mWrapR = Value.WRAP;
+ mAniso = 1.0f;
}
public void setMin(Value v) {
@@ -110,6 +240,14 @@ public class Sampler extends BaseObj {
}
}
+ public void setAnisotropy(float v) {
+ if(v >= 0.0f) {
+ mAniso = v;
+ } else {
+ throw new IllegalArgumentException("Invalid value");
+ }
+ }
+
static synchronized Sampler internalCreate(RenderScript rs, Builder b) {
rs.nSamplerBegin();
rs.nSamplerSet(0, b.mMin.mID);
@@ -117,6 +255,7 @@ public class Sampler extends BaseObj {
rs.nSamplerSet(2, b.mWrapS.mID);
rs.nSamplerSet(3, b.mWrapT.mID);
rs.nSamplerSet(4, b.mWrapR.mID);
+ rs.nSamplerSet2(5, b.mAniso);
int id = rs.nSamplerCreate();
return new Sampler(id, rs);
}
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 57ccfa3..ea616c6 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -38,39 +38,68 @@ public class Script extends BaseObj {
}
public void execute() {
- mRS.nScriptInvoke(mScript.mID, mSlot);
+ mRS.nScriptInvoke(mScript.getID(), mSlot);
}
}
+ protected void invoke(int slot) {
+ mRS.nScriptInvoke(getID(), slot);
+ }
+
+ protected void invoke(int slot, FieldPacker v) {
+ if (v != null) {
+ mRS.nScriptInvokeV(getID(), slot, v.getData());
+ } else {
+ mRS.nScriptInvoke(getID(), slot);
+ }
+ }
+
+
Script(int id, RenderScript rs) {
- super(rs);
- mID = id;
+ super(id, rs);
}
public void bindAllocation(Allocation va, int slot) {
mRS.validate();
- mRS.nScriptBindAllocation(mID, va.mID, slot);
+ if (va != null) {
+ mRS.nScriptBindAllocation(getID(), va.getID(), slot);
+ } else {
+ mRS.nScriptBindAllocation(getID(), 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(getID(), index, v);
}
- public void setClearDepth(float d) {
- mRS.validate();
- mRS.nScriptSetClearDepth(mID, d);
+ public void setVar(int index, double v) {
+ mRS.nScriptSetVarD(getID(), index, v);
}
- public void setClearStencil(int stencil) {
- mRS.validate();
- mRS.nScriptSetClearStencil(mID, stencil);
+ public void setVar(int index, int v) {
+ mRS.nScriptSetVarI(getID(), index, v);
+ }
+
+ public void setVar(int index, long v) {
+ mRS.nScriptSetVarJ(getID(), index, v);
+ }
+
+ public void setVar(int index, boolean v) {
+ mRS.nScriptSetVarI(getID(), index, v ? 1 : 0);
+ }
+
+ public void setVar(int index, BaseObj o) {
+ mRS.nScriptSetVarObj(getID(), index, (o == null) ? 0 : o.getID());
+ }
+
+ public void setVar(int index, FieldPacker v) {
+ mRS.nScriptSetVarV(getID(), index, v.getData());
}
public void setTimeZone(String timeZone) {
mRS.validate();
try {
- mRS.nScriptSetTimeZone(mID, timeZone.getBytes("UTF-8"));
+ mRS.nScriptSetTimeZone(getID(), timeZone.getBytes("UTF-8"));
} catch (java.io.UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
@@ -78,72 +107,39 @@ 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 void setType(Type t, int slot) {
- mTypes[slot] = t;
- mNames[slot] = null;
- }
- public void setType(Type t, String name, int slot) {
- mTypes[slot] = t;
- mNames[slot] = name;
- }
+ public static class FieldBase {
+ protected Element mElement;
+ protected Allocation mAllocation;
- public Invokable addInvokable(String func) {
- Invokable i = new Invokable();
- i.mName = func;
- i.mRS = mRS;
- i.mSlot = mInvokableCount;
- mInvokables[mInvokableCount++] = i;
- return i;
+ protected void init(RenderScript rs, int dimx) {
+ mAllocation = Allocation.createSized(rs, mElement, dimx);
}
- public void setType(boolean writable, int slot) {
- mWritable[slot] = writable;
+ protected FieldBase() {
}
- 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 Element getElement() {
+ return mElement;
}
- 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;
+ public Type getType() {
+ return mAllocation.getType();
}
- public void setRoot(boolean r) {
- mIsRoot = r;
+ public Allocation getAllocation() {
+ return mAllocation;
}
+ //@Override
+ public void updateAllocation() {
+ }
}
-
}
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index bb99e23..64ed75b 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -33,129 +33,49 @@ import java.lang.reflect.Modifier;
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
- ScriptC(int id, RenderScript rs) {
+ protected ScriptC(int id, RenderScript rs) {
super(id, rs);
}
- public static class Builder extends Script.Builder {
- byte[] mProgram;
- int mProgramLength;
- HashMap<String,Integer> mIntDefines = new HashMap();
- HashMap<String,Float> mFloatDefines = new HashMap();
+ protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
+ super(0, rs);
+ int id = internalCreate(rs, resources, resourceID);
+ setID(id);
+ }
- public Builder(RenderScript rs) {
- super(rs);
- }
- public void setScript(String s) {
+ private static synchronized int internalCreate(RenderScript rs, Resources resources, int resourceID) {
+ byte[] pgm;
+ int pgmLength;
+ InputStream is = resources.openRawResource(resourceID);
+ try {
try {
- mProgram = s.getBytes("UTF-8");
- mProgramLength = mProgram.length;
- } catch (java.io.UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- }
-
- public void setScript(Resources resources, int id) {
- InputStream is = resources.openRawResource(id);
- try {
- try {
- setScript(is);
- } finally {
- is.close();
- }
- } catch(IOException e) {
- throw new Resources.NotFoundException();
- }
- }
-
- public void setScript(InputStream is) throws IOException {
- byte[] buf = new byte[1024];
- int currentPos = 0;
- while(true) {
- int bytesLeft = buf.length - currentPos;
- if (bytesLeft == 0) {
- byte[] buf2 = new byte[buf.length * 2];
- System.arraycopy(buf, 0, buf2, 0, buf.length);
- buf = buf2;
- bytesLeft = buf.length - currentPos;
- }
- int bytesRead = is.read(buf, currentPos, bytesLeft);
- if (bytesRead <= 0) {
- break;
- }
- currentPos += bytesRead;
- }
- mProgram = buf;
- mProgramLength = currentPos;
- }
-
- static synchronized ScriptC internalCreate(Builder b) {
- b.mRS.nScriptCBegin();
- b.transferCreate();
-
- for (Entry<String,Integer> e: b.mIntDefines.entrySet()) {
- b.mRS.nScriptCAddDefineI32(e.getKey(), e.getValue().intValue());
- }
- for (Entry<String,Float> e: b.mFloatDefines.entrySet()) {
- b.mRS.nScriptCAddDefineF(e.getKey(), e.getValue().floatValue());
- }
-
- b.mRS.nScriptCSetScript(b.mProgram, 0, b.mProgramLength);
-
- int id = b.mRS.nScriptCCreate();
- ScriptC obj = new ScriptC(id, b.mRS);
- b.transferObject(obj);
-
- return obj;
- }
-
- public void addDefine(String name, int value) {
- mIntDefines.put(name, value);
- }
-
- public void addDefine(String name, float value) {
- mFloatDefines.put(name, value);
- }
-
- /**
- * Takes the all public static final fields for a class, and adds defines
- * for them, using the name of the field as the name of the define.
- */
- public void addDefines(Class cl) {
- addDefines(cl.getFields(), (Modifier.STATIC | Modifier.FINAL | Modifier.PUBLIC), null);
- }
-
- /**
- * Takes the all public fields for an object, and adds defines
- * for them, using the name of the field as the name of the define.
- */
- public void addDefines(Object o) {
- addDefines(o.getClass().getFields(), Modifier.PUBLIC, o);
- }
-
- void addDefines(Field[] fields, int mask, Object o) {
- for (Field f: fields) {
- try {
- if ((f.getModifiers() & mask) == mask) {
- Class t = f.getType();
- if (t == int.class) {
- mIntDefines.put(f.getName(), f.getInt(o));
- }
- else if (t == float.class) {
- mFloatDefines.put(f.getName(), f.getFloat(o));
- }
+ 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;
}
- } catch (IllegalAccessException ex) {
- // TODO: Do we want this log?
- Log.d(TAG, "addDefines skipping field " + f.getName());
+ pgmLength += bytesRead;
}
+ } finally {
+ is.close();
}
+ } catch(IOException e) {
+ throw new Resources.NotFoundException();
}
- public ScriptC create() {
- return internalCreate(this);
- }
+ rs.nScriptCBegin();
+ rs.nScriptCSetScript(pgm, 0, pgmLength);
+ Log.v(TAG, "Create script for resource = " + resources.getResourceName(resourceID));
+ return rs.nScriptCCreate(resources.getResourceName(resourceID));
}
}
-
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..859369c 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -16,68 +16,121 @@
package android.renderscript;
+
import java.lang.reflect.Field;
+import android.util.Log;
/**
* @hide
*
+ * Type is an allocation template. It consists of an Element and one or more
+ * dimensions. It describes only the layout of memory but does not allocate and
+ * storage for the data thus described.
+ *
+ * A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
+ * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned
+ * any positive integral value within the constraints of available memory. A
+ * single dimension allocation would have an X dimension of greater than zero
+ * while the Y and Z dimensions would be zero to indicate not present. In this
+ * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
+ * x=10, y=0 would be considered 1 dimensional.
+ *
+ * The LOD and Faces dimensions are booleans to indicate present or not present.
+ *
**/
public class Type extends BaseObj {
int mDimX;
int mDimY;
int mDimZ;
- boolean mDimLOD;
+ boolean mDimMipmaps;
boolean mDimFaces;
int mElementCount;
Element mElement;
- private int mNativeCache;
- Class mJavaClass;
-
+ /**
+ * Return the element associated with this Type.
+ *
+ * @return Element
+ */
public Element getElement() {
return mElement;
}
+ /**
+ * Return the value of the X dimension.
+ *
+ * @return int
+ */
public int getX() {
return mDimX;
}
+
+ /**
+ * Return the value of the Y dimension or 0 for a 1D allocation.
+ *
+ * @return int
+ */
public int getY() {
return mDimY;
}
+
+ /**
+ * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
+ *
+ * @return int
+ */
public int getZ() {
return mDimZ;
}
- public boolean getLOD() {
- return mDimLOD;
+
+ /**
+ * Return if the Type has a mipmap chain.
+ *
+ * @return boolean
+ */
+ public boolean hasMipmaps() {
+ return mDimMipmaps;
}
- public boolean getFaces() {
+
+ /**
+ * Return if the Type is a cube map.
+ *
+ * @return boolean
+ */
+ public boolean hasFaces() {
return mDimFaces;
}
- public int getElementCount() {
+
+ /**
+ * Return the total number of accessable cells in the Type.
+ *
+ * @return int
+ */
+ public int getCount() {
return mElementCount;
}
void calcElementCount() {
- boolean hasLod = getLOD();
+ boolean hasLod = hasMipmaps();
int x = getX();
int y = getY();
int z = getZ();
int faces = 1;
- if(getFaces()) {
+ if (hasFaces()) {
faces = 6;
}
- if(x == 0) {
+ if (x == 0) {
x = 1;
}
- if(y == 0) {
+ if (y == 0) {
y = 1;
}
- if(z == 0) {
+ if (z == 0) {
z = 1;
}
int count = x * y * z * faces;
- if(hasLod && (x > 1) && (y > 1) && (z > 1)) {
+ if (hasLod && (x > 1) && (y > 1) && (z > 1)) {
if(x > 1) {
x >>= 1;
}
@@ -95,131 +148,124 @@ public class Type extends BaseObj {
Type(int id, RenderScript rs) {
- super(rs);
- mID = id;
- mNativeCache = 0;
+ super(id, rs);
}
- protected void finalize() throws Throwable {
- if(mNativeCache != 0) {
- mRS.nTypeFinalDestroy(this);
- mNativeCache = 0;
- }
- super.finalize();
- }
+ @Override
+ void updateFromNative() {
+ // We have 6 integer to obtain mDimX; mDimY; mDimZ;
+ // mDimLOD; mDimFaces; mElement;
+ int[] dataBuffer = new int[6];
+ mRS.nTypeGetNativeData(getID(), dataBuffer);
- 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);
- }
- t.mJavaClass = c;
- return t;
- }
+ mDimX = dataBuffer[0];
+ mDimY = dataBuffer[1];
+ mDimZ = dataBuffer[2];
+ mDimMipmaps = dataBuffer[3] == 1 ? true : false;
+ mDimFaces = dataBuffer[4] == 1 ? true : false;
- public static Type createFromClass(RenderScript rs, Class c, int size, String scriptName) {
- Type t = createFromClass(rs, c, size);
- t.setName(scriptName);
- return t;
+ int elementID = dataBuffer[5];
+ if(elementID != 0) {
+ mElement = new Element(elementID, mRS);
+ mElement.updateFromNative();
+ }
+ calcElementCount();
}
-
+ /**
+ * Builder class for Type.
+ *
+ */
public static class Builder {
RenderScript mRS;
- Entry[] mEntries;
- int mEntryCount;
- Element mElement;
+ int mDimX = 1;
+ int mDimY;
+ int mDimZ;
+ boolean mDimMipmaps;
+ boolean mDimFaces;
- class Entry {
- Dimension mDim;
- int mValue;
- }
+ Element mElement;
+ /**
+ * Create a new builder object.
+ *
+ * @param rs
+ * @param e The element for the type to be created.
+ */
public Builder(RenderScript rs, Element e) {
- if(e.mID == 0) {
- throw new IllegalArgumentException("Invalid element.");
- }
-
+ e.checkValid();
mRS = rs;
- mEntries = new Entry[4];
mElement = e;
}
- public void add(Dimension d, int value) {
+ /**
+ * Add a dimension to the Type.
+ *
+ *
+ * @param d
+ * @param value
+ */
+ public Builder setX(int value) {
if(value < 1) {
- throw new IllegalArgumentException("Values of less than 1 for Dimensions are not valid.");
- }
- if(mEntries.length >= mEntryCount) {
- Entry[] en = new Entry[mEntryCount + 8];
- System.arraycopy(mEntries, 0, en, 0, mEntries.length);
- mEntries = en;
+ throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
}
- mEntries[mEntryCount] = new Entry();
- mEntries[mEntryCount].mDim = d;
- mEntries[mEntryCount].mValue = value;
- mEntryCount++;
+ mDimX = value;
+ return this;
}
- static synchronized Type internalCreate(RenderScript rs, Builder b) {
- rs.nTypeBegin(b.mElement.mID);
- for (int ct=0; ct < b.mEntryCount; ct++) {
- Entry en = b.mEntries[ct];
- rs.nTypeAdd(en.mDim.mID, en.mValue);
+ public Builder setY(int value) {
+ if(value < 1) {
+ throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
}
- int id = rs.nTypeCreate();
- return new Type(id, rs);
+ mDimY = value;
+ return this;
}
- public Type create() {
- Type t = internalCreate(mRS, this);
- t.mElement = mElement;
+ public Builder setMipmaps(boolean value) {
+ mDimMipmaps = value;
+ return this;
+ }
- for(int ct=0; ct < mEntryCount; ct++) {
- if(mEntries[ct].mDim == Dimension.X) {
- t.mDimX = mEntries[ct].mValue;
- }
- if(mEntries[ct].mDim == Dimension.Y) {
- t.mDimY = mEntries[ct].mValue;
+ public Builder setFaces(boolean value) {
+ mDimFaces = value;
+ return this;
+ }
+
+
+ /**
+ * Validate structure and create a new type.
+ *
+ * @return Type
+ */
+ public Type create() {
+ if (mDimZ > 0) {
+ if ((mDimX < 1) || (mDimY < 1)) {
+ throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
}
- if(mEntries[ct].mDim == Dimension.Z) {
- t.mDimZ = mEntries[ct].mValue;
+ if (mDimFaces) {
+ throw new RSInvalidStateException("Cube maps not supported with 3D types.");
}
- if(mEntries[ct].mDim == Dimension.LOD) {
- t.mDimLOD = mEntries[ct].mValue != 0;
+ }
+ if (mDimY > 0) {
+ if (mDimX < 1) {
+ throw new RSInvalidStateException("X dimension required when Y is present.");
}
- if(mEntries[ct].mDim == Dimension.FACE) {
- t.mDimFaces = mEntries[ct].mValue != 0;
+ }
+ if (mDimFaces) {
+ if (mDimY < 1) {
+ throw new RSInvalidStateException("Cube maps require 2D Types.");
}
}
+
+ int id = mRS.nTypeCreate(mElement.getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
+ Type t = new Type(id, mRS);
+ t.mElement = mElement;
+ t.mDimX = mDimX;
+ t.mDimY = mDimY;
+ t.mDimZ = mDimZ;
+ t.mDimMipmaps = mDimMipmaps;
+ t.mDimFaces = mDimFaces;
+
t.calcElementCount();
return t;
}