Merge "Adds enum value for KEYCODE_ASSIST"
diff --git a/api/current.txt b/api/current.txt
index ac367f6..d367a00 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21512,6 +21512,7 @@
public class MockContentResolver extends android.content.ContentResolver {
ctor public MockContentResolver();
+ ctor public MockContentResolver(android.content.Context);
method public void addProvider(java.lang.String, android.content.ContentProvider);
}
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 42c9d34..39539b4 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -321,17 +321,8 @@
@SuppressWarnings("unchecked")
private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags, int userId)
throws RemoteException {
- final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
- PackageInfo lastItem = null;
- ParceledListSlice<PackageInfo> slice;
-
- do {
- final String lastKey = lastItem != null ? lastItem.packageName : null;
- slice = pm.getInstalledPackages(flags, lastKey, userId);
- lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
- } while (!slice.isLastSlice());
-
- return packageInfos;
+ ParceledListSlice<PackageInfo> slice = pm.getInstalledPackages(flags, userId);
+ return slice.getList();
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 60d4363..12716456 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -187,7 +187,8 @@
= new ArrayList<Application>();
// set of instantiated backup agents, keyed by package name
final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
- static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
+ /** Reference to singleton {@link ActivityThread} */
+ private static ActivityThread sCurrentActivityThread;
Instrumentation mInstrumentation;
String mInstrumentationAppDir = null;
String mInstrumentationAppLibraryDir = null;
@@ -1564,7 +1565,7 @@
}
public static ActivityThread currentActivityThread() {
- return sThreadLocal.get();
+ return sCurrentActivityThread;
}
public static String currentPackageName() {
@@ -4894,7 +4895,7 @@
}
private void attach(boolean system) {
- sThreadLocal.set(this);
+ sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 4cea6a0..679c91d 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -228,7 +228,7 @@
}
public int noteOp(int op) {
- return noteOp(op, Process.myUid(), mContext.getPackageName());
+ return noteOp(op, Process.myUid(), mContext.getBasePackageName());
}
public int startOp(int op, int uid, String packageName) {
@@ -252,7 +252,7 @@
}
public int startOp(int op) {
- return startOp(op, Process.myUid(), mContext.getPackageName());
+ return startOp(op, Process.myUid(), mContext.getBasePackageName());
}
public void finishOp(int op, int uid, String packageName) {
@@ -263,6 +263,6 @@
}
public void finishOp(int op) {
- finishOp(op, Process.myUid(), mContext.getPackageName());
+ finishOp(op, Process.myUid(), mContext.getBasePackageName());
}
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 2ef3944..f09c2fe 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -426,17 +426,8 @@
@Override
public List<PackageInfo> getInstalledPackages(int flags, int userId) {
try {
- final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
- PackageInfo lastItem = null;
- ParceledListSlice<PackageInfo> slice;
-
- do {
- final String lastKey = lastItem != null ? lastItem.packageName : null;
- slice = mPM.getInstalledPackages(flags, lastKey, userId);
- lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
- } while (!slice.isLastSlice());
-
- return packageInfos;
+ ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
+ return slice.getList();
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -448,17 +439,9 @@
String[] permissions, int flags) {
final int userId = mContext.getUserId();
try {
- final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
- PackageInfo lastItem = null;
- ParceledListSlice<PackageInfo> slice;
-
- do {
- final String lastKey = lastItem != null ? lastItem.packageName : null;
- slice = mPM.getPackagesHoldingPermissions(permissions, flags, lastKey, userId);
- lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
- } while (!slice.isLastSlice());
-
- return packageInfos;
+ ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
+ permissions, flags, userId);
+ return slice.getList();
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -469,17 +452,8 @@
public List<ApplicationInfo> getInstalledApplications(int flags) {
final int userId = mContext.getUserId();
try {
- final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
- ApplicationInfo lastItem = null;
- ParceledListSlice<ApplicationInfo> slice;
-
- do {
- final String lastKey = lastItem != null ? lastItem.packageName : null;
- slice = mPM.getInstalledApplications(flags, lastKey, userId);
- lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
- } while (!slice.isLastSlice());
-
- return applicationInfos;
+ ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
+ return slice.getList();
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4925bf1..fd4389e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -628,6 +628,12 @@
return "android";
}
+ /** @hide */
+ @Override
+ public String getBasePackageName() {
+ return mBasePackageName != null ? mBasePackageName : getPackageName();
+ }
+
@Override
public ApplicationInfo getApplicationInfo() {
if (mPackageInfo != null) {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 32e40ee..26dc60d 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1085,6 +1085,7 @@
values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1);
values.putNull(Downloads.Impl._DATA);
values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
+ values.put(Downloads.Impl.COLUMN_FAILED_CONNECTIONS, 0);
mResolver.update(mBaseUri, values, getWhereClauseForIds(ids), getWhereArgsForIds(ids));
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e0856ae..39186c6 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -27,6 +27,7 @@
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
+import android.os.Looper;
import android.os.MessageQueue;
import android.os.PerformanceCollector;
import android.os.Process;
@@ -1637,7 +1638,7 @@
}
private final void validateNotAppThread() {
- if (ActivityThread.currentActivityThread() != null) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
throw new RuntimeException(
"This method can not be called from the main application thread");
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 51c9aa5..63c97ba 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -20,6 +20,7 @@
import android.accounts.Account;
import android.app.ActivityManagerNative;
+import android.app.ActivityThread;
import android.app.AppGlobals;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
@@ -206,8 +207,8 @@
private final Random mRandom = new Random(); // guarded by itself
public ContentResolver(Context context) {
- mContext = context;
- mPackageName = context.getPackageName();
+ mContext = context != null ? context : ActivityThread.currentApplication();
+ mPackageName = context.getBasePackageName();
}
/** @hide */
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 14f2847..f7c28b6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -418,6 +418,9 @@
/** Return the name of this application's package. */
public abstract String getPackageName();
+ /** @hide Return the name of the base context this context is derived from. */
+ public abstract String getBasePackageName();
+
/** Return the full application info for this context's package. */
public abstract ApplicationInfo getApplicationInfo();
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6a61884..b63f45e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -135,6 +135,12 @@
return mBase.getPackageName();
}
+ /** @hide */
+ @Override
+ public String getBasePackageName() {
+ return mBase.getBasePackageName();
+ }
+
@Override
public ApplicationInfo getApplicationInfo() {
return mBase.getApplicationInfo();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 4c9c278..0445b39 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -127,7 +127,7 @@
* limit that kicks in when flags are included that bloat up the data
* returned.
*/
- ParceledListSlice getInstalledPackages(int flags, in String lastRead, in int userId);
+ ParceledListSlice getInstalledPackages(int flags, in int userId);
/**
* This implements getPackagesHoldingPermissions via a "last returned row"
@@ -136,7 +136,7 @@
* returned.
*/
ParceledListSlice getPackagesHoldingPermissions(in String[] permissions,
- int flags, in String lastRead, int userId);
+ int flags, int userId);
/**
* This implements getInstalledApplications via a "last returned row"
@@ -144,7 +144,7 @@
* limit that kicks in when flags are included that bloat up the data
* returned.
*/
- ParceledListSlice getInstalledApplications(int flags, in String lastRead, int userId);
+ ParceledListSlice getInstalledApplications(int flags, int userId);
/**
* Retrieve all applications that are marked as persistent.
diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java
index f3a98db4..8a43472 100644
--- a/core/java/android/content/pm/ParceledListSlice.java
+++ b/core/java/android/content/pm/ParceledListSlice.java
@@ -16,44 +16,92 @@
package android.content.pm;
+import android.os.Binder;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+import java.util.ArrayList;
import java.util.List;
/**
- * Builds up a parcel that is discarded when written to another parcel or
- * written to a list. This is useful for API that sends huge lists across a
- * Binder that may be larger than the IPC limit.
+ * Transfer a large list of Parcelable objects across an IPC. Splits into
+ * multiple transactions if needed.
*
* @hide
*/
public class ParceledListSlice<T extends Parcelable> implements Parcelable {
+ private static String TAG = "ParceledListSlice";
+ private static boolean DEBUG = false;
+
/*
* TODO get this number from somewhere else. For now set it to a quarter of
* the 1MB limit.
*/
private static final int MAX_IPC_SIZE = 256 * 1024;
+ private static final int MAX_FIRST_IPC_SIZE = MAX_IPC_SIZE / 2;
- private Parcel mParcel;
+ private final List<T> mList;
- private int mNumItems;
-
- private boolean mIsLastSlice;
-
- public ParceledListSlice() {
- mParcel = Parcel.obtain();
+ public ParceledListSlice(List<T> list) {
+ mList = list;
}
- private ParceledListSlice(Parcel p, int numItems, boolean lastSlice) {
- mParcel = p;
- mNumItems = numItems;
- mIsLastSlice = lastSlice;
+ private ParceledListSlice(Parcel p, ClassLoader loader) {
+ final int N = p.readInt();
+ mList = new ArrayList<T>(N);
+ if (DEBUG) Log.d(TAG, "Retrieving " + N + " items");
+ if (N <= 0) {
+ return;
+ }
+ Parcelable.Creator<T> creator = p.readParcelableCreator(loader);
+ int i = 0;
+ while (i < N) {
+ if (p.readInt() == 0) {
+ break;
+ }
+ mList.add(p.readCreator(creator, loader));
+ if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
+ i++;
+ }
+ if (i >= N) {
+ return;
+ }
+ final IBinder retriever = p.readStrongBinder();
+ while (i < N) {
+ if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInt(i);
+ try {
+ retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e);
+ return;
+ }
+ while (i < N && reply.readInt() != 0) {
+ mList.add(reply.readCreator(creator, loader));
+ if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
+ i++;
+ }
+ reply.recycle();
+ data.recycle();
+ }
+ }
+
+ public List<T> getList() {
+ return mList;
}
@Override
public int describeContents() {
- return 0;
+ int contents = 0;
+ for (int i=0; i<mList.size(); i++) {
+ contents |= mList.get(i).describeContents();
+ }
+ return contents;
}
/**
@@ -63,104 +111,59 @@
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mNumItems);
- dest.writeInt(mIsLastSlice ? 1 : 0);
-
- if (mNumItems > 0) {
- final int parcelSize = mParcel.dataSize();
- dest.writeInt(parcelSize);
- dest.appendFrom(mParcel, 0, parcelSize);
+ final int N = mList.size();
+ final int callFlags = flags;
+ dest.writeInt(N);
+ if (DEBUG) Log.d(TAG, "Writing " + N + " items");
+ if (N > 0) {
+ dest.writeParcelableCreator(mList.get(0));
+ int i = 0;
+ while (i < N && dest.dataSize() < MAX_FIRST_IPC_SIZE) {
+ dest.writeInt(1);
+ mList.get(i).writeToParcel(dest, callFlags);
+ if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
+ i++;
+ }
+ if (i < N) {
+ dest.writeInt(0);
+ Binder retriever = new Binder() {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ if (code != FIRST_CALL_TRANSACTION) {
+ return super.onTransact(code, data, reply, flags);
+ }
+ int i = data.readInt();
+ if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
+ while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
+ reply.writeInt(1);
+ mList.get(i).writeToParcel(reply, callFlags);
+ if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
+ i++;
+ }
+ if (i < N) {
+ if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N);
+ reply.writeInt(0);
+ }
+ return true;
+ }
+ };
+ if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever);
+ dest.writeStrongBinder(retriever);
+ }
}
-
- mNumItems = 0;
- mParcel.recycle();
- mParcel = null;
- }
-
- /**
- * Appends a parcel to this list slice.
- *
- * @param item Parcelable item to append to this list slice
- * @return true when the list slice is full and should not be appended to
- * anymore
- */
- public boolean append(T item) {
- if (mParcel == null) {
- throw new IllegalStateException("ParceledListSlice has already been recycled");
- }
-
- item.writeToParcel(mParcel, PARCELABLE_WRITE_RETURN_VALUE);
- mNumItems++;
-
- return mParcel.dataSize() > MAX_IPC_SIZE;
- }
-
- /**
- * Populates a list and discards the internal state of the
- * ParceledListSlice in the process. The instance should
- * not be used anymore.
- *
- * @param list list to insert items from this slice.
- * @param creator creator that knows how to unparcel the
- * target object type.
- * @return the last item inserted into the list or null if none.
- */
- public T populateList(List<T> list, Creator<T> creator) {
- mParcel.setDataPosition(0);
-
- T item = null;
- for (int i = 0; i < mNumItems; i++) {
- item = creator.createFromParcel(mParcel);
- list.add(item);
- }
-
- mParcel.recycle();
- mParcel = null;
-
- return item;
- }
-
- /**
- * Sets whether this is the last list slice in the series.
- *
- * @param lastSlice
- */
- public void setLastSlice(boolean lastSlice) {
- mIsLastSlice = lastSlice;
- }
-
- /**
- * Returns whether this is the last slice in a series of slices.
- *
- * @return true if this is the last slice in the series.
- */
- public boolean isLastSlice() {
- return mIsLastSlice;
}
@SuppressWarnings("unchecked")
- public static final Parcelable.Creator<ParceledListSlice> CREATOR =
- new Parcelable.Creator<ParceledListSlice>() {
+ public static final Parcelable.ClassLoaderCreator<ParceledListSlice> CREATOR =
+ new Parcelable.ClassLoaderCreator<ParceledListSlice>() {
public ParceledListSlice createFromParcel(Parcel in) {
- final int numItems = in.readInt();
- final boolean lastSlice = in.readInt() == 1;
+ return new ParceledListSlice(in, null);
+ }
- if (numItems > 0) {
- final int parcelSize = in.readInt();
-
- // Advance within this Parcel
- int offset = in.dataPosition();
- in.setDataPosition(offset + parcelSize);
-
- Parcel p = Parcel.obtain();
- p.setDataPosition(0);
- p.appendFrom(in, offset, parcelSize);
- p.setDataPosition(0);
-
- return new ParceledListSlice(p, numItems, lastSlice);
- } else {
- return new ParceledListSlice();
- }
+ @Override
+ public ParceledListSlice createFromParcel(Parcel in, ClassLoader loader) {
+ return new ParceledListSlice(in, loader);
}
public ParceledListSlice[] newArray(int size) {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index d69fef0..31d323b 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1254,6 +1254,12 @@
p.writeToParcel(this, parcelableFlags);
}
+ /** @hide */
+ public final void writeParcelableCreator(Parcelable p) {
+ String name = p.getClass().getName();
+ writeString(name);
+ }
+
/**
* Write a generic serializable object in to a Parcel. It is strongly
* recommended that this method be avoided, since the serialization
@@ -2046,6 +2052,28 @@
* was an error trying to instantiate the Parcelable.
*/
public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
+ Parcelable.Creator<T> creator = readParcelableCreator(loader);
+ if (creator == null) {
+ return null;
+ }
+ if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+ return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
+ }
+ return creator.createFromParcel(this);
+ }
+
+ /** @hide */
+ public final <T extends Parcelable> T readCreator(Parcelable.Creator<T> creator,
+ ClassLoader loader) {
+ if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+ return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
+ }
+ return creator.createFromParcel(this);
+ }
+
+ /** @hide */
+ public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
+ ClassLoader loader) {
String name = readString();
if (name == null) {
return null;
@@ -2101,10 +2129,7 @@
}
}
- if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
- return ((Parcelable.ClassLoaderCreator<T>)creator).createFromParcel(this, loader);
- }
- return creator.createFromParcel(this);
+ return creator;
}
/**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 05099fb..facab4c 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -806,7 +806,15 @@
*/
public static final native void setProcessGroup(int pid, int group)
throws IllegalArgumentException, SecurityException;
-
+
+ /**
+ * Return the scheduling group of requested process.
+ *
+ * @hide
+ */
+ public static final native int getProcessGroup(int pid)
+ throws IllegalArgumentException, SecurityException;
+
/**
* Set the priority of the calling thread, based on Linux priorities. See
* {@link #setThreadPriority(int, int)} for more information.
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 54ea385..08eba4f 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -38,7 +38,7 @@
}
public SystemVibrator(Context context) {
- mPackageName = context.getPackageName();
+ mPackageName = context.getBasePackageName();
mService = IVibratorService.Stub.asInterface(
ServiceManager.getService("vibrator"));
}
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 31ad12b..9999760 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -407,6 +407,9 @@
*/
public static final String COLUMN_LAST_UPDATESRC = "lastUpdateSrc";
+ /** The column that is used to count retries */
+ public static final String COLUMN_FAILED_CONNECTIONS = "numfailed";
+
/**
* default value for {@link #COLUMN_LAST_UPDATESRC}.
* This value is used when this column's value is not relevant.
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
new file mode 100644
index 0000000..34b6126
--- /dev/null
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2007 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.util;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Arrays;
+
+/**
+ * Map of {@code long} to {@code long}. Unlike a normal array of longs, there
+ * can be gaps in the indices. It is intended to be more efficient than using a
+ * {@code HashMap}.
+ *
+ * @hide
+ */
+public class LongSparseLongArray implements Cloneable {
+ private long[] mKeys;
+ private long[] mValues;
+ private int mSize;
+
+ /**
+ * Creates a new SparseLongArray containing no mappings.
+ */
+ public LongSparseLongArray() {
+ this(10);
+ }
+
+ /**
+ * Creates a new SparseLongArray containing no mappings that will not
+ * require any additional memory allocation to store the specified
+ * number of mappings.
+ */
+ public LongSparseLongArray(int initialCapacity) {
+ initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+
+ mKeys = new long[initialCapacity];
+ mValues = new long[initialCapacity];
+ mSize = 0;
+ }
+
+ @Override
+ public LongSparseLongArray clone() {
+ LongSparseLongArray clone = null;
+ try {
+ clone = (LongSparseLongArray) super.clone();
+ clone.mKeys = mKeys.clone();
+ clone.mValues = mValues.clone();
+ } catch (CloneNotSupportedException cnse) {
+ /* ignore */
+ }
+ return clone;
+ }
+
+ /**
+ * Gets the long mapped from the specified key, or <code>0</code>
+ * if no such mapping has been made.
+ */
+ public long get(long key) {
+ return get(key, 0);
+ }
+
+ /**
+ * Gets the long mapped from the specified key, or the specified value
+ * if no such mapping has been made.
+ */
+ public long get(long key, long valueIfKeyNotFound) {
+ int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+
+ if (i < 0) {
+ return valueIfKeyNotFound;
+ } else {
+ return mValues[i];
+ }
+ }
+
+ /**
+ * Removes the mapping from the specified key, if there was any.
+ */
+ public void delete(long key) {
+ int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+
+ if (i >= 0) {
+ removeAt(i);
+ }
+ }
+
+ /**
+ * Removes the mapping at the given index.
+ */
+ public void removeAt(int index) {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
+ mSize--;
+ }
+
+ /**
+ * Adds a mapping from the specified key to the specified value,
+ * replacing the previous mapping from the specified key if there
+ * was one.
+ */
+ public void put(long key, long value) {
+ int i = Arrays.binarySearch(mKeys, 0, mSize, key);
+
+ if (i >= 0) {
+ mValues[i] = value;
+ } else {
+ i = ~i;
+
+ if (mSize >= mKeys.length) {
+ growKeyAndValueArrays(mSize + 1);
+ }
+
+ if (mSize - i != 0) {
+ System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+ System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+ }
+
+ mKeys[i] = key;
+ mValues[i] = value;
+ mSize++;
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings that this SparseIntArray
+ * currently stores.
+ */
+ public int size() {
+ return mSize;
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the key from the <code>index</code>th key-value mapping that this
+ * SparseLongArray stores.
+ */
+ public long keyAt(int index) {
+ return mKeys[index];
+ }
+
+ /**
+ * Given an index in the range <code>0...size()-1</code>, returns
+ * the value from the <code>index</code>th key-value mapping that this
+ * SparseLongArray stores.
+ */
+ public long valueAt(int index) {
+ return mValues[index];
+ }
+
+ /**
+ * Returns the index for which {@link #keyAt} would return the
+ * specified key, or a negative number if the specified
+ * key is not mapped.
+ */
+ public int indexOfKey(long key) {
+ return Arrays.binarySearch(mKeys, 0, mSize, key);
+ }
+
+ /**
+ * Returns an index for which {@link #valueAt} would return the
+ * specified key, or a negative number if no keys map to the
+ * specified value.
+ * Beware that this is a linear search, unlike lookups by key,
+ * and that multiple keys can map to the same value and this will
+ * find only one of them.
+ */
+ public int indexOfValue(long value) {
+ for (int i = 0; i < mSize; i++)
+ if (mValues[i] == value)
+ return i;
+
+ return -1;
+ }
+
+ /**
+ * Removes all key-value mappings from this SparseIntArray.
+ */
+ public void clear() {
+ mSize = 0;
+ }
+
+ /**
+ * Puts a key/value pair into the array, optimizing for the case where
+ * the key is greater than all existing keys in the array.
+ */
+ public void append(long key, long value) {
+ if (mSize != 0 && key <= mKeys[mSize - 1]) {
+ put(key, value);
+ return;
+ }
+
+ int pos = mSize;
+ if (pos >= mKeys.length) {
+ growKeyAndValueArrays(pos + 1);
+ }
+
+ mKeys[pos] = key;
+ mValues[pos] = value;
+ mSize = pos + 1;
+ }
+
+ private void growKeyAndValueArrays(int minNeededSize) {
+ int n = ArrayUtils.idealLongArraySize(minNeededSize);
+
+ long[] nkeys = new long[n];
+ long[] nvalues = new long[n];
+
+ System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+ System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+
+ mKeys = nkeys;
+ mValues = nvalues;
+ }
+}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 0d45bbc..2b4260d 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -173,17 +173,6 @@
public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";
/**
- * Turn on to allow region clipping (see
- * {@link android.graphics.Canvas#clipPath(android.graphics.Path)} and
- * {@link android.graphics.Canvas#clipRegion(android.graphics.Region)}.
- *
- * When this option is turned on a stencil buffer is always required.
- * If this option is off a stencil buffer is only created when the overdraw
- * debugging mode is turned on.
- */
- private static final boolean REGION_CLIPPING_ENABLED = false;
-
- /**
* A process can set this flag to false to prevent the use of hardware
* rendering.
*
@@ -885,15 +874,6 @@
if (value != mShowOverdraw) {
changed = true;
mShowOverdraw = value;
-
- if (!REGION_CLIPPING_ENABLED) {
- if (surface != null && isEnabled()) {
- if (validate()) {
- sEglConfig = loadEglConfig();
- invalidate(surface);
- }
- }
- }
}
if (nLoadProperties()) {
@@ -1764,9 +1744,8 @@
@Override
int[] getConfig(boolean dirtyRegions) {
- //noinspection PointlessBooleanExpression
- final int stencilSize = mShowOverdraw || REGION_CLIPPING_ENABLED ?
- GLES20Canvas.getStencilSize() : 0;
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ final int stencilSize = GLES20Canvas.getStencilSize();
final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
return new int[] {
diff --git a/core/java/android/view/SimulatedTrackball.java b/core/java/android/view/SimulatedDpad.java
similarity index 83%
rename from core/java/android/view/SimulatedTrackball.java
rename to core/java/android/view/SimulatedDpad.java
index 4ab557a..0a37fdd 100644
--- a/core/java/android/view/SimulatedTrackball.java
+++ b/core/java/android/view/SimulatedDpad.java
@@ -28,15 +28,15 @@
import android.util.Log;
/**
- * This class creates trackball events from touchpad events.
+ * This class creates DPAD events from touchpad events.
*
* @see ViewRootImpl
*/
//TODO: Make this class an internal class of ViewRootImpl.java
-class SimulatedTrackball {
+class SimulatedDpad {
- private static final String TAG = "SimulatedTrackball";
+ private static final String TAG = "SimulatedDpad";
// Maximum difference in milliseconds between the down and up of a touch
// event for it to be considered a tap
@@ -97,7 +97,7 @@
// How quickly the repeated events die off
private float mFlickDecay;
- public SimulatedTrackball(Context context) {
+ public SimulatedDpad(Context context) {
mDistancePerTick = SystemProperties.getInt("persist.vr_dist_tick", 64);
mDistancePerTickSquared = mDistancePerTick * mDistancePerTick;
mMaxRepeatDelay = SystemProperties.getInt("persist.vr_repeat_delay", 300);
@@ -140,7 +140,11 @@
}
};
- public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) {
+ public void updateTouchPad(ViewRootImpl viewroot, MotionEvent event,
+ boolean synthesizeNewKeys) {
+ if (!synthesizeNewKeys) {
+ mHandler.removeMessages(MSG_FLICK);
+ }
// Store what time the touchpad event occurred
final long time = SystemClock.uptimeMillis();
switch (event.getAction()) {
@@ -159,8 +163,9 @@
mEdgeSwipePossible = true;
}
// Clear any flings
- mHandler.removeMessages(MSG_FLICK);
-
+ if (synthesizeNewKeys) {
+ mHandler.removeMessages(MSG_FLICK);
+ }
break;
case MotionEvent.ACTION_MOVE:
// Determine whether the move is slop or an intentional move
@@ -226,12 +231,16 @@
while (dominantAxis * dominantAxis > mDistancePerTickSquared) {
repeatCount++;
dominantAxis -= sign * mDistancePerTick;
- viewroot.enqueueInputEvent(new KeyEvent(time, time,
- KeyEvent.ACTION_DOWN, key, 0, event.getMetaState(),
- event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK, event.getSource()));
- viewroot.enqueueInputEvent(new KeyEvent(time, time,
- KeyEvent.ACTION_UP, key, 0, event.getMetaState(),
- event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK, event.getSource()));
+ if (synthesizeNewKeys) {
+ viewroot.enqueueInputEvent(new KeyEvent(time, time,
+ KeyEvent.ACTION_DOWN, key, 0, event.getMetaState(),
+ event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK,
+ event.getSource()));
+ viewroot.enqueueInputEvent(new KeyEvent(time, time,
+ KeyEvent.ACTION_UP, key, 0, event.getMetaState(),
+ event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK,
+ event.getSource()));
+ }
}
// Save new axis values
mAccumulatedX = isXAxis ? dominantAxis : 0;
@@ -244,18 +253,16 @@
break;
case MotionEvent.ACTION_UP:
if (time - mLastTouchPadStartTimeMs < MAX_TAP_TIME && mAlwaysInTapRegion) {
- // Trackball Down
- MotionEvent trackballEvent = MotionEvent.obtain(mLastTouchPadStartTimeMs, time,
- MotionEvent.ACTION_DOWN, 0, 0, 0, 0, event.getMetaState(),
- 10f, 10f, event.getDeviceId(), 0);
- trackballEvent.setSource(InputDevice.SOURCE_TRACKBALL);
- viewroot.enqueueInputEvent(trackballEvent);
- // Trackball Release
- trackballEvent = MotionEvent.obtain(mLastTouchPadStartTimeMs, time,
- MotionEvent.ACTION_UP, 0, 0, 0, 0, event.getMetaState(),
- 10f, 10f, event.getDeviceId(), 0);
- trackballEvent.setSource(InputDevice.SOURCE_TRACKBALL);
- viewroot.enqueueInputEvent(trackballEvent);
+ if (synthesizeNewKeys) {
+ viewroot.enqueueInputEvent(new KeyEvent(mLastTouchPadStartTimeMs, time,
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0,
+ event.getMetaState(), event.getDeviceId(), 0,
+ KeyEvent.FLAG_FALLBACK, event.getSource()));
+ viewroot.enqueueInputEvent(new KeyEvent(mLastTouchPadStartTimeMs, time,
+ KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0,
+ event.getMetaState(), event.getDeviceId(), 0,
+ KeyEvent.FLAG_FALLBACK, event.getSource()));
+ }
} else {
float xMoveSquared = mLastMoveX * mLastMoveX;
float yMoveSquared = mLastMoveY * mLastMoveY;
@@ -267,10 +274,12 @@
mLastSource = event.getSource();
mLastMetaState = event.getMetaState();
- Message message = Message.obtain(mHandler, MSG_FLICK,
- mKeySendRateMs, mLastKeySent, viewroot);
- message.setAsynchronous(true);
- mHandler.sendMessageDelayed(message, mKeySendRateMs);
+ if (synthesizeNewKeys) {
+ Message message = Message.obtain(mHandler, MSG_FLICK,
+ mKeySendRateMs, mLastKeySent, viewroot);
+ message.setAsynchronous(true);
+ mHandler.sendMessageDelayed(message, mKeySendRateMs);
+ }
}
}
mEdgeSwipePossible = false;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1ae69fea..3faac40 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -144,7 +144,7 @@
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
- final SimulatedTrackball mSimulatedTrackball;
+ final SimulatedDpad mSimulatedDpad;
int mLastJoystickXDirection;
int mLastJoystickYDirection;
@@ -391,7 +391,7 @@
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
loadSystemProperties();
- mSimulatedTrackball = new SimulatedTrackball(context);
+ mSimulatedDpad = new SimulatedDpad(context);
}
/**
@@ -3535,8 +3535,7 @@
if (isJoystick) {
updateJoystickDirection(event, false);
} else if (isTouchPad) {
- //Convert TouchPad motion into a TrackBall event
- mSimulatedTrackball.updateTrackballDirection(this, event);
+ mSimulatedDpad.updateTouchPad(this, event, false);
}
return EVENT_NOT_HANDLED;
}
@@ -3546,8 +3545,7 @@
if (isJoystick) {
updateJoystickDirection(event, false);
} else if (isTouchPad) {
- //Convert TouchPad motion into a TrackBall event
- mSimulatedTrackball.updateTrackballDirection(this, event);
+ mSimulatedDpad.updateTouchPad(this, event, false);
}
return EVENT_HANDLED;
}
@@ -3559,8 +3557,7 @@
return EVENT_HANDLED;
}
if (isTouchPad) {
- //Convert TouchPad motion into a TrackBall event
- mSimulatedTrackball.updateTrackballDirection(this, event);
+ mSimulatedDpad.updateTouchPad(this, event, true);
return EVENT_HANDLED;
}
return EVENT_NOT_HANDLED;
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index 1a4ccfa..d7a0b60 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -33,12 +33,15 @@
import android.widget.EditText;
import android.widget.TextView;
-class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
- View.OnClickListener {
+/**
+ * @hide
+ */
+public class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
+ View.OnClickListener, WebView.FindListener {
private View mCustomView;
private EditText mEditText;
private TextView mMatches;
- private WebViewClassic mWebView;
+ private WebView mWebView;
private InputMethodManager mInput;
private Resources mResources;
private boolean mMatchesFound;
@@ -46,7 +49,7 @@
private int mActiveMatchIndex;
private ActionMode mActionMode;
- FindActionModeCallback(Context context) {
+ public FindActionModeCallback(Context context) {
mCustomView = LayoutInflater.from(context).inflate(
com.android.internal.R.layout.webview_find, null);
mEditText = (EditText) mCustomView.findViewById(
@@ -61,7 +64,7 @@
mResources = context.getResources();
}
- void finish() {
+ public void finish() {
mActionMode.finish();
}
@@ -69,7 +72,7 @@
* Place text in the text field so it can be searched for. Need to press
* the find next or find previous button to find all of the matches.
*/
- void setText(String text) {
+ public void setText(String text) {
mEditText.setText(text);
Spannable span = (Spannable) mEditText.getText();
int length = span.length();
@@ -84,15 +87,23 @@
}
/*
- * Set the WebView to search. Must be non null, and set before calling
- * startActionMode.
+ * Set the WebView to search. Must be non null.
*/
- void setWebView(WebViewClassic webView) {
+ public void setWebView(WebView webView) {
if (null == webView) {
throw new AssertionError("WebView supplied to "
+ "FindActionModeCallback cannot be null");
}
mWebView = webView;
+ mWebView.setFindDialogFindListener(this);
+ }
+
+ @Override
+ public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
+ boolean isDoneCounting) {
+ if (isDoneCounting) {
+ updateMatchCount(activeMatchOrdinal, numberOfMatches, numberOfMatches == 0);
+ }
}
/*
@@ -121,7 +132,7 @@
/*
* Highlight all the instances of the string from mEditText in mWebView.
*/
- void findAll() {
+ public void findAll() {
if (mWebView == null) {
throw new AssertionError(
"No WebView for FindActionModeCallback::findAll");
@@ -208,7 +219,8 @@
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
mWebView.notifyFindDialogDismissed();
- mInput.hideSoftInputFromWindow(mWebView.getWebView().getWindowToken(), 0);
+ mWebView.setFindDialogFindListener(null);
+ mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
}
@Override
@@ -222,7 +234,7 @@
throw new AssertionError(
"No WebView for FindActionModeCallback::onActionItemClicked");
}
- mInput.hideSoftInputFromWindow(mWebView.getWebView().getWindowToken(), 0);
+ mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
switch(item.getItemId()) {
case com.android.internal.R.id.find_prev:
findNext(false);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 1abea2b..5412400 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1329,7 +1329,8 @@
*/
public void setFindListener(FindListener listener) {
checkThread();
- mProvider.setFindListener(listener);
+ setupFindListenerIfNeeded();
+ mFindListener.mUserFindListener = listener;
}
/**
@@ -1850,11 +1851,60 @@
}
//-------------------------------------------------------------------------
+ // Package-private internal stuff
+ //-------------------------------------------------------------------------
+
+ // Only used by android.webkit.FindActionModeCallback.
+ void setFindDialogFindListener(FindListener listener) {
+ checkThread();
+ setupFindListenerIfNeeded();
+ mFindListener.mFindDialogFindListener = listener;
+ }
+
+ // Only used by android.webkit.FindActionModeCallback.
+ void notifyFindDialogDismissed() {
+ checkThread();
+ mProvider.notifyFindDialogDismissed();
+ }
+
+ //-------------------------------------------------------------------------
// Private internal stuff
//-------------------------------------------------------------------------
private WebViewProvider mProvider;
+ /**
+ * In addition to the FindListener that the user may set via the WebView.setFindListener
+ * API, FindActionModeCallback will register it's own FindListener. We keep them separate
+ * via this class so that that the two FindListeners can potentially exist at once.
+ */
+ private class FindListenerDistributor implements FindListener {
+ private FindListener mFindDialogFindListener;
+ private FindListener mUserFindListener;
+
+ @Override
+ public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
+ boolean isDoneCounting) {
+ if (mFindDialogFindListener != null) {
+ mFindDialogFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches,
+ isDoneCounting);
+ }
+
+ if (mUserFindListener != null) {
+ mUserFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches,
+ isDoneCounting);
+ }
+ }
+ }
+ private FindListenerDistributor mFindListener;
+
+ private void setupFindListenerIfNeeded() {
+ if (mFindListener == null) {
+ mFindListener = new FindListenerDistributor();
+ mProvider.setFindListener(mFindListener);
+ }
+ }
+
private void ensureProviderCreated() {
checkThread();
if (mProvider == null) {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 9a83964..a867d39 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -3668,7 +3668,7 @@
mCachedOverlappingActionModeHeight = -1;
mFindCallback = callback;
setFindIsUp(true);
- mFindCallback.setWebView(this);
+ mFindCallback.setWebView(getWebView());
if (showIme) {
mFindCallback.showSoftInput();
} else if (text != null) {
@@ -3770,7 +3770,8 @@
/**
* Called when the find ActionMode ends.
*/
- void notifyFindDialogDismissed() {
+ @Override
+ public void notifyFindDialogDismissed() {
mFindCallback = null;
mCachedOverlappingActionModeHeight = -1;
if (mWebViewCore == null) {
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 1020634..fa17ab9 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -240,7 +240,7 @@
public View findHierarchyView(String className, int hashCode);
//-------------------------------------------------------------------------
- // Provider glue methods
+ // Provider internal methods
//-------------------------------------------------------------------------
/**
@@ -255,6 +255,12 @@
*/
/* package */ ScrollDelegate getScrollDelegate();
+ /**
+ * Only used by FindActionModeCallback to inform providers that the find dialog has
+ * been dismissed.
+ */
+ public void notifyFindDialogDismissed();
+
//-------------------------------------------------------------------------
// View / ViewGroup delegation methods
//-------------------------------------------------------------------------
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index df0fcd9..6429aa4 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -106,7 +106,7 @@
}
ThreadGroup group = Thread.currentThread().getThreadGroup();
- SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group);
+ SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupThreadSet(group);
samplingProfiler = new SamplingProfiler(samplingProfilerDepth, threadSet);
samplingProfiler.start(samplingProfilerMilliseconds);
startMillis = System.currentTimeMillis();
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index 1752e5b..ce31c5b 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -62,7 +62,9 @@
uint16_t glyph = codepoint;
paint->getTextWidths(&glyph, sizeof(glyph), &skWidth, &skBounds);
+#if DEBUG_GLYPHS
ALOGD("returned glyph for %i: width = %f", codepoint, skWidth);
+#endif
if (width)
*width = SkScalarToHBFixed(skWidth);
if (extents) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index d7df402..6d3c878 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -810,6 +810,9 @@
case HB_SCRIPT_CYRILLIC:
case HB_SCRIPT_HANGUL:
case HB_SCRIPT_INHERITED:
+ case HB_SCRIPT_HAN:
+ case HB_SCRIPT_KATAKANA:
+ case HB_SCRIPT_HIRAGANA:
return false;
default:
return true;
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 0290857..5d32328 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -268,6 +268,15 @@
closedir(d);
}
+jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid)
+{
+ SchedPolicy sp;
+ if (get_sched_policy(pid, &sp) != 0) {
+ signalExceptionForGroupError(env, errno);
+ }
+ return (int) sp;
+}
+
static void android_os_Process_setCanSelfBackground(JNIEnv* env, jobject clazz, jboolean bgOk) {
// Establishes the calling thread as illegal to put into the background.
// Typically used only for the system process's main looper.
@@ -991,7 +1000,8 @@
{"setThreadPriority", "(I)V", (void*)android_os_Process_setCallingThreadPriority},
{"getThreadPriority", "(I)I", (void*)android_os_Process_getThreadPriority},
{"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup},
- {"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup},
+ {"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup},
+ {"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup},
{"setOomAdj", "(II)Z", (void*)android_os_Process_setOomAdj},
{"setArgV0", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},
{"setUid", "(I)I", (void*)android_os_Process_setUid},
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5b8200e..9fa0a06 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -316,7 +316,7 @@
<string name="permlab_updateBatteryStats" msgid="3719689764536379557">"የባትሪ ስታስቲክስን ይቀይራል"</string>
<string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"የተሰበሰቡ የባትሪ ስታስቲክሶችን እንዲቀይር ለመተግበሪያው ያስችለዋል። ለመደበኛ መተግበሪያዎች ጥቅም አይደለም።"</string>
<string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"የመተግበሪያ ክወናዎች ስታቲስቲክስን ይቀይሩ"</string>
- <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"መተግበሪያው የተሰበሰቡ የክወና ስታስቲክሶችን እንዲቀይር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች ጥቅም ያልሆነ።"</string>
+ <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"መተግበሪያው የተሰበሰቡ የክወና ስታስቲክሶችን እንዲቀይር ይፈቅድሎታል። ለመደበኛ መተግበሪያዎች ጥቅም ያልሆነ።"</string>
<string name="permlab_backup" msgid="470013022865453920">"የስርዓት መጠባበቂያን ተቆጣጠር እናእነበረበት መልስ"</string>
<string name="permdesc_backup" msgid="6912230525140589891">"የስርዓቱን ምትኬ እና እንደነበር መልስ መንገዶችን ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ፡፡ በመደበኛ መተግበሪያዎች ለመጠቀም አይሆንም፡፡"</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"የሙሉ መጠበቂያ ወይም እነበረበት መልስ ከዋኝ አረጋግጥ"</string>
@@ -943,7 +943,7 @@
</plurals>
<plurals name="in_num_hours">
<item quantity="one" msgid="7164353342477769999">"በ 1 ሰዓት"</item>
- <item quantity="other" msgid="547290677353727389">"በ <xliff:g id="COUNT">%d</xliff:g> ሰዓታት"</item>
+ <item quantity="other" msgid="547290677353727389">"በ <xliff:g id="COUNT">%d</xliff:g> ሰዓቶች"</item>
</plurals>
<plurals name="in_num_days">
<item quantity="one" msgid="5413088743009839518">"ነገ"</item>
@@ -975,7 +975,7 @@
</plurals>
<plurals name="abbrev_in_num_hours">
<item quantity="one" msgid="3274708118124045246">"በ 1 ሰዓት"</item>
- <item quantity="other" msgid="3705373766798013406">"በ <xliff:g id="COUNT">%d</xliff:g> ሰዓታት"</item>
+ <item quantity="other" msgid="3705373766798013406">"በ <xliff:g id="COUNT">%d</xliff:g> ሰዓቶች"</item>
</plurals>
<plurals name="abbrev_in_num_days">
<item quantity="one" msgid="2178576254385739855">"ነገ"</item>
@@ -1006,7 +1006,7 @@
</plurals>
<plurals name="duration_hours">
<item quantity="one" msgid="8917467491248809972">"1 ሰዓት"</item>
- <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> ሰዓታት"</item>
+ <item quantity="other" msgid="3863962854246773930">"<xliff:g id="COUNT">%d</xliff:g> ሰዓቶች"</item>
</plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"የቪዲዮ ችግር"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ይቅርታ፣ ይህ ቪዲዮ በዚህ መሣሪያ ለመልቀቅ ትክክል አይደለም።"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 590dfee..8fc1450 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -315,8 +315,8 @@
<string name="permdesc_batteryStats" msgid="5897346582882915114">"Permite a una aplicación leer los datos actuales de uso de batería de bajo nivel. Puede permitir a la aplicación buscar información detallada sobre las aplicaciones que usas."</string>
<string name="permlab_updateBatteryStats" msgid="3719689764536379557">"modificar las estadísticas de la batería"</string>
<string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Permite a la aplicación modificar las estadísticas recopiladas de la batería. Las aplicaciones normales no deben utilizarlo."</string>
- <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"Modificar estadísticas de operaciones de aplicación"</string>
- <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Permite que la aplicación modifique las estadísticas recopiladas de operación de la aplicación. Las aplicaciones normales no deben utilizar este permiso."</string>
+ <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modificar estadísticas de uso de aplicaciones"</string>
+ <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Permite que la aplicación modifique las estadísticas recopiladas sobre el uso de aplicaciones. Las aplicaciones normales no deben utilizar este permiso."</string>
<string name="permlab_backup" msgid="470013022865453920">"copia de seguridad y restauración del sistema de control"</string>
<string name="permdesc_backup" msgid="6912230525140589891">"Permite que la aplicación controle el mecanismo de copia de seguridad y restauración del sistema. Las aplicaciones normales no deben utilizar este permiso."</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"Confirmar una copia completa de seguridad o una operación de restauración"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7d18dc9..d3eaa61 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -315,7 +315,7 @@
<string name="permdesc_batteryStats" msgid="5897346582882915114">"Consente a un\'applicazione di leggere i dati di utilizzo della batteria di basso livello correnti. Potrebbe consentire all\'applicazione di trovare informazioni dettagliate sulle applicazioni che utilizzi."</string>
<string name="permlab_updateBatteryStats" msgid="3719689764536379557">"modifica statistiche batteria"</string>
<string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Consente all\'applicazione di modificare le statistiche raccolte sulla batteria. Da non usare per normali applicazioni."</string>
- <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modifica statistiche funzion. app"</string>
+ <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"modifica statistiche funzionamento app"</string>
<string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Consente all\'applicazione di modificare le statistiche raccolte sul funzionamento dell\'applicazione. Da non usare per normali applicazioni."</string>
<string name="permlab_backup" msgid="470013022865453920">"controllo del backup di sistema e ripristino"</string>
<string name="permdesc_backup" msgid="6912230525140589891">"Consente all\'applicazione di controllare il meccanismo di backup e di ripristino del sistema. Da non usare per normali applicazioni."</string>
diff --git a/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java b/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java
new file mode 100644
index 0000000..cb468bc
--- /dev/null
+++ b/core/tests/coretests/src/android/util/LongSparseLongArrayTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007 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.util;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Tests for {@link LongSparseLongArray}.
+ */
+public class LongSparseLongArrayTest extends TestCase {
+ private static final String TAG = "LongSparseLongArrayTest";
+
+ public void testSimplePut() throws Exception {
+ final LongSparseLongArray array = new LongSparseLongArray(5);
+ for (int i = 0; i < 48; i++) {
+ final long value = 1 << i;
+ array.put(value, value);
+ }
+ for (int i = 0; i < 48; i++) {
+ final long value = 1 << i;
+ assertEquals(value, array.get(value, -1));
+ assertEquals(-1, array.get(-value, -1));
+ }
+ }
+
+ public void testSimplePutBackwards() throws Exception {
+ final LongSparseLongArray array = new LongSparseLongArray(5);
+ for (int i = 47; i >= 0; i--) {
+ final long value = 1 << i;
+ array.put(value, value);
+ }
+ for (int i = 0; i < 48; i++) {
+ final long value = 1 << i;
+ assertEquals(value, array.get(value, -1));
+ assertEquals(-1, array.get(-value, -1));
+ }
+ }
+
+ public void testMiddleInsert() throws Exception {
+ final LongSparseLongArray array = new LongSparseLongArray(5);
+ for (int i = 0; i < 48; i++) {
+ final long value = 1 << i;
+ array.put(value, value);
+ }
+ final long special = (1 << 24) + 5;
+ array.put(special, 1024);
+ for (int i = 0; i < 48; i++) {
+ final long value = 1 << i;
+ assertEquals(value, array.get(value, -1));
+ assertEquals(-1, array.get(-value, -1));
+ }
+ assertEquals(1024, array.get(special, -1));
+ }
+
+ public void testFuzz() throws Exception {
+ final Random r = new Random();
+
+ final HashMap<Long, Long> map = new HashMap<Long, Long>();
+ final LongSparseLongArray array = new LongSparseLongArray(r.nextInt(128));
+
+ for (int i = 0; i < 10240; i++) {
+ if (r.nextBoolean()) {
+ final long key = r.nextLong();
+ final long value = r.nextLong();
+ map.put(key, value);
+ array.put(key, value);
+ }
+ if (r.nextBoolean() && map.size() > 0) {
+ final int index = r.nextInt(map.size());
+ final long key = getKeyAtIndex(map, index);
+ map.remove(key);
+ array.delete(key);
+ }
+ }
+
+ Log.d(TAG, "verifying a map with " + map.size() + " entries");
+
+ for (Map.Entry<Long, Long> e : map.entrySet()) {
+ final long key = e.getKey();
+ final long value = e.getValue();
+ assertEquals(value, array.get(key));
+ }
+ }
+
+ private static <E> E getKeyAtIndex(Map<E, ?> map, int index) {
+ final Iterator<E> keys = map.keySet().iterator();
+ for (int i = 0; i < index; i++) {
+ keys.next();
+ }
+ return keys.next();
+ }
+}
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index c12761b..57fa498 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -51,7 +51,7 @@
<li class="item carousel-home">
<div class="col-8">
<img
-src="http://4.bp.blogspot.com/-lfjzgG5Dqrk/UHMThRtpRwI/AAAAAAAABpk/h4d3nsmkgPM/s400/mint.png"
+src="//lh4.ggpht.com/-lfjzgG5Dqrk/UHMThRtpRwI/AAAAAAAABpk/h4d3nsmkgPM/s400/mint.png"
class="play no-shadow no-transform" />
</div>
<div class="content-right col-6">
@@ -65,7 +65,7 @@
<li class="item carousel-home">
<div class="col-8">
<img
-src="http://1.bp.blogspot.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s1600/google-play-subscriptions.png" class="play"></div>
+src="//lh4.ggpht.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s1600/google-play-subscriptions.png" class="play"></div>
<div class="content-right col-6">
<h2>In-app Subscriptions with Trials</h2>
<p>You can now set up a <strong>free trial period</strong> for any Google Play in-app subscription, making it easy for users try your subscriber content before automatically converting to a full subscription. Free trials give you a new way to bring users into your products and engage them effectively. </p>
@@ -77,7 +77,7 @@
<li class="item carousel-home">
<div class="col-8">
<img
-src="http://2.bp.blogspot.com/-MgN5DnoO5XU/UHYGYzTcAOI/AAAAAAAABs4/jTS7sKkfBcM/s1600/pubsites.png" class="play"></div>
+src="//lh4.ggpht.com/-MgN5DnoO5XU/UHYGYzTcAOI/AAAAAAAABs4/jTS7sKkfBcM/s1600/pubsites.png" class="play"></div>
<div class="content-right col-6">
<p class="title-intro">From the blog:</p>
<h2>New Google Play Developer Console</h2>
@@ -90,7 +90,7 @@
<li class="item carousel-home">
<div class="col-8">
<img
-src="http://4.bp.blogspot.com/-g05If_eKKRQ/UAcrVLI-OYI/AAAAAAAAAr8/AWvunVb5S-w/s320/nexus7.png"
+src="//lh4.ggpht.com/-g05If_eKKRQ/UAcrVLI-OYI/AAAAAAAAAr8/AWvunVb5S-w/s320/nexus7.png"
class="play no-shadow no-transform" />
</div>
<div class="content-right col-6">
@@ -127,7 +127,7 @@
<p>You can take advantage of the auth APIs in Google Play services to let your back end know which app is calling and for which user....</p>
</a></li>
<li><a href="//android-developers.blogspot.com/2012/12/daydream-interactive-screen-savers.html">
- <div class="feed-image" style="background:url('//3.bp.blogspot.com/-wVsUOo4xGE0/UNy9mZ1nmMI/AAAAAAAAB4w/f6rhyLn5KbI/s1600/daydream-example.jpg') no-repeat 0 0;background-position:right top;"></div>
+ <div class="feed-image" style="background:url('//lh4.ggpht.com/-wVsUOo4xGE0/UNy9mZ1nmMI/AAAAAAAAB4w/f6rhyLn5KbI/s1600/daydream-example.jpg') no-repeat 0 0;background-position:right top;"></div>
<h4>Daydream: Interactive Screen Savers</h4>
<p>Daydream is an interactive screen-saver mode introduced in Android 4.2. Learn how to add Daydreams to your apps...</p>
</a></li>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index cf06324..afda7a9 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -22,7 +22,7 @@
<script type="text/javascript">
var params = { allowScriptAccess: "always" };
var atts = { id: "ytapiplayer" };
- swfobject.embedSWF("http://www.youtube.com/v/RRelFvc6Czo?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
+ swfobject.embedSWF("//www.youtube.com/v/RRelFvc6Czo?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
"ytapiplayer", "600", "338", "8", null, null, params, atts);
// Callback used to pause/resume carousel based on video state
diff --git a/docs/html/training/animation/anim_page_transformer_depth.mp4 b/docs/html/training/animation/anim_page_transformer_depth.mp4
new file mode 100644
index 0000000..ba21663
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_depth.mp4
Binary files differ
diff --git a/docs/html/training/animation/anim_page_transformer_depth.ogv b/docs/html/training/animation/anim_page_transformer_depth.ogv
new file mode 100644
index 0000000..929735a
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_depth.ogv
Binary files differ
diff --git a/docs/html/training/animation/anim_page_transformer_depth.webm b/docs/html/training/animation/anim_page_transformer_depth.webm
new file mode 100644
index 0000000..37ab4e1
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_depth.webm
Binary files differ
diff --git a/docs/html/training/animation/anim_page_transformer_zoomout.mp4 b/docs/html/training/animation/anim_page_transformer_zoomout.mp4
new file mode 100644
index 0000000..598e964
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_zoomout.mp4
Binary files differ
diff --git a/docs/html/training/animation/anim_page_transformer_zoomout.ogv b/docs/html/training/animation/anim_page_transformer_zoomout.ogv
new file mode 100644
index 0000000..60b86af
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_zoomout.ogv
Binary files differ
diff --git a/docs/html/training/animation/anim_page_transformer_zoomout.webm b/docs/html/training/animation/anim_page_transformer_zoomout.webm
new file mode 100644
index 0000000..fc599a0
--- /dev/null
+++ b/docs/html/training/animation/anim_page_transformer_zoomout.webm
Binary files differ
diff --git a/docs/html/training/animation/cardflip.jd b/docs/html/training/animation/cardflip.jd
index ab3eb3a..1477f9fa 100644
--- a/docs/html/training/animation/cardflip.jd
+++ b/docs/html/training/animation/cardflip.jd
@@ -21,6 +21,16 @@
<a href="#animate">Animate the Card Flip</a>
</li>
</ol>
+ <h2>
+ Try it out
+ </h2>
+ <div class="download-box">
+ <a href="{@docRoot}shareables/training/Animations.zip" class=
+ "button">Download the sample app</a>
+ <p class="filename">
+ Animations.zip
+ </p>
+ </div>
</div>
</div>
<p> This lesson shows you how to do a card flip
diff --git a/docs/html/training/animation/crossfade.jd b/docs/html/training/animation/crossfade.jd
index 99e879b..2fbb6c0 100644
--- a/docs/html/training/animation/crossfade.jd
+++ b/docs/html/training/animation/crossfade.jd
@@ -20,6 +20,16 @@
<a href="#animate">Crossfade the Views</a>
</li>
</ol>
+ <h2>
+ Try it out
+ </h2>
+ <div class="download-box">
+ <a href="{@docRoot}shareables/training/Animations.zip" class=
+ "button">Download the sample app</a>
+ <p class="filename">
+ Animations.zip
+ </p>
+ </div>
</div>
</div>
diff --git a/docs/html/training/animation/layout.jd b/docs/html/training/animation/layout.jd
index b8e0077..e3a47d6 100644
--- a/docs/html/training/animation/layout.jd
+++ b/docs/html/training/animation/layout.jd
@@ -11,7 +11,16 @@
<li><a href="#views">Create the Layout</a></li>
<li><a href="#add">Add, Update, or Remove Items from the Layout</a></li>
</ol>
-
+ <h2>
+ Try it out
+ </h2>
+ <div class="download-box">
+ <a href="{@docRoot}shareables/training/Animations.zip" class=
+ "button">Download the sample app</a>
+ <p class="filename">
+ Animations.zip
+ </p>
+ </div>
</div>
</div>
diff --git a/docs/html/training/animation/screen-slide.jd b/docs/html/training/animation/screen-slide.jd
old mode 100755
new mode 100644
index 8a7af67..716805e
--- a/docs/html/training/animation/screen-slide.jd
+++ b/docs/html/training/animation/screen-slide.jd
@@ -9,15 +9,26 @@
<ol>
<li><a href="#views">Create the Views</a></li>
<li><a href="#fragment">Create the Fragment</a></li>
- <li><a href="#viewpager">Animate the Screen Slide</a></li>
+ <li><a href="#viewpager">Add a ViewPager</a></li>
+ <li><a href="#pagetransformer">Customize the Animation with PageTransformer</a></li>
</ol>
+ <h2>
+ Try it out
+ </h2>
+ <div class="download-box">
+ <a href="{@docRoot}shareables/training/Animations.zip" class=
+ "button">Download the sample app</a>
+ <p class="filename">
+ Animations.zip
+ </p>
+ </div>
</div>
</div>
<p>
Screen slides are transitions between one entire screen to another and are common with UIs
like setup wizards or slideshows. This lesson shows you how to do screen slides with
a {@link android.support.v4.view.ViewPager} provided by the <a href=
- "{@docRoot}/tools/extras/support-library.html">support library</a>.
+ "{@docRoot}tools/extras/support-library.html">support library</a>.
{@link android.support.v4.view.ViewPager}s can animate screen slides
automatically. Here's what a screen slide looks like that transitions from
one screen of content to the next:
@@ -89,7 +100,7 @@
}
</pre>
-<h2 id="viewpager">Screen Slides with ViewPager</h2>
+<h2 id="viewpager">Add a ViewPager</h2>
<p>{@link android.support.v4.view.ViewPager}s have built-in swipe gestures to transition
through pages, and they display screen slide animations by default, so you don't need to create any. {@link android.support.v4.view.ViewPager}s use
@@ -112,12 +123,12 @@
<ul>
<li>Sets the content view to be the layout with the {@link android.support.v4.view.ViewPager}.</li>
- <li>Create a class that extends the {@link android.support.v13.app.FragmentStatePagerAdapter} abstract class. Implement
+ <li>Creates a class that extends the {@link android.support.v13.app.FragmentStatePagerAdapter} abstract class and implements
the {@link android.support.v4.app.FragmentStatePagerAdapter#getItem getItem()} method to supply
instances of <code>ScreenSlidePageFragment</code> as new pages. The pager adapter also requires that you implement the
{@link android.support.v4.view.PagerAdapter#getCount getCount()} method, which returns the amount of pages the adapter will create (five in the example).
<li>Hooks up the {@link android.support.v4.view.PagerAdapter} to the {@link android.support.v4.view.ViewPager}</code>.</li>
- <li>Handle's the device's back button by moving backwards in the virtual stack of fragments.
+ <li>Handles the device's back button by moving backwards in the virtual stack of fragments.
If the user is already on the first page, go back on the activity back stack.</li>
</ul>
@@ -182,4 +193,179 @@
}
}
}
-</pre>
\ No newline at end of file
+</pre>
+
+
+<h2 id="pagetransformer">Customize the Animation with PageTransformer</h2>
+
+<p>To display a different animation from the default screen slide animation, implement the
+ {@link android.support.v4.view.ViewPager.PageTransformer} interface and supply it to
+ the view pager. The interface exposes a single method, {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()}. At each point in the screen's transition, this method is called once for each visible page (generally there's only one visible page) and for adjacent pages just off the screen.
+ For example, if page three is visible and the user drags towards page four,
+ {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()} is called
+ for pages two, three, and four at each step of the gesture.</p>
+
+ <p>
+ In your implementation of {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()},
+ you can then create custom slide animations by determining which pages need to be transformed based on the
+ position of the page on the screen, which is obtained from the <code>position</code> parameter
+ of the {@link android.support.v4.view.ViewPager.PageTransformer#transformPage transformPage()} method.</p>
+
+<p>The <code>position</code> parameter indicates where a given page is located relative to the center of the screen.
+It is a dynamic property that changes as the user scrolls through the pages. When a page fills the screen, its position value is <code>0</code>.
+When a page is drawn just off the right side of the screen, its position value is <code>1</code>. If the user scrolls halfway between pages one and two, page one has a position of -0.5 and page two has a position of 0.5. Based on the position of the pages on the screen, you can create custom slide animations by setting page properties with methods such as {@link android.view.View#setAlpha setAlpha()}, {@link android.view.View#setTranslationX setTranslationX()}, or
+ {@link android.view.View#setScaleY setScaleY()}.</p>
+
+
+<p>When you have an implementation of a {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer},
+call {@link android.support.v4.view.ViewPager#setPageTransformer setPageTransformer()} with
+ your implementation to apply your custom animations. For example, if you have a
+ {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer} named
+ <code>ZoomOutPageTransformer</code>, you can set your custom animations
+ like this:</p>
+<pre>
+ViewPager pager = (ViewPager) findViewById(R.id.pager);
+...
+pager.setPageTransformer(true, new ZoomOutPageTransformer());
+</pre>
+
+
+<p>See the <a href="#zoom-out">Zoom-out page transformer</a> and <a href="#depth-page">Depth page transformer</a>
+sections for examples and videos of a {@link android.support.v4.view.ViewPager.PageTransformer PageTransformer}.</p>
+
+
+<h3 id="zoom-out">Zoom-out page transformer</h3>
+<p>
+ This page transformer shrinks and fades pages when scrolling between
+ adjacent pages. As a page gets closer to the center, it grows back to
+ its normal size and fades in.
+</p>
+
+<div class="framed-galaxynexus-land-span-8">
+ <video class="play-on-hover" autoplay>
+ <source src="anim_page_transformer_zoomout.mp4" type="video/mp4">
+ <source src="anim_page_transformer_zoomout.webm" type="video/webm">
+ <source src="anim_page_transformer_zoomout.ogv" type="video/ogg">
+ </video>
+</div>
+
+<div class="figure-caption">
+ <code>ZoomOutPageTransformer</code> example
+ <div class="video-instructions"> </div>
+</div>
+
+
+<pre>
+public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
+ private static float MIN_SCALE = 0.85f;
+ private static float MIN_ALPHA = 0.5f;
+
+ public void transformPage(View view, float position) {
+ int pageWidth = view.getWidth();
+ int pageHeight = view.getHeight();
+
+ if (position < -1) { // [-Infinity,-1)
+ // This page is way off-screen to the left.
+ view.setAlpha(0);
+
+ } else if (position <= 1) { // [-1,1]
+ // Modify the default slide transition to shrink the page as well
+ float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
+ float vertMargin = pageHeight * (1 - scaleFactor) / 2;
+ float horzMargin = pageWidth * (1 - scaleFactor) / 2;
+ if (position < 0) {
+ view.setTranslationX(horzMargin - vertMargin / 2);
+ } else {
+ view.setTranslationX(-horzMargin + vertMargin / 2);
+ }
+
+ // Scale the page down (between MIN_SCALE and 1)
+ view.setScaleX(scaleFactor);
+ view.setScaleY(scaleFactor);
+
+ // Fade the page relative to its size.
+ view.setAlpha(MIN_ALPHA +
+ (scaleFactor - MIN_SCALE) /
+ (1 - MIN_SCALE) * (1 - MIN_ALPHA));
+
+ } else { // (1,+Infinity]
+ // This page is way off-screen to the right.
+ view.setAlpha(0);
+ }
+ }
+}
+</pre>
+
+<h3 id="depth-page">Depth page transformer</h3>
+<p>
+This page transformer uses the default slide animation for sliding pages
+to the left, while using a "depth" animation for sliding pages to the
+right. This depth animation fades the page out, and scales it down linearly.
+</p>
+
+<div class="framed-galaxynexus-land-span-8">
+ <video class="play-on-hover" autoplay>
+ <source src="anim_page_transformer_depth.mp4" type="video/mp4">
+ <source src="anim_page_transformer_depth.webm" type="video/webm">
+ <source src="anim_page_transformer_depth.ogv" type="video/ogg">
+ </video>
+</div>
+
+<div class="figure-caption">
+ <code>DepthPageTransformer</code> example
+ <div class="video-instructions"> </div>
+</div>
+
+<p class="note"><strong>Note:</strong> During the depth animation, the default animation (a screen slide) still
+takes place, so you must counteract the screen slide with a negative X translation.
+
+For example:
+
+<pre>
+view.setTranslationX(-1 * view.getWidth() * position);
+</pre>
+
+The following example shows how to counteract the default screen slide animation
+in a working page transformer:
+</p>
+
+<pre>
+
+public class DepthPageTransformer implements ViewPager.PageTransformer {
+ private static float MIN_SCALE = 0.75f;
+
+ public void transformPage(View view, float position) {
+ int pageWidth = view.getWidth();
+
+ if (position < -1) { // [-Infinity,-1)
+ // This page is way off-screen to the left.
+ view.setAlpha(0);
+
+ } else if (position <= 0) { // [-1,0]
+ // Use the default slide transition when moving to the left page
+ view.setAlpha(1);
+ view.setTranslationX(0);
+ view.setScaleX(1);
+ view.setScaleY(1);
+
+ } else if (position <= 1) { // (0,1]
+ // Fade the page out.
+ view.setAlpha(1 - position);
+
+ // Counteract the default slide transition
+ view.setTranslationX(pageWidth * -position);
+
+ // Scale the page down (between MIN_SCALE and 1)
+ float scaleFactor = MIN_SCALE
+ + (1 - MIN_SCALE) * (1 - Math.abs(position));
+ view.setScaleX(scaleFactor);
+ view.setScaleY(scaleFactor);
+
+ } else { // (1,+Infinity]
+ // This page is way off-screen to the right.
+ view.setAlpha(0);
+ }
+ }
+}
+</pre>
+
diff --git a/docs/html/training/animation/zoom.jd b/docs/html/training/animation/zoom.jd
index 5dc2b6c..6a38e7d 100644
--- a/docs/html/training/animation/zoom.jd
+++ b/docs/html/training/animation/zoom.jd
@@ -19,6 +19,16 @@
<a href="#animate">Zoom the View</a>
</li>
</ol>
+ <h2>
+ Try it out
+ </h2>
+ <div class="download-box">
+ <a href="{@docRoot}shareables/training/Animations.zip" class=
+ "button">Download the sample app</a>
+ <p class="filename">
+ Animations.zip
+ </p>
+ </div>
</div>
</div>
<p>
diff --git a/docs/html/training/articles/smp.jd b/docs/html/training/articles/smp.jd
index 53d7879..d46787d 100644
--- a/docs/html/training/articles/smp.jd
+++ b/docs/html/training/articles/smp.jd
@@ -628,7 +628,7 @@
<p>The “loop_until” seen in previous examples has been expanded to show the load
of B into reg0. reg1 is assigned the numeric value 8, and reg2 is loaded from
-the address [A+reg1] (same location that thread 1 is accessing).</p>
+the address [A+reg1] (the same location that thread 1 is accessing).</p>
<p>This will not behave correctly because the load from B could be observed
after the load from [A+reg1]. We can fix this with a load/load barrier after
@@ -640,7 +640,7 @@
<th>Thread 2</th>
</tr>
<tr>
-<td><code>A = 41<br />
+<td><code>[A+8] = 41<br />
<em>store/store barrier</em><br />
B = 1 // “A is ready”</code></td>
<td><code>loop:<br />
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 628d8a0..ae188be 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -270,9 +270,7 @@
GammaFontRenderer* fontRenderer;
Dither dither;
-#if STENCIL_BUFFER_SIZE
Stencil stencil;
-#endif
// Debug methods
PFNGLINSERTEVENTMARKEREXTPROC eventMark;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index ee1d391..79dbfb0 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -41,6 +41,7 @@
renderer = NULL;
displayList = NULL;
fbo = 0;
+ stencil = 0;
debugDrawUpdate = false;
Caches::getInstance().resourceCache.incrementRefcount(this);
}
@@ -53,9 +54,67 @@
deleteTexture();
}
-void Layer::removeFbo() {
+uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
+ return uint32_t(ceilf(layerWidth / float(LAYER_SIZE)) * LAYER_SIZE);
+}
+
+uint32_t Layer::computeIdealHeight(uint32_t layerHeight) {
+ return uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE);
+}
+
+bool Layer::resize(const uint32_t width, const uint32_t height) {
+ uint32_t desiredWidth = computeIdealWidth(width);
+ uint32_t desiredHeight = computeIdealWidth(height);
+
+ if (desiredWidth <= getWidth() && desiredHeight <= getHeight()) {
+ return true;
+ }
+
+ uint32_t oldWidth = getWidth();
+ uint32_t oldHeight = getHeight();
+
+ setSize(desiredWidth, desiredHeight);
+
if (fbo) {
- LayerRenderer::flushLayer(this);
+ Caches::getInstance().activeTexture(0);
+ bindTexture();
+ allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+
+ if (glGetError() != GL_NO_ERROR) {
+ setSize(oldWidth, oldHeight);
+ return false;
+ }
+ }
+
+ if (stencil) {
+ bindStencilRenderBuffer();
+ allocateStencilRenderBuffer();
+
+ if (glGetError() != GL_NO_ERROR) {
+ setSize(oldWidth, oldHeight);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Layer::removeFbo(bool flush) {
+ if (stencil) {
+ // TODO: recycle & cache instead of simply deleting
+ GLuint previousFbo;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
+ if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
+ if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
+
+ glDeleteRenderbuffers(1, &stencil);
+ stencil = 0;
+ }
+
+ if (fbo) {
+ if (flush) LayerRenderer::flushLayer(this);
+ // If put fails the cache will delete the FBO
Caches::getInstance().fboCache.put(fbo);
fbo = 0;
}
@@ -75,7 +134,5 @@
}
}
-
-
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 181eb6c..a551b3f 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -48,7 +48,15 @@
Layer(const uint32_t layerWidth, const uint32_t layerHeight);
~Layer();
- void removeFbo();
+ static uint32_t computeIdealWidth(uint32_t layerWidth);
+ static uint32_t computeIdealHeight(uint32_t layerHeight);
+
+ /**
+ * Calling this method will remove (either by recycling or
+ * destroying) the associated FBO, if present, and any render
+ * buffer (stencil for instance.)
+ */
+ void removeFbo(bool flush = true);
/**
* Sets this layer's region to a rectangle. Computes the appropriate
@@ -86,6 +94,17 @@
return texture.height;
}
+ /**
+ * Resize the layer and its texture if needed.
+ *
+ * @param width The new width of the layer
+ * @param height The new height of the layer
+ *
+ * @return True if the layer was resized or nothing happened, false if
+ * a failure occurred during the resizing operation
+ */
+ bool resize(const uint32_t width, const uint32_t height);
+
void setSize(uint32_t width, uint32_t height) {
texture.width = width;
texture.height = height;
@@ -134,6 +153,14 @@
return fbo;
}
+ inline void setStencilRenderBuffer(GLuint renderBuffer) {
+ this->stencil = renderBuffer;
+ }
+
+ inline GLuint getStencilRenderBuffer() {
+ return stencil;
+ }
+
inline GLuint getTexture() {
return texture.id;
}
@@ -190,6 +217,12 @@
}
}
+ inline void bindStencilRenderBuffer() {
+ if (stencil) {
+ glBindRenderbuffer(GL_RENDERBUFFER, stencil);
+ }
+ }
+
inline void generateTexture() {
if (!texture.id) {
glGenTextures(1, &texture.id);
@@ -212,15 +245,20 @@
texture.id = 0;
}
- inline void deleteFbo() {
- if (fbo) glDeleteFramebuffers(1, &fbo);
- }
-
inline void allocateTexture(GLenum format, GLenum storage) {
#if DEBUG_LAYERS
ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
#endif
- glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL);
+ if (texture.id) {
+ glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
+ format, storage, NULL);
+ }
+ }
+
+ inline void allocateStencilRenderBuffer() {
+ if (stencil) {
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWidth(), getHeight());
+ }
}
inline mat4& getTexTransform() {
@@ -275,6 +313,12 @@
GLuint fbo;
/**
+ * Name of the render buffer used as the stencil buffer. If the
+ * name is 0, this layer does not have a stencil buffer.
+ */
+ GLuint stencil;
+
+ /**
* Indicates whether this layer has been used already.
*/
bool empty;
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index cfc5b04..4278464 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -136,31 +136,6 @@
}
}
-bool LayerCache::resize(Layer* layer, const uint32_t width, const uint32_t height) {
- // TODO: We should be smarter and see if we have a texture of the appropriate
- // size already in the cache, and reuse it instead of creating a new one
-
- LayerEntry entry(width, height);
- if (entry.mWidth <= layer->getWidth() && entry.mHeight <= layer->getHeight()) {
- return true;
- }
-
- uint32_t oldWidth = layer->getWidth();
- uint32_t oldHeight = layer->getHeight();
-
- Caches::getInstance().activeTexture(0);
- layer->bindTexture();
- layer->setSize(entry.mWidth, entry.mHeight);
- layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
-
- if (glGetError() != GL_NO_ERROR) {
- layer->setSize(oldWidth, oldHeight);
- return false;
- }
-
- return true;
-}
-
bool LayerCache::put(Layer* layer) {
if (!layer->isCacheable()) return false;
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index fc2cd91..7720b42 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -72,17 +72,6 @@
* Clears the cache. This causes all layers to be deleted.
*/
void clear();
- /**
- * Resize the specified layer if needed.
- *
- * @param layer The layer to resize
- * @param width The new width of the layer
- * @param height The new height of the layer
- *
- * @return True if the layer was resized or nothing happened, false if
- * a failure occurred during the resizing operation
- */
- bool resize(Layer* layer, const uint32_t width, const uint32_t height);
/**
* Sets the maximum size of the cache in bytes.
@@ -108,8 +97,8 @@
}
LayerEntry(const uint32_t layerWidth, const uint32_t layerHeight): mLayer(NULL) {
- mWidth = uint32_t(ceilf(layerWidth / float(LAYER_SIZE)) * LAYER_SIZE);
- mHeight = uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE);
+ mWidth = Layer::computeIdealWidth(layerWidth);
+ mHeight = Layer::computeIdealHeight(layerHeight);
}
LayerEntry(Layer* layer):
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 3484d41..61bedbb 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -100,13 +100,21 @@
}
///////////////////////////////////////////////////////////////////////////////
-// Dirty region tracking
+// Layer support
///////////////////////////////////////////////////////////////////////////////
bool LayerRenderer::hasLayer() {
return true;
}
+void LayerRenderer::ensureStencilBuffer() {
+ attachStencilBufferToLayer(mLayer);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Dirty region tracking
+///////////////////////////////////////////////////////////////////////////////
+
Region* LayerRenderer::getRegion() {
if (getSnapshot()->flags & Snapshot::kFlagFboTarget) {
return OpenGLRenderer::getRegion();
@@ -256,7 +264,7 @@
if (layer) {
LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->getFbo(), width, height);
- if (Caches::getInstance().layerCache.resize(layer, width, height)) {
+ if (layer->resize(width, height)) {
layer->layer.set(0.0f, 0.0f, width, height);
layer->texCoords.set(0.0f, height / float(layer->getHeight()),
width / float(layer->getWidth()), 0.0f);
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index c44abce..7a8bdc5 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -64,6 +64,7 @@
static void flushLayer(Layer* layer);
protected:
+ virtual void ensureStencilBuffer();
virtual bool hasLayer();
virtual Region* getRegion();
virtual GLint getTargetFbo();
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index a924362..79fae2b 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -30,6 +30,16 @@
namespace android {
namespace uirenderer {
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+static const float EPSILON = 0.0000001f;
+
+///////////////////////////////////////////////////////////////////////////////
+// Matrix
+///////////////////////////////////////////////////////////////////////////////
+
void Matrix4::loadIdentity() {
data[kScaleX] = 1.0f;
data[kSkewY] = 0.0f;
@@ -51,44 +61,91 @@
data[kTranslateZ] = 0.0f;
data[kPerspective2] = 1.0f;
- mIsIdentity = true;
- mSimpleMatrix = true;
+ mType = kTypeIdentity | kTypeRectToRect;
+}
+
+static bool isZero(float f) {
+ return fabs(f) <= EPSILON;
+}
+
+uint32_t Matrix4::getType() const {
+ if (mType & kTypeUnknown) {
+ mType = kTypeIdentity;
+
+ if (data[kPerspective0] != 0.0f || data[kPerspective1] != 0.0f ||
+ data[kPerspective2] != 1.0f) {
+ mType |= kTypePerspective;
+ }
+
+ if (data[kTranslateX] != 0.0f || data[kTranslateY] != 0.0f) {
+ mType |= kTypeTranslate;
+ }
+
+ float m00 = data[kScaleX];
+ float m01 = data[kSkewX];
+ float m10 = data[kSkewY];
+ float m11 = data[kScaleY];
+
+ if (m01 != 0.0f || m10 != 0.0f) {
+ mType |= kTypeAffine;
+ }
+
+ if (m00 != 1.0f || m11 != 1.0f) {
+ mType |= kTypeScale;
+ }
+
+ // The following section determines whether the matrix will preserve
+ // rectangles. For instance, a rectangle transformed by a pure
+ // translation matrix will result in a rectangle. A rectangle
+ // transformed by a 45 degrees rotation matrix is not a rectangle.
+ // If the matrix has a perspective component then we already know
+ // it doesn't preserve rectangles.
+ if (!(mType & kTypePerspective)) {
+ if ((isZero(m00) && isZero(m11) && !isZero(m01) && !isZero(m10)) ||
+ (isZero(m01) && isZero(m10) && !isZero(m00) && !isZero(m11))) {
+ mType |= kTypeRectToRect;
+ }
+ }
+ }
+ return mType;
+}
+
+uint32_t Matrix4::getGeometryType() const {
+ return getType() & sGeometryMask;
+}
+
+bool Matrix4::rectToRect() const {
+ return getType() & kTypeRectToRect;
}
bool Matrix4::changesBounds() const {
- return !(data[0] == 1.0f && data[1] == 0.0f && data[2] == 0.0f && data[4] == 0.0f &&
- data[5] == 1.0f && data[6] == 0.0f && data[8] == 0.0f && data[9] == 0.0f &&
- data[10] == 1.0f);
+ return getType() & (kTypeScale | kTypeAffine | kTypePerspective);
}
bool Matrix4::isPureTranslate() const {
- return mSimpleMatrix && data[kScaleX] == 1.0f && data[kScaleY] == 1.0f;
+ return getGeometryType() == kTypeTranslate;
}
bool Matrix4::isSimple() const {
- return mSimpleMatrix;
+ return getGeometryType() <= (kTypeScale | kTypeTranslate);
}
bool Matrix4::isIdentity() const {
- return mIsIdentity;
+ return getGeometryType() == kTypeIdentity;
}
bool Matrix4::isPerspective() const {
- return data[kPerspective0] != 0.0f || data[kPerspective1] != 0.0f ||
- data[kPerspective2] != 1.0f;
+ return getType() & kTypePerspective;
}
void Matrix4::load(const float* v) {
memcpy(data, v, sizeof(data));
- // TODO: Do something smarter here
- mSimpleMatrix = false;
- mIsIdentity = false;
+ mType = kTypeUnknown;
}
void Matrix4::load(const Matrix4& v) {
memcpy(data, v.data, sizeof(data));
- mSimpleMatrix = v.mSimpleMatrix;
- mIsIdentity = v.mIsIdentity;
+ mType = v.getType();
}
void Matrix4::load(const SkMatrix& v) {
@@ -108,8 +165,14 @@
data[kScaleZ] = 1.0f;
- mSimpleMatrix = (v.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
- mIsIdentity = v.isIdentity();
+ // NOTE: The flags are compatible between SkMatrix and this class.
+ // However, SkMatrix::getType() does not return the flag
+ // kRectStaysRect. The return value is masked with 0xF
+ // so we need the extra rectStaysRect() check
+ mType = v.getType();
+ if (v.rectStaysRect()) {
+ mType |= kTypeRectToRect;
+ }
}
void Matrix4::copyTo(SkMatrix& v) const {
@@ -158,8 +221,7 @@
data[kPerspective2] = (v.data[kScaleX] * v.data[kScaleY] -
v.data[kSkewX] * v.data[kSkewY]) * scale;
- mSimpleMatrix = v.mSimpleMatrix;
- mIsIdentity = v.mIsIdentity;
+ mType = kTypeUnknown;
}
void Matrix4::copyTo(float* v) const {
@@ -178,7 +240,7 @@
for (int i = 0; i < 16; i++) {
data[i] *= v;
}
- mIsIdentity = false;
+ mType = kTypeUnknown;
}
void Matrix4::loadTranslate(float x, float y, float z) {
@@ -188,7 +250,7 @@
data[kTranslateY] = y;
data[kTranslateZ] = z;
- mIsIdentity = false;
+ mType = kTypeTranslate | kTypeRectToRect;
}
void Matrix4::loadScale(float sx, float sy, float sz) {
@@ -198,7 +260,7 @@
data[kScaleY] = sy;
data[kScaleZ] = sz;
- mIsIdentity = false;
+ mType = kTypeScale | kTypeRectToRect;
}
void Matrix4::loadSkew(float sx, float sy) {
@@ -216,8 +278,23 @@
data[kPerspective1] = 0.0f;
data[kPerspective2] = 1.0f;
- mSimpleMatrix = false;
- mIsIdentity = false;
+ mType = kTypeUnknown;
+}
+
+void Matrix4::loadRotate(float angle) {
+ angle *= float(M_PI / 180.0f);
+ float c = cosf(angle);
+ float s = sinf(angle);
+
+ loadIdentity();
+
+ data[kScaleX] = c;
+ data[kSkewX] = -s;
+
+ data[kSkewY] = s;
+ data[kScaleY] = c;
+
+ mType = kTypeUnknown;
}
void Matrix4::loadRotate(float angle, float x, float y, float z) {
@@ -257,8 +334,7 @@
data[6] = yz * nc + xs;
data[kScaleZ] = z * z * nc + c;
- mSimpleMatrix = false;
- mIsIdentity = false;
+ mType = kTypeUnknown;
}
void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
@@ -282,8 +358,7 @@
set(i, 3, w);
}
- mSimpleMatrix = u.mSimpleMatrix && v.mSimpleMatrix;
- mIsIdentity = false;
+ mType = kTypeUnknown;
}
void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
@@ -296,13 +371,13 @@
data[kTranslateY] = -(top + bottom) / (top - bottom);
data[kTranslateZ] = -(far + near) / (far - near);
- mIsIdentity = false;
+ mType = kTypeTranslate | kTypeScale | kTypeRectToRect;
}
#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
void Matrix4::mapPoint(float& x, float& y) const {
- if (mSimpleMatrix) {
+ if (isSimple()) {
MUL_ADD_STORE(x, data[kScaleX], data[kTranslateX]);
MUL_ADD_STORE(y, data[kScaleY], data[kTranslateY]);
return;
@@ -318,7 +393,7 @@
}
void Matrix4::mapRect(Rect& r) const {
- if (mSimpleMatrix) {
+ if (isSimple()) {
MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]);
MUL_ADD_STORE(r.right, data[kScaleX], data[kTranslateX]);
MUL_ADD_STORE(r.top, data[kScaleY], data[kTranslateY]);
@@ -376,7 +451,7 @@
}
void Matrix4::dump() const {
- ALOGD("Matrix4[simple=%d", mSimpleMatrix);
+ ALOGD("Matrix4[simple=%d, type=0x%x", isSimple(), getType());
ALOGD(" %f %f %f %f", data[kScaleX], data[kSkewX], data[8], data[kTranslateX]);
ALOGD(" %f %f %f %f", data[kSkewY], data[kScaleY], data[9], data[kTranslateY]);
ALOGD(" %f %f %f %f", data[2], data[6], data[kScaleZ], data[kTranslateZ]);
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index f86823d..46a5597 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -48,6 +48,21 @@
kPerspective2 = 15
};
+ // NOTE: The flags from kTypeIdentity to kTypePerspective
+ // must be kept in sync with the type flags found
+ // in SkMatrix
+ enum Type {
+ kTypeIdentity = 0,
+ kTypeTranslate = 0x1,
+ kTypeScale = 0x2,
+ kTypeAffine = 0x4,
+ kTypePerspective = 0x8,
+ kTypeRectToRect = 0x10,
+ kTypeUnknown = 0x20,
+ };
+
+ static const int sGeometryMask = 0xf;
+
Matrix4() {
loadIdentity();
}
@@ -75,11 +90,14 @@
void loadTranslate(float x, float y, float z);
void loadScale(float sx, float sy, float sz);
void loadSkew(float sx, float sy);
+ void loadRotate(float angle);
void loadRotate(float angle, float x, float y, float z);
void loadMultiply(const Matrix4& u, const Matrix4& v);
void loadOrtho(float left, float right, float bottom, float top, float near, float far);
+ uint32_t getType() const;
+
void multiply(const Matrix4& v) {
Matrix4 u;
u.loadMultiply(*this, v);
@@ -112,10 +130,14 @@
multiply(u);
}
- bool isPureTranslate() const;
+ /**
+ * If the matrix is identity or translate and/or scale.
+ */
bool isSimple() const;
+ bool isPureTranslate() const;
bool isIdentity() const;
bool isPerspective() const;
+ bool rectToRect() const;
bool changesBounds() const;
@@ -131,8 +153,7 @@
void dump() const;
private:
- bool mSimpleMatrix;
- bool mIsIdentity;
+ mutable uint32_t mType;
inline float get(int i, int j) const {
return data[i * 4 + j];
@@ -141,6 +162,9 @@
inline void set(int i, int j, float v) {
data[i * 4 + j] = v;
}
+
+ uint32_t getGeometryType() const;
+
}; // class Matrix4
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index bb1edbb..f55bc9d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -837,6 +837,8 @@
return;
}
+ Layer* layer = current->layer;
+ const Rect& rect = layer->layer;
const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
if (fboLayer) {
@@ -844,6 +846,9 @@
// Detach the texture from the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
+
+ layer->removeFbo(false);
+
// Unbind current FBO and restore previous one
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
debugOverdraw(true, false);
@@ -851,9 +856,6 @@
startTiling(previous);
}
- Layer* layer = current->layer;
- const Rect& rect = layer->layer;
-
if (!fboLayer && layer->getAlpha() < 255) {
drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
layer->getAlpha() << 24, SkXfermode::kDstIn_Mode, true);
@@ -881,17 +883,6 @@
composeLayerRect(layer, rect, true);
}
- if (fboLayer) {
- // Note: No need to use glDiscardFramebufferEXT() since we never
- // create/compose layers that are not on screen with this
- // code path
- // See LayerRenderer::destroyLayer(Layer*)
-
- // Put the FBO name back in the cache, if it doesn't fit, it will be destroyed
- mCaches.fboCache.put(current->fbo);
- layer->setFbo(0);
- }
-
dirtyClip();
// Failing to add the layer to the cache should happen only if the layer is too large
@@ -1001,10 +992,14 @@
const float texY = 1.0f / float(layer->getHeight());
const float height = rect.getHeight();
+ setupDraw();
+
+ // We must get (and therefore bind) the region mesh buffer
+ // after we setup drawing in case we need to mess with the
+ // stencil buffer in setupDraw()
TextureVertex* mesh = mCaches.getRegionMesh();
GLsizei numQuads = 0;
- setupDraw();
setupDrawWithTexture();
setupDrawColor(alpha, alpha, alpha, alpha);
setupDrawColorFilter();
@@ -1089,6 +1084,25 @@
#endif
}
+void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
+ SkXfermode::Mode mode, bool dirty) {
+ int count = 0;
+ Vector<float> rects;
+
+ SkRegion::Iterator it(region);
+ while (!it.done()) {
+ const SkIRect& r = it.rect();
+ rects.push(r.fLeft);
+ rects.push(r.fTop);
+ rects.push(r.fRight);
+ rects.push(r.fBottom);
+ count++;
+ it.next();
+ }
+
+ drawColorRects(rects.array(), count, color, mode, true, dirty);
+}
+
void OpenGLRenderer::dirtyLayer(const float left, const float top,
const float right, const float bottom, const mat4 transform) {
if (hasLayer()) {
@@ -1219,6 +1233,66 @@
}
}
+void OpenGLRenderer::ensureStencilBuffer() {
+ // Thanks to the mismatch between EGL and OpenGL ES FBO we
+ // cannot attach a stencil buffer to fbo0 dynamically. Let's
+ // just hope we have one when hasLayer() returns false.
+ if (hasLayer()) {
+ attachStencilBufferToLayer(mSnapshot->layer);
+ }
+}
+
+void OpenGLRenderer::attachStencilBufferToLayer(Layer* layer) {
+ // The layer's FBO is already bound when we reach this stage
+ if (!layer->getStencilRenderBuffer()) {
+ // TODO: See Layer::removeFbo(). The stencil renderbuffer should be cached
+ GLuint buffer;
+ glGenRenderbuffers(1, &buffer);
+
+ layer->setStencilRenderBuffer(buffer);
+ layer->bindStencilRenderBuffer();
+ layer->allocateStencilRenderBuffer();
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, buffer);
+ }
+}
+
+void OpenGLRenderer::setStencilFromClip() {
+ if (!mCaches.debugOverdraw) {
+ if (!mSnapshot->clipRegion->isEmpty()) {
+ // NOTE: The order here is important, we must set dirtyClip to false
+ // before any draw call to avoid calling back into this method
+ mDirtyClip = false;
+
+ ensureStencilBuffer();
+
+ mCaches.stencil.enableWrite();
+
+ // Clear the stencil but first make sure we restrict drawing
+ // to the region's bounds
+ bool resetScissor = mCaches.enableScissor();
+ if (resetScissor) {
+ // The scissor was not set so we now need to update it
+ setScissorFromClip();
+ }
+ mCaches.stencil.clear();
+ if (resetScissor) mCaches.disableScissor();
+
+ // NOTE: We could use the region contour path to generate a smaller mesh
+ // Since we are using the stencil we could use the red book path
+ // drawing technique. It might increase bandwidth usage though.
+
+ // The last parameter is important: we are not drawing in the color buffer
+ // so we don't want to dirty the current layer, if any
+ drawRegionRects(*mSnapshot->clipRegion, 0xff000000, SkXfermode::kSrc_Mode, false);
+
+ mCaches.stencil.enableTest();
+ } else {
+ mCaches.stencil.disable();
+ }
+ }
+}
+
const Rect& OpenGLRenderer::getClipBounds() {
return mSnapshot->getLocalClip();
}
@@ -1284,40 +1358,60 @@
return rejected;
}
+void OpenGLRenderer::debugClip() {
+#if DEBUG_CLIP_REGIONS
+ if (!isDeferred() && !mSnapshot->clipRegion->isEmpty()) {
+ drawRegionRects(*mSnapshot->clipRegion, 0x7f00ff00, SkXfermode::kSrcOver_Mode);
+ }
+#endif
+}
+
bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
- bool clipped = mSnapshot->clip(left, top, right, bottom, op);
+ if (CC_LIKELY(mSnapshot->transform->rectToRect())) {
+ bool clipped = mSnapshot->clip(left, top, right, bottom, op);
+ if (clipped) {
+ dirtyClip();
+ }
+ return !mSnapshot->clipRect->isEmpty();
+ }
+
+ SkPath path;
+ path.addRect(left, top, right, bottom);
+
+ return clipPath(&path, op);
+}
+
+bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
+ SkMatrix transform;
+ mSnapshot->transform->copyTo(transform);
+
+ SkPath transformed;
+ path->transform(transform, &transformed);
+
+ SkRegion clip;
+ if (!mSnapshot->clipRegion->isEmpty()) {
+ clip.setRegion(*mSnapshot->clipRegion);
+ } else {
+ Rect* bounds = mSnapshot->clipRect;
+ clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
+ }
+
+ SkRegion region;
+ region.setPath(transformed, clip);
+
+ bool clipped = mSnapshot->clipRegionTransformed(region, op);
if (clipped) {
dirtyClip();
-#if DEBUG_CLIP_REGIONS
- if (!isDeferred() && mSnapshot->clipRegion && !mSnapshot->clipRegion->isRect()) {
- int count = 0;
- Vector<float> rects;
- SkRegion::Iterator it(*mSnapshot->clipRegion);
- while (!it.done()) {
- const SkIRect& r = it.rect();
- rects.push(r.fLeft);
- rects.push(r.fTop);
- rects.push(r.fRight);
- rects.push(r.fBottom);
- count++;
- it.next();
- }
-
- drawColorRects(rects.array(), count, 0x7f00ff00, SkXfermode::kSrcOver_Mode, true);
- }
-#endif
}
return !mSnapshot->clipRect->isEmpty();
}
-bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
- const SkRect& bounds = path->getBounds();
- return clipRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, op);
-}
-
bool OpenGLRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
- const SkIRect& bounds = region->getBounds();
- return clipRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, op);
+ bool clipped = mSnapshot->clipRegionTransformed(*region, op);
+ if (clipped) {
+ dirtyClip();
+ }
+ return !mSnapshot->clipRect->isEmpty();
}
Rect* OpenGLRenderer::getClipRect() {
@@ -1332,8 +1426,11 @@
// TODO: It would be best if we could do this before quickReject()
// changes the scissor test state
if (clear) clearLayerRegions();
+ // Make sure setScissor & setStencil happen at the beginning of
+ // this method
if (mDirtyClip) {
setScissorFromClip();
+ setStencilFromClip();
}
mDescription.reset();
mSetShaderColor = false;
@@ -3085,7 +3182,7 @@
}
status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color,
- SkXfermode::Mode mode, bool ignoreTransform) {
+ SkXfermode::Mode mode, bool ignoreTransform, bool dirty) {
float left = FLT_MAX;
float top = FLT_MAX;
@@ -3103,7 +3200,7 @@
float r = rects[index + 2];
float b = rects[index + 3];
- if (!quickRejectNoScissor(left, top, right, bottom)) {
+ if (ignoreTransform || !quickRejectNoScissor(left, top, right, bottom)) {
Vertex::set(vertex++, l, b);
Vertex::set(vertex++, l, t);
Vertex::set(vertex++, r, t);
@@ -3136,7 +3233,7 @@
setupDrawColorFilterUniforms();
setupDrawVertices((GLvoid*) &mesh[0].position[0]);
- if (hasLayer()) {
+ if (dirty && hasLayer()) {
dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index f07325f..d4e1eb5 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -287,6 +287,19 @@
void resumeAfterLayer();
/**
+ * This method is called whenever a stencil buffer is required. Subclasses
+ * should override this method and call attachStencilBufferToLayer() on the
+ * appropriate layer(s).
+ */
+ virtual void ensureStencilBuffer();
+
+ /**
+ * Obtains a stencil render buffer (allocating it if necessary) and
+ * attaches it to the specified layer.
+ */
+ void attachStencilBufferToLayer(Layer* layer);
+
+ /**
* Compose the layer defined in the current snapshot with the layer
* defined by the previous snapshot.
*
@@ -423,6 +436,12 @@
void setScissorFromClip();
/**
+ * Sets the clipping region using the stencil buffer. The clip region
+ * is defined by the current snapshot's clipRegion member.
+ */
+ void setStencilFromClip();
+
+ /**
* Performs a quick reject but does not affect the scissor. Returns
* the transformed rect to test and the current clip.
*/
@@ -524,9 +543,10 @@
* @param color The rectangles' ARGB color, defined as a packed 32 bits word
* @param mode The Skia xfermode to use
* @param ignoreTransform True if the current transform should be ignored
+ * @param dirty True if calling this method should dirty the current layer
*/
status_t drawColorRects(const float* rects, int count, int color,
- SkXfermode::Mode mode, bool ignoreTransform = false);
+ SkXfermode::Mode mode, bool ignoreTransform = false, bool dirty = true);
/**
* Draws the shape represented by the specified path texture.
@@ -774,6 +794,19 @@
*/
void drawRegionRects(const Region& region);
+ /**
+ * Renders the specified region as a series of rectangles. The region
+ * must be in screen-space coordinates.
+ */
+ void drawRegionRects(const SkRegion& region, int color, SkXfermode::Mode mode,
+ bool dirty = false);
+
+ /**
+ * Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
+ * is turned on.
+ */
+ void debugClip();
+
void debugOverdraw(bool enable, bool clear);
void renderOverdraw();
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index d947299..22c7dde 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -31,7 +31,7 @@
transform = &mTransformRoot;
clipRect = &mClipRectRoot;
region = NULL;
- clipRegion = NULL;
+ clipRegion = &mClipRegionRoot;
}
/**
@@ -39,12 +39,10 @@
* the previous snapshot.
*/
Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags):
- flags(0), previous(s), layer(NULL), fbo(s->fbo),
+ flags(0), previous(s), layer(s->layer), fbo(s->fbo),
invisible(s->invisible), empty(false),
viewport(s->viewport), height(s->height), alpha(s->alpha) {
- clipRegion = NULL;
-
if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
mTransformRoot.load(*s->transform);
transform = &mTransformRoot;
@@ -55,17 +53,13 @@
if (saveFlags & SkCanvas::kClip_SaveFlag) {
mClipRectRoot.set(*s->clipRect);
clipRect = &mClipRectRoot;
-#if STENCIL_BUFFER_SIZE
- if (s->clipRegion) {
+ if (!s->clipRegion->isEmpty()) {
mClipRegionRoot.op(*s->clipRegion, SkRegion::kUnion_Op);
- clipRegion = &mClipRegionRoot;
}
-#endif
+ clipRegion = &mClipRegionRoot;
} else {
clipRect = s->clipRect;
-#if STENCIL_BUFFER_SIZE
clipRegion = s->clipRegion;
-#endif
}
if (s->flags & Snapshot::kFlagFboTarget) {
@@ -81,41 +75,38 @@
///////////////////////////////////////////////////////////////////////////////
void Snapshot::ensureClipRegion() {
-#if STENCIL_BUFFER_SIZE
- if (!clipRegion) {
- clipRegion = &mClipRegionRoot;
+ if (clipRegion->isEmpty()) {
clipRegion->setRect(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
}
-#endif
}
void Snapshot::copyClipRectFromRegion() {
-#if STENCIL_BUFFER_SIZE
if (!clipRegion->isEmpty()) {
const SkIRect& bounds = clipRegion->getBounds();
clipRect->set(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
if (clipRegion->isRect()) {
clipRegion->setEmpty();
- clipRegion = NULL;
}
} else {
clipRect->setEmpty();
- clipRegion = NULL;
}
-#endif
}
bool Snapshot::clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op) {
-#if STENCIL_BUFFER_SIZE
SkIRect tmp;
tmp.set(left, top, right, bottom);
clipRegion->op(tmp, op);
copyClipRectFromRegion();
return true;
-#else
- return false;
-#endif
+}
+
+bool Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
+ ensureClipRegion();
+ clipRegion->op(region, op);
+ copyClipRectFromRegion();
+ flags |= Snapshot::kFlagClipSet;
+ return true;
}
bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
@@ -129,7 +120,7 @@
switch (op) {
case SkRegion::kIntersect_Op: {
- if (CC_UNLIKELY(clipRegion)) {
+ if (CC_UNLIKELY(!clipRegion->isEmpty())) {
ensureClipRegion();
clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kIntersect_Op);
} else {
@@ -142,7 +133,7 @@
break;
}
case SkRegion::kUnion_Op: {
- if (CC_UNLIKELY(clipRegion)) {
+ if (CC_UNLIKELY(!clipRegion->isEmpty())) {
ensureClipRegion();
clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op);
} else {
@@ -171,12 +162,9 @@
void Snapshot::setClip(float left, float top, float right, float bottom) {
clipRect->set(left, top, right, bottom);
-#if STENCIL_BUFFER_SIZE
- if (clipRegion) {
+ if (!clipRegion->isEmpty()) {
clipRegion->setEmpty();
- clipRegion = NULL;
}
-#endif
flags |= Snapshot::kFlagClipSet;
}
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 9c612ff..ffd4729 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -94,6 +94,12 @@
bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
/**
+ * Modifies the current clip with the specified region and operation.
+ * The specified region is considered already transformed.
+ */
+ bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
+
+ /**
* Sets the current clip.
*/
void setClip(float left, float top, float right, float bottom);
@@ -136,7 +142,7 @@
sp<Snapshot> previous;
/**
- * Only set when the flag kFlagIsLayer is set.
+ * A pointer to the currently active layer.
*
* This snapshot does not own the layer, this pointer must not be freed.
*/
@@ -200,8 +206,6 @@
*
* This is a reference to a region owned by this snapshot or another
* snapshot. This pointer must not be freed. See ::mClipRegionRoot.
- *
- * This field is used only if STENCIL_BUFFER_SIZE is > 0.
*/
SkRegion* clipRegion;
@@ -234,9 +238,7 @@
Rect mClipRectRoot;
Rect mLocalClip;
-#if STENCIL_BUFFER_SIZE
SkRegion mClipRegionRoot;
-#endif
}; // class Snapshot
diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp
index 84df82b..4fcd51d 100644
--- a/libs/hwui/Stencil.cpp
+++ b/libs/hwui/Stencil.cpp
@@ -37,7 +37,7 @@
void Stencil::enableTest() {
if (mState != kTest) {
enable();
- glStencilFunc(GL_EQUAL, 0x1, 0x1);
+ glStencilFunc(GL_EQUAL, 0xff, 0xff);
// We only want to test, let's keep everything
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -48,7 +48,7 @@
void Stencil::enableWrite() {
if (mState != kWrite) {
enable();
- glStencilFunc(GL_ALWAYS, 0x1, 0x1);
+ glStencilFunc(GL_ALWAYS, 0xff, 0xff);
// The test always passes so the first two values are meaningless
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8c2dd8e..580bfe7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -147,7 +147,7 @@
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"Mode silenci."</string>
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"S\'ha omès <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string>
- <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Capa de notificació."</string>
+ <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Àrea de notificacions"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string>
<string name="accessibility_desc_recent_apps" msgid="9014032916410590027">"Aplicacions recents."</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuari <xliff:g id="USER">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 28c4113..54c4666 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -75,7 +75,8 @@
private Drawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
private Drawable mRecentIcon;
-
+ private Drawable mRecentLandIcon;
+
private DelegateViewHelper mDelegateHelper;
private DeadZone mDeadZone;
@@ -179,6 +180,7 @@
mBackAltIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
mBackAltLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_ime);
mRecentIcon = res.getDrawable(R.drawable.ic_sysbar_recent);
+ mRecentLandIcon = res.getDrawable(R.drawable.ic_sysbar_recent_land);
}
@Override
@@ -238,7 +240,7 @@
? (mVertical ? mBackAltLandIcon : mBackAltIcon)
: (mVertical ? mBackLandIcon : mBackIcon));
- ((ImageView)getRecentsButton()).setImageDrawable(mRecentIcon);
+ ((ImageView)getRecentsButton()).setImageDrawable(mVertical ? mRecentLandIcon : mRecentIcon);
setDisabledFlags(mDisabledFlags, true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index e5ef5fe..6eb88be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -135,7 +135,7 @@
mLastPokeTime = event.getEventTime();
if (DEBUG)
Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
- postInvalidate();
+ if (mShouldFlash) postInvalidate();
}
public void setFlash(float f) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 4cfe5d5..7cfa8c2 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -194,7 +194,6 @@
private int mNetworkPreference;
private int mActiveDefaultNetwork = -1;
// 0 is full bad, 100 is full good
- private int mDefaultInetCondition = 0;
private int mDefaultInetConditionPublished = 0;
private boolean mInetConditionChangeInFlight = false;
private int mDefaultConnectionSequence = 0;
@@ -1730,6 +1729,10 @@
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
} else {
mDefaultInetConditionPublished = 0; // we're not connected anymore
+ if (DBG) {
+ log("handleDisconnect: net=" + mActiveDefaultNetwork +
+ ", published condition=" + mDefaultInetConditionPublished);
+ }
intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
}
}
@@ -1920,6 +1923,10 @@
intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
} else {
mDefaultInetConditionPublished = 0;
+ if (DBG) {
+ log("handleConnectionFailure: net=" + mActiveDefaultNetwork +
+ ", published condition=" + mDefaultInetConditionPublished);
+ }
intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
}
}
@@ -2064,6 +2071,10 @@
mDefaultInetConditionPublished = 0;
mDefaultConnectionSequence++;
mInetConditionChangeInFlight = false;
+ if (DBG) {
+ log("handleConnect: net=" + newNetType +
+ ", published condition=" + mDefaultInetConditionPublished);
+ }
// Don't do this - if we never sign in stay, grey
//reportNetworkCondition(mActiveDefaultNetwork, 100);
}
@@ -2779,7 +2790,8 @@
{
int netType = msg.arg1;
int sequence = msg.arg2;
- handleInetConditionHoldEnd(netType, sequence);
+ int condition = (Integer)msg.obj;
+ handleInetConditionHoldEnd(netType, sequence, condition);
break;
}
case EVENT_SET_NETWORK_PREFERENCE:
@@ -2992,14 +3004,13 @@
if (VDBG) {
log("handleInetConditionChange: net=" +
netType + ", condition=" + condition +
- ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
+ " mActiveDefaultNetwork=" + mActiveDefaultNetwork);
}
- mDefaultInetCondition = condition;
int delay;
if (mInetConditionChangeInFlight == false) {
if (VDBG) log("handleInetConditionChange: starting a change hold");
// setup a new hold to debounce this
- if (mDefaultInetCondition > 50) {
+ if (condition > 50) {
delay = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
} else {
@@ -3008,18 +3019,16 @@
}
mInetConditionChangeInFlight = true;
mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
- mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
+ mActiveDefaultNetwork, mDefaultConnectionSequence, new Integer(condition)), delay);
} else {
// we've set the new condition, when this hold ends that will get picked up
if (VDBG) log("handleInetConditionChange: currently in hold - not setting new end evt");
}
}
- private void handleInetConditionHoldEnd(int netType, int sequence) {
+ private void handleInetConditionHoldEnd(int netType, int sequence, int condition) {
if (DBG) {
- log("handleInetConditionHoldEnd: net=" + netType +
- ", condition=" + mDefaultInetCondition +
- ", published condition=" + mDefaultInetConditionPublished);
+ log("handleInetConditionHoldEnd: net=" + netType + ", condition=" + condition);
}
mInetConditionChangeInFlight = false;
@@ -3031,19 +3040,13 @@
if (DBG) log("handleInetConditionHoldEnd: event hold for obsolete network - ignoring");
return;
}
- // TODO: Figure out why this optimization sometimes causes a
- // change in mDefaultInetCondition to be missed and the
- // UI to not be updated.
- //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
- // if (DBG) log("no change in condition - aborting");
- // return;
- //}
+
NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
if (networkInfo.isConnected() == false) {
if (DBG) log("handleInetConditionHoldEnd: default network not connected - ignoring");
return;
}
- mDefaultInetConditionPublished = mDefaultInetCondition;
+ mDefaultInetConditionPublished = condition;
sendInetConditionBroadcast(networkInfo);
return;
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 2f12112..593b9bf 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -2554,6 +2554,9 @@
public void onCheckedChanged(
CompoundButton buttonView, boolean isChecked) {
mWindowManagerService.setHardKeyboardEnabled(isChecked);
+ // Ensure that the input method dialog is dismissed when changing
+ // the hardware keyboard state.
+ hideInputMethodMenu();
}
});
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 9b3795a..47987f1 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2878,187 +2878,144 @@
}
}
- private static final int getContinuationPoint(final String[] keys, final String key) {
- final int index;
- if (key == null) {
- index = 0;
- } else {
- final int insertPoint = Arrays.binarySearch(keys, key);
- if (insertPoint < 0) {
- index = -insertPoint;
- } else {
- index = insertPoint + 1;
- }
- }
- return index;
- }
-
@Override
- public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead,
- int userId) {
- final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
+ public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
- final String[] keys;
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
// writer
synchronized (mPackages) {
+ ArrayList<PackageInfo> list;
if (listUninstalled) {
- keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
- } else {
- keys = mPackages.keySet().toArray(new String[mPackages.size()]);
- }
-
- Arrays.sort(keys);
- int i = getContinuationPoint(keys, lastRead);
- final int N = keys.length;
-
- while (i < N) {
- final String packageName = keys[i++];
-
- PackageInfo pi = null;
- if (listUninstalled) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
+ list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
+ for (PackageSetting ps : mSettings.mPackages.values()) {
+ PackageInfo pi;
+ if (ps.pkg != null) {
+ pi = generatePackageInfo(ps.pkg, flags, userId);
+ } else {
pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
}
- } else {
- final PackageParser.Package p = mPackages.get(packageName);
- if (p != null) {
- pi = generatePackageInfo(p, flags, userId);
+ if (pi != null) {
+ list.add(pi);
}
}
-
- if (pi != null && list.append(pi)) {
- break;
+ } else {
+ list = new ArrayList<PackageInfo>(mPackages.size());
+ for (PackageParser.Package p : mPackages.values()) {
+ PackageInfo pi = generatePackageInfo(p, flags, userId);
+ if (pi != null) {
+ list.add(pi);
+ }
}
}
- if (i == N) {
- list.setLastSlice(true);
+ return new ParceledListSlice<PackageInfo>(list);
+ }
+ }
+
+ private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
+ String[] permissions, boolean[] tmp, int flags, int userId) {
+ int numMatch = 0;
+ for (int i=0; i<permissions.length; i++) {
+ if (ps.grantedPermissions.contains(permissions[i])) {
+ tmp[i] = true;
+ numMatch++;
+ } else {
+ tmp[i] = false;
}
}
-
- return list;
+ if (numMatch == 0) {
+ return;
+ }
+ PackageInfo pi;
+ if (ps.pkg != null) {
+ pi = generatePackageInfo(ps.pkg, flags, userId);
+ } else {
+ pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
+ }
+ if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
+ if (numMatch == permissions.length) {
+ pi.requestedPermissions = permissions;
+ } else {
+ pi.requestedPermissions = new String[numMatch];
+ numMatch = 0;
+ for (int i=0; i<permissions.length; i++) {
+ if (tmp[i]) {
+ pi.requestedPermissions[numMatch] = permissions[i];
+ numMatch++;
+ }
+ }
+ }
+ }
+ list.add(pi);
}
@Override
public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
- String[] permissions, int flags, String lastRead, int userId) {
+ String[] permissions, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
// writer
synchronized (mPackages) {
- ArrayList<String> keysList = new ArrayList<String>();
+ ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
+ boolean[] tmpBools = new boolean[permissions.length];
if (listUninstalled) {
for (PackageSetting ps : mSettings.mPackages.values()) {
- for (String perm : permissions) {
- if (ps.grantedPermissions.contains(perm)) {
- keysList.add(ps.name);
- break;
- }
- }
+ addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
}
} else {
for (PackageParser.Package pkg : mPackages.values()) {
PackageSetting ps = (PackageSetting)pkg.mExtras;
if (ps != null) {
- for (String perm : permissions) {
- if (ps.grantedPermissions.contains(perm)) {
- keysList.add(ps.name);
- break;
- }
+ addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
+ userId);
+ }
+ }
+ }
+
+ return new ParceledListSlice<PackageInfo>(list);
+ }
+ }
+
+ @Override
+ public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
+ if (!sUserManager.exists(userId)) return null;
+ final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
+
+ // writer
+ synchronized (mPackages) {
+ ArrayList<ApplicationInfo> list;
+ if (listUninstalled) {
+ list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
+ for (PackageSetting ps : mSettings.mPackages.values()) {
+ ApplicationInfo ai;
+ if (ps.pkg != null) {
+ ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
+ ps.readUserState(userId), userId);
+ } else {
+ ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
+ }
+ if (ai != null) {
+ list.add(ai);
+ }
+ }
+ } else {
+ list = new ArrayList<ApplicationInfo>(mPackages.size());
+ for (PackageParser.Package p : mPackages.values()) {
+ if (p.mExtras != null) {
+ ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
+ ((PackageSetting)p.mExtras).readUserState(userId), userId);
+ if (ai != null) {
+ list.add(ai);
}
}
}
}
- String[] keys = new String[keysList.size()];
- keysList.toArray(keys);
- Arrays.sort(keys);
- int i = getContinuationPoint(keys, lastRead);
- final int N = keys.length;
-
- while (i < N) {
- final String packageName = keys[i++];
-
- PackageInfo pi = null;
- if (listUninstalled) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
- }
- } else {
- final PackageParser.Package p = mPackages.get(packageName);
- if (p != null) {
- pi = generatePackageInfo(p, flags, userId);
- }
- }
-
- if (pi != null && list.append(pi)) {
- break;
- }
- }
-
- if (i == N) {
- list.setLastSlice(true);
- }
+ return new ParceledListSlice<ApplicationInfo>(list);
}
-
- return list;
- }
-
- @Override
- public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
- String lastRead, int userId) {
- if (!sUserManager.exists(userId)) return null;
- final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
- final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
- final String[] keys;
-
- // writer
- synchronized (mPackages) {
- if (listUninstalled) {
- keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
- } else {
- keys = mPackages.keySet().toArray(new String[mPackages.size()]);
- }
-
- Arrays.sort(keys);
- int i = getContinuationPoint(keys, lastRead);
- final int N = keys.length;
-
- while (i < N) {
- final String packageName = keys[i++];
-
- ApplicationInfo ai = null;
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (listUninstalled) {
- if (ps != null) {
- ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
- }
- } else {
- final PackageParser.Package p = mPackages.get(packageName);
- if (p != null && ps != null) {
- ai = PackageParser.generateApplicationInfo(p, flags,
- ps.readUserState(userId), userId);
- }
- }
-
- if (ai != null && list.append(ai)) {
- break;
- }
- }
-
- if (i == N) {
- list.setLastSlice(true);
- }
- }
-
- return list;
}
public List<ApplicationInfo> getPersistentApplications(int flags) {
diff --git a/test-runner/src/android/test/mock/MockContentResolver.java b/test-runner/src/android/test/mock/MockContentResolver.java
index 715da0f..aec6c77 100644
--- a/test-runner/src/android/test/mock/MockContentResolver.java
+++ b/test-runner/src/android/test/mock/MockContentResolver.java
@@ -54,12 +54,20 @@
public class MockContentResolver extends ContentResolver {
Map<String, ContentProvider> mProviders;
- /*
- * Creates a local map of providers. This map is used instead of the global map when an
- * API call tries to acquire a provider.
+ /**
+ * Creates a local map of providers. This map is used instead of the global
+ * map when an API call tries to acquire a provider.
*/
public MockContentResolver() {
- super(null);
+ this(null);
+ }
+
+ /**
+ * Creates a local map of providers. This map is used instead of the global
+ * map when an API call tries to acquire a provider.
+ */
+ public MockContentResolver(Context context) {
+ super(context);
mProviders = Maps.newHashMap();
}
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 3097811..248fbf1 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -106,6 +106,12 @@
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public String getBasePackageName() {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public ApplicationInfo getApplicationInfo() {
throw new UnsupportedOperationException();
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java
index 1b72486..ab60f21 100644
--- a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java
@@ -21,6 +21,7 @@
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup;
@@ -180,7 +181,7 @@
}
private final void validateNotAppThread() {
- if (ActivityThread.currentActivityThread() != null) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
throw new RuntimeException(
"This method can not be called from the main application thread");
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index 9a4e99e..22b587f 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -22,6 +22,7 @@
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.ViewGroup;
@@ -184,7 +185,7 @@
}
private final void validateNotAppThread() {
- if (ActivityThread.currentActivityThread() != null) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
throw new RuntimeException(
"This method can not be called from the main application thread");
}
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 7d2ba19..57ce1d6 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -148,7 +148,16 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-
+
+ <activity
+ android:name="ClipRegion2Activity"
+ android:label="_ClipRegion2">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
<activity
android:name="DisplayListLayersActivity"
android:label="__DisplayListLayers">
diff --git a/tests/HwAccelerationTest/res/layout/view_layers_5.xml b/tests/HwAccelerationTest/res/layout/view_layers_5.xml
index 36cf8c9..5baf583 100644
--- a/tests/HwAccelerationTest/res/layout/view_layers_5.xml
+++ b/tests/HwAccelerationTest/res/layout/view_layers_5.xml
@@ -48,13 +48,32 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Grow layer" />
+
+ <Button
+ android:onClick="enableClip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Circle clip" />
+
+ <Button
+ android:onClick="disableClip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="No clip" />
</LinearLayout>
- <ListView
- android:id="@+id/list1"
+ <view class="com.android.test.hwui.ViewLayersActivity5$ClipFrameLayout"
+ android:id="@+id/container"
android:layout_width="0dip"
android:layout_height="match_parent"
- android:layout_weight="1" />
+ android:layout_weight="1">
+
+ <ListView
+ android:id="@+id/list1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </view>
</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java
new file mode 100644
index 0000000..066e35c
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegion2Activity.java
@@ -0,0 +1,86 @@
+/*
+ * 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 com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ClipRegion2Activity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final RegionView group = new RegionView(this);
+
+ final TextView text = new TextView(this);
+ text.setText(buildText());
+ group.addView(text);
+
+ setContentView(group);
+ }
+
+ private static CharSequence buildText() {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < 10; i++) {
+ buffer.append(LOREM_IPSUM);
+ }
+ return buffer;
+ }
+
+ public static class RegionView extends FrameLayout {
+ private final Region mRegion = new Region();
+ private float mClipPosition = 0.0f;
+
+ public RegionView(Context c) {
+ super(c);
+ }
+
+ public float getClipPosition() {
+ return mClipPosition;
+ }
+
+ public void setClipPosition(float clipPosition) {
+ mClipPosition = clipPosition;
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+
+ canvas.save();
+
+ mRegion.setEmpty();
+ mRegion.op(0, 0, getWidth(), getHeight(),
+ Region.Op.REPLACE);
+ mRegion.op(getWidth() / 4, getHeight() / 4, 3 * getWidth() / 4, 3 * getHeight() / 4,
+ Region.Op.DIFFERENCE);
+
+ canvas.clipRegion(mRegion);
+ super.dispatchDraw(canvas);
+
+ canvas.restore();
+ }
+ }
+
+ private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sagittis molestie aliquam. Donec metus metus, laoreet nec sagittis vitae, ultricies sit amet eros. Suspendisse sed massa sit amet felis consectetur gravida. In vitae erat mi, in egestas nisl. Phasellus quis ipsum massa, at scelerisque arcu. Nam lectus est, pellentesque eget lacinia non, congue vitae augue. Aliquam erat volutpat. Pellentesque bibendum tincidunt viverra. Aliquam erat volutpat. Maecenas pretium vulputate placerat. Nulla varius elementum rutrum. Aenean mollis blandit imperdiet. Pellentesque interdum fringilla ligula.";
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java
index d5daa5f..3d3d709 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java
@@ -16,38 +16,77 @@
package com.android.test.hwui;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Region;
+import android.graphics.Path;
import android.os.Bundle;
-import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.TextView;
@SuppressWarnings({"UnusedDeclaration"})
public class ClipRegionActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- final RegionView view = new RegionView(this);
- setContentView(view);
+
+ final RegionView group = new RegionView(this);
+
+ final TextView text = new TextView(this);
+ text.setText(buildText());
+ group.addView(text);
+
+ setContentView(group);
+
+ ObjectAnimator animator = ObjectAnimator.ofFloat(group, "clipPosition", 0.0f, 1.0f);
+ animator.setDuration(3000);
+ animator.setRepeatCount(ValueAnimator.INFINITE);
+ animator.setRepeatMode(ValueAnimator.REVERSE);
+ animator.start();
}
- public static class RegionView extends View {
+ private static CharSequence buildText() {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < 10; i++) {
+ buffer.append(LOREM_IPSUM);
+ }
+ return buffer;
+ }
+
+ public static class RegionView extends FrameLayout {
+ private final Path mClipPath = new Path();
+ private float mClipPosition = 0.0f;
+
public RegionView(Context c) {
super(c);
}
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
+ public float getClipPosition() {
+ return mClipPosition;
+ }
- canvas.save();
- canvas.clipRect(100.0f, 100.0f, getWidth() - 100.0f, getHeight() - 100.0f,
- Region.Op.DIFFERENCE);
- canvas.drawARGB(128, 255, 0, 0);
- canvas.restore();
-
+ public void setClipPosition(float clipPosition) {
+ mClipPosition = clipPosition;
invalidate();
}
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+
+ canvas.save();
+
+ mClipPath.reset();
+ mClipPath.addCircle(mClipPosition * getWidth(), getHeight() / 2.0f,
+ getWidth() / 4.0f, Path.Direction.CW);
+
+ canvas.clipPath(mClipPath);
+ super.dispatchDraw(canvas);
+
+ canvas.restore();
+ }
}
+
+ private static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sagittis molestie aliquam. Donec metus metus, laoreet nec sagittis vitae, ultricies sit amet eros. Suspendisse sed massa sit amet felis consectetur gravida. In vitae erat mi, in egestas nisl. Phasellus quis ipsum massa, at scelerisque arcu. Nam lectus est, pellentesque eget lacinia non, congue vitae augue. Aliquam erat volutpat. Pellentesque bibendum tincidunt viverra. Aliquam erat volutpat. Maecenas pretium vulputate placerat. Nulla varius elementum rutrum. Aenean mollis blandit imperdiet. Pellentesque interdum fringilla ligula.";
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
index 2664977..cbbb7ef 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
@@ -19,14 +19,18 @@
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.Bundle;
+import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
+import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
@@ -37,30 +41,75 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
+ init();
+
setContentView(R.layout.view_layers_5);
-
- mPaint.setColorFilter(new PorterDuffColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY));
-
setupList(R.id.list1);
}
+ public static class ClipFrameLayout extends FrameLayout {
+ private final Path mClipPath = new Path();
+ private boolean mClipEnabled;
+
+ public ClipFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ClipFrameLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public boolean isClipEnabled() {
+ return mClipEnabled;
+ }
+
+ public void setClipEnabled(boolean clipEnabled) {
+ mClipEnabled = clipEnabled;
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ if (mClipEnabled) {
+ mClipPath.reset();
+ mClipPath.addCircle(getWidth() / 2.0f, getHeight() / 2.0f,
+ Math.min(getWidth(), getHeight()) / 3.0f, Path.Direction.CW);
+
+ canvas.clipPath(mClipPath);
+ }
+ super.dispatchDraw(canvas);
+ }
+ }
+
+ private void init() {
+ mPaint.setColorFilter(new PorterDuffColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY));
+ }
+
+ public void enableClip(View v) {
+ ((ClipFrameLayout) findViewById(R.id.container)).setClipEnabled(true);
+ }
+
+ public void disableClip(View v) {
+ ((ClipFrameLayout) findViewById(R.id.container)).setClipEnabled(false);
+ }
+
public void enableLayer(View v) {
- findViewById(R.id.list1).setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
+ findViewById(R.id.container).setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
}
public void disableLayer(View v) {
- findViewById(R.id.list1).setLayerType(View.LAYER_TYPE_NONE, null);
+ findViewById(R.id.container).setLayerType(View.LAYER_TYPE_NONE, null);
}
public void growLayer(View v) {
- findViewById(R.id.list1).getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
- findViewById(R.id.list1).requestLayout();
+ findViewById(R.id.container).getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
+ findViewById(R.id.container).requestLayout();
}
public void shrinkLayer(View v) {
- findViewById(R.id.list1).getLayoutParams().height = 300;
- findViewById(R.id.list1).requestLayout();
+ findViewById(R.id.container).getLayoutParams().height = 300;
+ findViewById(R.id.container).requestLayout();
}
private void setupList(int listId) {
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/Android.mk b/tests/RenderScriptTests/RSTest_CompatLib/Android.mk
new file mode 100644
index 0000000..e79c780
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/Android.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2013 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := RSTest_Compat
+
+LOCAL_STATIC_JAVA_LIBRARIES := android.support.v8.renderscript
+
+LOCAL_SDK_VERSION := 8
+LOCAL_RENDERSCRIPT_TARGET_API := 18
+LOCAL_RENDERSCRIPT_COMPATIBILITY := 18
+
+LOCAL_RENDERSCRIPT_FLAGS := -rs-package-name=android.support.v8.renderscript
+LOCAL_REQUIRED_MODULES := librsjni
+
+include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/AndroidManifest.xml b/tests/RenderScriptTests/RSTest_CompatLib/AndroidManifest.xml
new file mode 100644
index 0000000..f45b555
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rs.test">
+ <uses-sdk android:minSdkVersion="8" />
+ <uses-sdk android:targetSdkVersion="8" />
+ <application
+ android:label="_RS_Test_Compat"
+ android:icon="@drawable/test_pattern">
+ <activity android:name="RSTest"
+ android:screenOrientation="portrait">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/res/drawable-nodpi/test_pattern.png b/tests/RenderScriptTests/RSTest_CompatLib/res/drawable-nodpi/test_pattern.png
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/res/drawable-nodpi/test_pattern.png
Binary files differ
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTest.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTest.java
new file mode 100644
index 0000000..c667122
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.support.v8.renderscript.RenderScript;
+
+import android.app.ListActivity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.ArrayAdapter;
+
+import java.lang.Runtime;
+
+public class RSTest extends ListActivity {
+
+ private static final String LOG_TAG = "RSTest_Compat";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = false;
+
+ private RenderScript mRS;
+ private RSTestCore RSTC;
+
+ String mTestNames[];
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mRS = RenderScript.create(this);
+
+ RSTC = new RSTestCore(this);
+ RSTC.init(mRS, getResources());
+
+
+
+
+ }
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java
new file mode 100644
index 0000000..6b3df328
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008-2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
+import android.app.ListActivity;
+import android.widget.ArrayAdapter;
+
+public class RSTestCore {
+ ListActivity mCtx;
+
+ public RSTestCore(ListActivity ctx) {
+ mCtx = ctx;
+ }
+
+ private Resources mRes;
+ private RenderScript mRS;
+
+ private ArrayList<UnitTest> unitTests;
+ private ListIterator<UnitTest> test_iter;
+ private UnitTest activeTest;
+ private boolean stopTesting;
+
+ private ScriptField_ListAllocs_s mListAllocs;
+
+ private ArrayAdapter<UnitTest> testAdapter;
+
+ /* Periodic timer for ensuring future tests get scheduled */
+ private Timer mTimer;
+ public static final int RS_TIMER_PERIOD = 100;
+
+ public void init(RenderScript rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+ stopTesting = false;
+
+ unitTests = new ArrayList<UnitTest>();
+
+ unitTests.add(new UT_primitives(this, mRes, mCtx));
+ unitTests.add(new UT_constant(this, mRes, mCtx));
+ unitTests.add(new UT_vector(this, mRes, mCtx));
+ unitTests.add(new UT_unsigned(this, mRes, mCtx));
+ unitTests.add(new UT_array_init(this, mRes, mCtx));
+ unitTests.add(new UT_array_alloc(this, mRes, mCtx));
+ unitTests.add(new UT_kernel(this, mRes, mCtx));
+ unitTests.add(new UT_kernel_struct(this, mRes, mCtx));
+ unitTests.add(new UT_bug_char(this, mRes, mCtx));
+ unitTests.add(new UT_clamp(this, mRes, mCtx));
+ unitTests.add(new UT_clamp_relaxed(this, mRes, mCtx));
+ unitTests.add(new UT_convert(this, mRes, mCtx));
+ unitTests.add(new UT_convert_relaxed(this, mRes, mCtx));
+ unitTests.add(new UT_copy_test(this, mRes, mCtx));
+ unitTests.add(new UT_rsdebug(this, mRes, mCtx));
+ unitTests.add(new UT_rstime(this, mRes, mCtx));
+ unitTests.add(new UT_rstypes(this, mRes, mCtx));
+ unitTests.add(new UT_alloc(this, mRes, mCtx));
+ unitTests.add(new UT_refcount(this, mRes, mCtx));
+ unitTests.add(new UT_foreach(this, mRes, mCtx));
+ unitTests.add(new UT_foreach_bounds(this, mRes, mCtx));
+ unitTests.add(new UT_noroot(this, mRes, mCtx));
+ unitTests.add(new UT_atomic(this, mRes, mCtx));
+ unitTests.add(new UT_struct(this, mRes, mCtx));
+ unitTests.add(new UT_math(this, mRes, mCtx));
+ unitTests.add(new UT_math_conformance(this, mRes, mCtx));
+ unitTests.add(new UT_math_agree(this, mRes, mCtx));
+ unitTests.add(new UT_min(this, mRes, mCtx));
+ unitTests.add(new UT_int4(this, mRes, mCtx));
+ unitTests.add(new UT_element(this, mRes, mCtx));
+ unitTests.add(new UT_sampler(this, mRes, mCtx));
+ unitTests.add(new UT_fp_mad(this, mRes, mCtx));
+
+ /*
+ unitTests.add(new UnitTest(null, "<Pass>", 1));
+ unitTests.add(new UnitTest());
+ unitTests.add(new UnitTest(null, "<Fail>", -1));
+
+ for (int i = 0; i < 20; i++) {
+ unitTests.add(new UnitTest(null, "<Pass>", 1));
+ }
+ */
+
+ UnitTest [] uta = new UnitTest[unitTests.size()];
+ uta = unitTests.toArray(uta);
+
+ mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length);
+ for (int i = 0; i < uta.length; i++) {
+
+ ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item();
+ listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT);
+ listElem.result = uta[i].getResult();
+ mListAllocs.set(listElem, i, false);
+ uta[i].setItem(listElem);
+ }
+
+ mListAllocs.copyAll();
+
+ testAdapter = new ArrayAdapter<UnitTest>(mCtx, android.R.layout.simple_list_item_1, unitTests);
+ mCtx.setListAdapter(testAdapter);
+
+ test_iter = unitTests.listIterator();
+ refreshTestResults(); /* Kick off the first test */
+
+ TimerTask pTask = new TimerTask() {
+ public void run() {
+ refreshTestResults();
+ }
+ };
+
+ mTimer = new Timer();
+ mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD);
+ }
+
+ public void checkAndRunNextTest() {
+ mCtx.runOnUiThread(new Runnable() {
+ public void run() {
+ if (testAdapter != null)
+ testAdapter.notifyDataSetChanged();
+ }
+ });
+
+ if (activeTest != null) {
+ if (!activeTest.isAlive()) {
+ /* Properly clean up on our last test */
+ try {
+ activeTest.join();
+ }
+ catch (InterruptedException e) {
+ }
+ activeTest = null;
+ }
+ }
+
+ if (!stopTesting && activeTest == null) {
+ if (test_iter.hasNext()) {
+ activeTest = test_iter.next();
+ activeTest.start();
+ /* This routine will only get called once when a new test
+ * should start running. The message handler in UnitTest.java
+ * ensures this. */
+ }
+ else {
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+ }
+ }
+ }
+
+ public void refreshTestResults() {
+ checkAndRunNextTest();
+ }
+
+ public void cleanup() {
+ stopTesting = true;
+ UnitTest t = activeTest;
+
+ /* Stop periodic refresh of testing */
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer.purge();
+ mTimer = null;
+ }
+
+ /* Wait to exit until we finish the current test */
+ if (t != null) {
+ try {
+ t.join();
+ }
+ catch (InterruptedException e) {
+ }
+ t = null;
+ }
+
+ }
+
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_alloc.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_alloc.java
new file mode 100644
index 0000000..92362b8
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_alloc.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_alloc extends UnitTest {
+ private Resources mRes;
+
+ protected UT_alloc(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Alloc", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_alloc s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ int Z = 0;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ s.set_dimZ(Z);
+ typeBuilder.setX(X).setY(Y);
+ Allocation A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+
+ typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ typeBuilder.setX(X).setY(Y).setFaces(true);
+ Allocation AFaces = Allocation.createTyped(RS, typeBuilder.create());
+ s.set_aFaces(AFaces);
+ typeBuilder.setFaces(false).setMipmaps(true);
+ Allocation ALOD = Allocation.createTyped(RS, typeBuilder.create());
+ s.set_aLOD(ALOD);
+ typeBuilder.setFaces(true).setMipmaps(true);
+ Allocation AFacesLOD = Allocation.createTyped(RS, typeBuilder.create());
+ s.set_aFacesLOD(AFacesLOD);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_alloc s = new ScriptC_alloc(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_alloc_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_alloc.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_alloc.java
new file mode 100644
index 0000000..7be30a5
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_alloc.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_array_alloc extends UnitTest {
+ private Resources mRes;
+
+ protected UT_array_alloc(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Array Allocation", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_array_alloc s = new ScriptC_array_alloc(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ int dimX = s.get_dimX();
+ Allocation[] Arr = new Allocation[dimX];
+ Type.Builder typeBuilder = new Type.Builder(pRS, Element.I32(pRS));
+ Type T = typeBuilder.setX(1).create();
+ for (int i = 0; i < dimX; i++) {
+ Allocation A = Allocation.createTyped(pRS, T);
+ Arr[i] = A;
+ }
+ s.set_a(Arr);
+
+ s.invoke_array_alloc_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ passTest();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_init.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_init.java
new file mode 100644
index 0000000..9c4b420
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_array_init.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_array_init extends UnitTest {
+ private Resources mRes;
+
+ protected UT_array_init(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Array Init", ctx);
+ mRes = res;
+ }
+
+ private void checkInit(ScriptC_array_init s) {
+ float[] fa = s.get_fa();
+ _RS_ASSERT("fa[0] == 1.0", fa[0] == 1.0);
+ _RS_ASSERT("fa[1] == 9.9999f", fa[1] == 9.9999f);
+ _RS_ASSERT("fa[2] == 0", fa[2] == 0);
+ _RS_ASSERT("fa[3] == 0", fa[3] == 0);
+ _RS_ASSERT("fa.length == 4", fa.length == 4);
+
+ double[] da = s.get_da();
+ _RS_ASSERT("da[0] == 7.0", da[0] == 7.0);
+ _RS_ASSERT("da[1] == 8.88888", da[1] == 8.88888);
+ _RS_ASSERT("da.length == 2", da.length == 2);
+
+ byte[] ca = s.get_ca();
+ _RS_ASSERT("ca[0] == 'a'", ca[0] == 'a');
+ _RS_ASSERT("ca[1] == 7", ca[1] == 7);
+ _RS_ASSERT("ca[2] == 'b'", ca[2] == 'b');
+ _RS_ASSERT("ca[3] == 'c'", ca[3] == 'c');
+ _RS_ASSERT("ca.length == 4", ca.length == 4);
+
+ short[] sa = s.get_sa();
+ _RS_ASSERT("sa[0] == 1", sa[0] == 1);
+ _RS_ASSERT("sa[1] == 1", sa[1] == 1);
+ _RS_ASSERT("sa[2] == 2", sa[2] == 2);
+ _RS_ASSERT("sa[3] == 3", sa[3] == 3);
+ _RS_ASSERT("sa.length == 4", sa.length == 4);
+
+ int[] ia = s.get_ia();
+ _RS_ASSERT("ia[0] == 5", ia[0] == 5);
+ _RS_ASSERT("ia[1] == 8", ia[1] == 8);
+ _RS_ASSERT("ia[2] == 0", ia[2] == 0);
+ _RS_ASSERT("ia[3] == 0", ia[3] == 0);
+ _RS_ASSERT("ia.length == 4", ia.length == 4);
+
+ long[] la = s.get_la();
+ _RS_ASSERT("la[0] == 13", la[0] == 13);
+ _RS_ASSERT("la[1] == 21", la[1] == 21);
+ _RS_ASSERT("la.length == 4", la.length == 2);
+
+ long[] lla = s.get_lla();
+ _RS_ASSERT("lla[0] == 34", lla[0] == 34);
+ _RS_ASSERT("lla[1] == 0", lla[1] == 0);
+ _RS_ASSERT("lla[2] == 0", lla[2] == 0);
+ _RS_ASSERT("lla[3] == 0", lla[3] == 0);
+ _RS_ASSERT("lla.length == 4", lla.length == 4);
+
+ boolean[] ba = s.get_ba();
+ _RS_ASSERT("ba[0] == true", ba[0] == true);
+ _RS_ASSERT("ba[1] == false", ba[1] == false);
+ _RS_ASSERT("ba[2] == false", ba[2] == false);
+ _RS_ASSERT("ba.length == 3", ba.length == 3);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_array_init s = new ScriptC_array_init(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ checkInit(s);
+ s.invoke_array_init_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ passTest();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_atomic.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_atomic.java
new file mode 100644
index 0000000..9f94b7f
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_atomic.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_atomic extends UnitTest {
+ private Resources mRes;
+
+ protected UT_atomic(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Atomics", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_atomic s = new ScriptC_atomic(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_atomic_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_bug_char.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_bug_char.java
new file mode 100644
index 0000000..18389ed
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_bug_char.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import java.util.Arrays;
+
+public class UT_bug_char extends UnitTest {
+ private Resources mRes;
+
+ protected UT_bug_char(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Bug Char", ctx);
+ mRes = res;
+ }
+
+ // packing functions
+ private Byte2 pack_b2(byte[] val) {
+ assert val.length == 2;
+ Log.i("bug_char", "pack_b2 " + val[0] + " " + val[1]);
+ return new Byte2(val[0], val[1]);
+ }
+
+ private byte min(byte v1, byte v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private byte[] min(byte[] v1, byte[] v2) {
+ assert v1.length == v2.length;
+ byte[] rv = new byte[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+
+ private void initializeValues(ScriptC_bug_char s) {
+ byte rand_sc1_0 = (byte)7;
+ byte[] rand_sc2_0 = new byte[2];
+ rand_sc2_0[0] = 11;
+ rand_sc2_0[1] = 21;
+ Log.i("bug_char", "Generated sc2_0 to " + Arrays.toString(rand_sc2_0));
+ byte rand_sc1_1 = (byte)10;
+ byte[] rand_sc2_1 = new byte[2];
+ rand_sc2_1[0] = 13;
+ rand_sc2_1[1] = 15;
+ Log.i("bug_char", "Generated sc2_1 to " + Arrays.toString(rand_sc2_1));
+
+ s.set_rand_sc1_0(rand_sc1_0);
+ s.set_rand_sc2_0(pack_b2(rand_sc2_0));
+ s.set_rand_sc1_1(rand_sc1_1);
+ s.set_rand_sc2_1(pack_b2(rand_sc2_1));
+ // Set results for min
+ s.set_min_rand_sc1_sc1(min(rand_sc1_0, rand_sc1_1));
+ byte[] min_rand_sc2_raw = min(rand_sc2_0, rand_sc2_1);
+ Log.i("bug_char", "Generating min_rand_sc2_sc2 to " +
+ Arrays.toString(min_rand_sc2_raw));
+ Byte2 min_rand_sc2 = pack_b2(min_rand_sc2_raw);
+ Log.i("bug_char", "Setting min_rand_sc2_sc2 to [" + min_rand_sc2.x +
+ ", " + min_rand_sc2.y + "]");
+ s.set_min_rand_sc2_sc2(min_rand_sc2);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_bug_char s = new ScriptC_bug_char(pRS, mRes,
+ R.raw.bug_char);
+ pRS.setMessageHandler(mRsMessage);
+ initializeValues(s);
+ s.invoke_bug_char_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp.java
new file mode 100644
index 0000000..e8b865a
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_clamp extends UnitTest {
+ private Resources mRes;
+
+ protected UT_clamp(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Clamp (Full)", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_clamp s = new ScriptC_clamp(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_clamp_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp_relaxed.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp_relaxed.java
new file mode 100644
index 0000000..738b121
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_clamp_relaxed.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_clamp_relaxed extends UnitTest {
+ private Resources mRes;
+
+ protected UT_clamp_relaxed(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Clamp (Relaxed)", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_clamp_relaxed s =
+ new ScriptC_clamp_relaxed(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_clamp_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_constant.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_constant.java
new file mode 100644
index 0000000..aca656b
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_constant.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_constant extends UnitTest {
+ private Resources mRes;
+
+ protected UT_constant(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Const", ctx);
+ mRes = res;
+ }
+
+ private void Assert(boolean b) {
+ if (!b) {
+ failTest();
+ }
+ }
+
+ public void run() {
+ Assert(ScriptC_constant.const_floatTest == 1.99f);
+ Assert(ScriptC_constant.const_doubleTest == 2.05);
+ Assert(ScriptC_constant.const_charTest == -8);
+ Assert(ScriptC_constant.const_shortTest == -16);
+ Assert(ScriptC_constant.const_intTest == -32);
+ Assert(ScriptC_constant.const_longTest == 17179869184l);
+ Assert(ScriptC_constant.const_longlongTest == 68719476736l);
+
+ Assert(ScriptC_constant.const_ucharTest == 8);
+ Assert(ScriptC_constant.const_ushortTest == 16);
+ Assert(ScriptC_constant.const_uintTest == 32);
+ Assert(ScriptC_constant.const_ulongTest == 4611686018427387904L);
+ Assert(ScriptC_constant.const_int64_tTest == -17179869184l);
+ Assert(ScriptC_constant.const_uint64_tTest == 117179869184l);
+
+ Assert(ScriptC_constant.const_boolTest == true);
+
+ passTest();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert.java
new file mode 100644
index 0000000..bc2797d
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_convert extends UnitTest {
+ private Resources mRes;
+
+ protected UT_convert(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Convert", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_convert s = new ScriptC_convert(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_convert_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert_relaxed.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert_relaxed.java
new file mode 100644
index 0000000..5f3ffb7
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_convert_relaxed.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_convert_relaxed extends UnitTest {
+ private Resources mRes;
+
+ protected UT_convert_relaxed(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Convert (Relaxed)", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_convert_relaxed s =
+ new ScriptC_convert_relaxed(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_convert_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_copy_test.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_copy_test.java
new file mode 100644
index 0000000..e94a877
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_copy_test.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+
+public class UT_copy_test extends UnitTest {
+ private Resources mRes;
+ boolean pass = true;
+
+ protected UT_copy_test(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Copy", ctx);
+ mRes = res;
+ }
+
+ void testFloat2(RenderScript rs, ScriptC_copy_test s) {
+ Allocation a1 = Allocation.createSized(rs, Element.F32_2(rs), 1024);
+ Allocation a2 = Allocation.createSized(rs, Element.F32_2(rs), 1024);
+
+ float[] f1 = new float[1024 * 2];
+ float[] f2 = new float[1024 * 2];
+ for (int ct=0; ct < f1.length; ct++) {
+ f1[ct] = (float)ct;
+ }
+ a1.copyFrom(f1);
+
+ s.forEach_copyFloat2(a1, a2);
+
+ a2.copyTo(f2);
+ for (int ct=0; ct < f1.length; ct++) {
+ if (f1[ct] != f2[ct]) {
+ failTest();
+ Log.v("RS Test", "Compare failed at " + ct + ", " + f1[ct] + ", " + f2[ct]);
+ }
+ }
+ a1.destroy();
+ a2.destroy();
+ }
+
+ void testFloat3(RenderScript rs, ScriptC_copy_test s) {
+ Allocation a1 = Allocation.createSized(rs, Element.F32_3(rs), 1024);
+ Allocation a2 = Allocation.createSized(rs, Element.F32_3(rs), 1024);
+
+ float[] f1 = new float[1024 * 4];
+ float[] f2 = new float[1024 * 4];
+ for (int ct=0; ct < f1.length; ct++) {
+ f1[ct] = (float)ct;
+ }
+ a1.copyFrom(f1);
+
+ s.forEach_copyFloat3(a1, a2);
+
+ a2.copyTo(f2);
+ for (int ct=0; ct < f1.length; ct++) {
+ if ((f1[ct] != f2[ct]) && ((ct&3) != 3)) {
+ failTest();
+ Log.v("RS Test", "Compare failed at " + ct + ", " + f1[ct] + ", " + f2[ct]);
+ }
+ }
+ a1.destroy();
+ a2.destroy();
+ }
+
+ void testFloat4(RenderScript rs, ScriptC_copy_test s) {
+ Allocation a1 = Allocation.createSized(rs, Element.F32_4(rs), 1024);
+ Allocation a2 = Allocation.createSized(rs, Element.F32_4(rs), 1024);
+
+ float[] f1 = new float[1024 * 4];
+ float[] f2 = new float[1024 * 4];
+ for (int ct=0; ct < f1.length; ct++) {
+ f1[ct] = (float)ct;
+ }
+ a1.copyFrom(f1);
+
+ s.forEach_copyFloat4(a1, a2);
+
+ a2.copyTo(f2);
+ for (int ct=0; ct < f1.length; ct++) {
+ if (f1[ct] != f2[ct]) {
+ failTest();
+ Log.v("RS Test", "Compare failed at " + ct + ", " + f1[ct] + ", " + f2[ct]);
+ }
+ }
+ a1.destroy();
+ a2.destroy();
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_copy_test s = new ScriptC_copy_test(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ testFloat2(pRS, s);
+ testFloat3(pRS, s);
+ testFloat4(pRS, s);
+ s.invoke_sendResult(true);
+
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_element.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_element.java
new file mode 100644
index 0000000..8176903
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_element.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_element extends UnitTest {
+ private Resources mRes;
+
+ Element simpleElem;
+ Element complexElem;
+
+ final String subElemNames[] = {
+ "subElem0",
+ "subElem1",
+ "subElem2",
+ "arrayElem0",
+ "arrayElem1",
+ "subElem3",
+ "subElem4",
+ "subElem5",
+ "subElem6",
+ "subElem_7",
+ };
+
+ final int subElemArraySizes[] = {
+ 1,
+ 1,
+ 1,
+ 2,
+ 5,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ };
+
+ final int subElemOffsets[] = {
+ 0,
+ 4,
+ 8,
+ 12,
+ 20,
+ 40,
+ 44,
+ 48,
+ 64,
+ 80,
+ };
+
+ protected UT_element(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Element", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_element s) {
+ simpleElem = Element.F32_3(RS);
+ complexElem = ScriptField_ComplexStruct.createElement(RS);
+ s.set_simpleElem(simpleElem);
+ s.set_complexElem(complexElem);
+
+ ScriptField_ComplexStruct data = new ScriptField_ComplexStruct(RS, 1);
+ s.bind_complexStruct(data);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_element s = new ScriptC_element(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_element_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+
+ int subElemCount = simpleElem.getSubElementCount();
+ _RS_ASSERT("subElemCount == 0", subElemCount == 0);
+
+ subElemCount = complexElem.getSubElementCount();
+ _RS_ASSERT("subElemCount == 10", subElemCount == 10);
+ _RS_ASSERT("complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof",
+ complexElem.getBytesSize() == ScriptField_ComplexStruct.Item.sizeof);
+
+ for (int i = 0; i < subElemCount; i ++) {
+ _RS_ASSERT("complexElem.getSubElement(i) != null",
+ complexElem.getSubElement(i) != null);
+ _RS_ASSERT("complexElem.getSubElementName(i).equals(subElemNames[i])",
+ complexElem.getSubElementName(i).equals(subElemNames[i]));
+ _RS_ASSERT("complexElem.getSubElementArraySize(i) == subElemArraySizes[i]",
+ complexElem.getSubElementArraySize(i) == subElemArraySizes[i]);
+ _RS_ASSERT("complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]",
+ complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]);
+ }
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach.java
new file mode 100644
index 0000000..c518a00
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011-2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_foreach extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+
+ protected UT_foreach(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ForEach", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_foreach s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ typeBuilder.setX(X).setY(Y);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_foreach s = new ScriptC_foreach(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_root(A);
+ s.invoke_verify_root();
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
+ s.invoke_foreach_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach_bounds.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach_bounds.java
new file mode 100644
index 0000000..7ba10de
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_foreach_bounds.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_foreach_bounds extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+
+ protected UT_foreach_bounds(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ForEach (bounds)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_foreach_bounds s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ typeBuilder.setX(X).setY(Y);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+ s.set_s(s);
+ s.set_ain(A);
+ s.set_aout(A);
+ s.set_xStart(2);
+ s.set_xEnd(5);
+ s.set_yStart(3);
+ s.set_yEnd(6);
+ s.forEach_zero(A);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_foreach_bounds s = new ScriptC_foreach_bounds(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_foreach_bounds_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_fp_mad.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_fp_mad.java
new file mode 100644
index 0000000..279b881
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_fp_mad.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_fp_mad extends UnitTest {
+ private Resources mRes;
+
+ protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Fp_Mad", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_fp_mad s = new ScriptC_fp_mad(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_fp_mad_test(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_int4.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_int4.java
new file mode 100644
index 0000000..ae1eb0f
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_int4.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_int4 extends UnitTest {
+ private Resources mRes;
+
+ protected UT_int4(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "int4", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_int4 s = new ScriptC_int4(pRS, mRes, R.raw.int4);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_int4_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel.java
new file mode 100644
index 0000000..6830fda
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+
+public class UT_kernel extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+ private Allocation B;
+
+ protected UT_kernel(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Kernels (pass-by-value)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_kernel s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ s.set_dimX(X);
+ typeBuilder.setX(X);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_ain(A);
+ B = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_aout(B);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_kernel s = new ScriptC_kernel(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_init_vars(A);
+ s.forEach_root(A, B);
+ s.invoke_verify_root();
+ s.invoke_kernel_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel_struct.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel_struct.java
new file mode 100644
index 0000000..5945bac
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_kernel_struct.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+
+public class UT_kernel_struct extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+ private Allocation B;
+
+ protected UT_kernel_struct(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Kernels (struct pass-by-value)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_kernel_struct s) {
+ int X = 5;
+ s.set_dimX(X);
+ ScriptField_simpleStruct t;
+ t = new ScriptField_simpleStruct(RS, X);
+ s.bind_ain(t);
+ A = t.getAllocation();
+ t = new ScriptField_simpleStruct(RS, X);
+ s.bind_aout(t);
+ B = t.getAllocation();
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_kernel_struct s = new ScriptC_kernel_struct(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_init_vars(A);
+ s.forEach_root(A, B);
+ s.invoke_verify_root();
+ s.invoke_kernel_struct_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math.java
new file mode 100644
index 0000000..a696ac4
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_math extends UnitTest {
+ private Resources mRes;
+
+ protected UT_math(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Math", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_math s = new ScriptC_math(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_math_test(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_agree.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_agree.java
new file mode 100644
index 0000000..14a5fa0
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_agree.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+import android.util.Log;
+import java.util.Arrays;
+import java.util.Random;
+
+public class UT_math_agree extends UnitTest {
+ private Resources mRes;
+ private Random rand;
+
+ protected UT_math_agree(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Math Agreement", ctx);
+ mRes = res;
+ rand = new Random();
+ }
+
+ // packing functions
+ private Float2 pack_f2(float[] val) {
+ assert val.length == 2;
+ return new Float2(val[0], val[1]);
+ }
+ private Float3 pack_f3(float[] val) {
+ assert val.length == 3;
+ return new Float3(val[0], val[1], val[2]);
+ }
+ private Float4 pack_f4(float[] val) {
+ assert val.length == 4;
+ return new Float4(val[0], val[1], val[2], val[3]);
+ }
+ private Byte2 pack_b2(byte[] val) {
+ assert val.length == 2;
+ return new Byte2(val[0], val[1]);
+ }
+ private Byte3 pack_b3(byte[] val) {
+ assert val.length == 3;
+ return new Byte3(val[0], val[1], val[2]);
+ }
+ private Byte4 pack_b4(byte[] val) {
+ assert val.length == 4;
+ return new Byte4(val[0], val[1], val[2], val[3]);
+ }
+ private Short2 pack_s2(short[] val) {
+ assert val.length == 2;
+ return new Short2(val[0], val[1]);
+ }
+ private Short3 pack_s3(short[] val) {
+ assert val.length == 3;
+ return new Short3(val[0], val[1], val[2]);
+ }
+ private Short4 pack_s4(short[] val) {
+ assert val.length == 4;
+ return new Short4(val[0], val[1], val[2], val[3]);
+ }
+ private Int2 pack_i2(int[] val) {
+ assert val.length == 2;
+ return new Int2(val[0], val[1]);
+ }
+ private Int3 pack_i3(int[] val) {
+ assert val.length == 3;
+ return new Int3(val[0], val[1], val[2]);
+ }
+ private Int4 pack_i4(int[] val) {
+ assert val.length == 4;
+ return new Int4(val[0], val[1], val[2], val[3]);
+ }
+ private Long2 pack_l2(long[] val) {
+ assert val.length == 2;
+ return new Long2(val[0], val[1]);
+ }
+ private Long3 pack_l3(long[] val) {
+ assert val.length == 3;
+ return new Long3(val[0], val[1], val[2]);
+ }
+ private Long4 pack_l4(long[] val) {
+ assert val.length == 4;
+ return new Long4(val[0], val[1], val[2], val[3]);
+ }
+
+ // random vector generation functions
+ private float[] randvec_float(int dim) {
+ float[] fv = new float[dim];
+ for (int i = 0; i < dim; ++i)
+ fv[i] = rand.nextFloat();
+ return fv;
+ }
+ private byte[] randvec_char(int dim) {
+ byte[] cv = new byte[dim];
+ rand.nextBytes(cv);
+ return cv;
+ }
+ private short[] randvec_uchar(int dim) {
+ short[] ucv = new short[dim];
+ for (int i = 0; i < dim; ++i)
+ ucv[i] = (short)rand.nextInt(0x1 << 8);
+ return ucv;
+ }
+ private short[] randvec_short(int dim) {
+ short[] sv = new short[dim];
+ for (int i = 0; i < dim; ++i)
+ sv[i] = (short)rand.nextInt(0x1 << 16);
+ return sv;
+ }
+ private int[] randvec_ushort(int dim) {
+ int[] usv = new int[dim];
+ for (int i = 0; i < dim; ++i)
+ usv[i] = rand.nextInt(0x1 << 16);
+ return usv;
+ }
+ private int[] randvec_int(int dim) {
+ int[] iv = new int[dim];
+ for (int i = 0; i < dim; ++i)
+ iv[i] = rand.nextInt();
+ return iv;
+ }
+ private long[] randvec_uint(int dim) {
+ long[] uiv = new long[dim];
+ for (int i = 0; i < dim; ++i)
+ uiv[i] = (long)rand.nextInt() - (long)Integer.MIN_VALUE;
+ return uiv;
+ }
+ private long[] randvec_long(int dim) {
+ long[] lv = new long[dim];
+ for (int i = 0; i < dim; ++i)
+ lv[i] = rand.nextLong();
+ return lv;
+ }
+ // TODO: unsigned long generator
+
+ // min reference functions
+ private float min(float v1, float v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private float[] min(float[] v1, float[] v2) {
+ assert v1.length == v2.length;
+ float[] rv = new float[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+ private byte min(byte v1, byte v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private byte[] min(byte[] v1, byte[] v2) {
+ assert v1.length == v2.length;
+ byte[] rv = new byte[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+ private short min(short v1, short v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private short[] min(short[] v1, short[] v2) {
+ assert v1.length == v2.length;
+ short[] rv = new short[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+ private int min(int v1, int v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private int[] min(int[] v1, int[] v2) {
+ assert v1.length == v2.length;
+ int[] rv = new int[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+ private long min(long v1, long v2) {
+ return v1 < v2 ? v1 : v2;
+ }
+ private long[] min(long[] v1, long[] v2) {
+ assert v1.length == v2.length;
+ long[] rv = new long[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2[i]);
+ return rv;
+ }
+ // TODO: unsigned long version of min
+
+ // max reference functions
+ private float max(float v1, float v2) {
+ return v1 > v2 ? v1 : v2;
+ }
+ private float[] max(float[] v1, float[] v2) {
+ assert v1.length == v2.length;
+ float[] rv = new float[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2[i]);
+ return rv;
+ }
+ private byte max(byte v1, byte v2) {
+ return v1 > v2 ? v1 : v2;
+ }
+ private byte[] max(byte[] v1, byte[] v2) {
+ assert v1.length == v2.length;
+ byte[] rv = new byte[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2[i]);
+ return rv;
+ }
+ private short max(short v1, short v2) {
+ return v1 > v2 ? v1 : v2;
+ }
+ private short[] max(short[] v1, short[] v2) {
+ assert v1.length == v2.length;
+ short[] rv = new short[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2[i]);
+ return rv;
+ }
+ private int max(int v1, int v2) {
+ return v1 > v2 ? v1 : v2;
+ }
+ private int[] max(int[] v1, int[] v2) {
+ assert v1.length == v2.length;
+ int[] rv = new int[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2[i]);
+ return rv;
+ }
+ private long max(long v1, long v2) {
+ return v1 > v2 ? v1 : v2;
+ }
+ private long[] max(long[] v1, long[] v2) {
+ assert v1.length == v2.length;
+ long[] rv = new long[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2[i]);
+ return rv;
+ }
+ // TODO: unsigned long version of max
+
+ // fmin reference functions
+ private float fmin(float v1, float v2) {
+ return min(v1, v2);
+ }
+ private float[] fmin(float[] v1, float[] v2) {
+ return min(v1, v2);
+ }
+ private float[] fmin(float[] v1, float v2) {
+ float[] rv = new float[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = min(v1[i], v2);
+ return rv;
+ }
+
+ // fmax reference functions
+ private float fmax(float v1, float v2) {
+ return max(v1, v2);
+ }
+ private float[] fmax(float[] v1, float[] v2) {
+ return max(v1, v2);
+ }
+ private float[] fmax(float[] v1, float v2) {
+ float[] rv = new float[v1.length];
+ for (int i = 0; i < v1.length; ++i)
+ rv[i] = max(v1[i], v2);
+ return rv;
+ }
+
+ private void initializeValues(ScriptC_math_agree s) {
+ float x = rand.nextFloat();
+ float y = rand.nextFloat();
+
+ s.set_x(x);
+ s.set_y(y);
+ s.set_result_add(x + y);
+ s.set_result_sub(x - y);
+ s.set_result_mul(x * y);
+ s.set_result_div(x / y);
+
+ // Generate random vectors of all types
+ float rand_f1_0 = rand.nextFloat();
+ float[] rand_f2_0 = randvec_float(2);
+ float[] rand_f3_0 = randvec_float(3);
+ float[] rand_f4_0 = randvec_float(4);
+ float rand_f1_1 = rand.nextFloat();
+ float[] rand_f2_1 = randvec_float(2);
+ float[] rand_f3_1 = randvec_float(3);
+ float[] rand_f4_1 = randvec_float(4);
+ short rand_uc1_0 = (short)rand.nextInt(0x1 << 8);
+ short[] rand_uc2_0 = randvec_uchar(2);
+ short[] rand_uc3_0 = randvec_uchar(3);
+ short[] rand_uc4_0 = randvec_uchar(4);
+ short rand_uc1_1 = (short)rand.nextInt(0x1 << 8);
+ short[] rand_uc2_1 = randvec_uchar(2);
+ short[] rand_uc3_1 = randvec_uchar(3);
+ short[] rand_uc4_1 = randvec_uchar(4);
+ short rand_ss1_0 = (short)rand.nextInt(0x1 << 16);
+ short[] rand_ss2_0 = randvec_short(2);
+ short[] rand_ss3_0 = randvec_short(3);
+ short[] rand_ss4_0 = randvec_short(4);
+ short rand_ss1_1 = (short)rand.nextInt(0x1 << 16);
+ short[] rand_ss2_1 = randvec_short(2);
+ short[] rand_ss3_1 = randvec_short(3);
+ short[] rand_ss4_1 = randvec_short(4);
+ int rand_us1_0 = rand.nextInt(0x1 << 16);
+ int[] rand_us2_0 = randvec_ushort(2);
+ int[] rand_us3_0 = randvec_ushort(3);
+ int[] rand_us4_0 = randvec_ushort(4);
+ int rand_us1_1 = rand.nextInt(0x1 << 16);
+ int[] rand_us2_1 = randvec_ushort(2);
+ int[] rand_us3_1 = randvec_ushort(3);
+ int[] rand_us4_1 = randvec_ushort(4);
+ int rand_si1_0 = rand.nextInt();
+ int[] rand_si2_0 = randvec_int(2);
+ int[] rand_si3_0 = randvec_int(3);
+ int[] rand_si4_0 = randvec_int(4);
+ int rand_si1_1 = rand.nextInt();
+ int[] rand_si2_1 = randvec_int(2);
+ int[] rand_si3_1 = randvec_int(3);
+ int[] rand_si4_1 = randvec_int(4);
+ long rand_ui1_0 = (long)rand.nextInt() - (long)Integer.MIN_VALUE;
+ long[] rand_ui2_0 = randvec_uint(2);
+ long[] rand_ui3_0 = randvec_uint(3);
+ long[] rand_ui4_0 = randvec_uint(4);
+ long rand_ui1_1 = (long)rand.nextInt() - (long)Integer.MIN_VALUE;
+ long[] rand_ui2_1 = randvec_uint(2);
+ long[] rand_ui3_1 = randvec_uint(3);
+ long[] rand_ui4_1 = randvec_uint(4);
+ long rand_sl1_0 = rand.nextLong();
+ long[] rand_sl2_0 = randvec_long(2);
+ long[] rand_sl3_0 = randvec_long(3);
+ long[] rand_sl4_0 = randvec_long(4);
+ long rand_sl1_1 = rand.nextLong();
+ long[] rand_sl2_1 = randvec_long(2);
+ long[] rand_sl3_1 = randvec_long(3);
+ long[] rand_sl4_1 = randvec_long(4);
+ byte rand_sc1_0 = (byte)rand.nextInt(0x1 << 8);
+ byte[] rand_sc2_0 = randvec_char(2);
+ byte[] rand_sc3_0 = randvec_char(3);
+ byte[] rand_sc4_0 = randvec_char(4);
+ byte rand_sc1_1 = (byte)rand.nextInt(0x1 << 8);
+ byte[] rand_sc2_1 = randvec_char(2);
+ byte[] rand_sc3_1 = randvec_char(3);
+ byte[] rand_sc4_1 = randvec_char(4);
+ // TODO: generate unsigned long vectors
+
+ // Set random vectors in renderscript code
+ s.set_rand_f1_0(rand_f1_0);
+ s.set_rand_f2_0(pack_f2(rand_f2_0));
+ s.set_rand_f3_0(pack_f3(rand_f3_0));
+ s.set_rand_f4_0(pack_f4(rand_f4_0));
+ s.set_rand_f1_1(rand_f1_1);
+ s.set_rand_f2_1(pack_f2(rand_f2_1));
+ s.set_rand_f3_1(pack_f3(rand_f3_1));
+ s.set_rand_f4_1(pack_f4(rand_f4_1));
+ s.set_rand_uc1_1(rand_uc1_1);
+ s.set_rand_uc2_1(pack_s2(rand_uc2_1));
+ s.set_rand_uc3_1(pack_s3(rand_uc3_1));
+ s.set_rand_uc4_1(pack_s4(rand_uc4_1));
+ s.set_rand_ss1_0(rand_ss1_0);
+ s.set_rand_ss2_0(pack_s2(rand_ss2_0));
+ s.set_rand_ss3_0(pack_s3(rand_ss3_0));
+ s.set_rand_ss4_0(pack_s4(rand_ss4_0));
+ s.set_rand_ss1_1(rand_ss1_1);
+ s.set_rand_ss2_1(pack_s2(rand_ss2_1));
+ s.set_rand_ss3_1(pack_s3(rand_ss3_1));
+ s.set_rand_ss4_1(pack_s4(rand_ss4_1));
+ s.set_rand_us1_0(rand_us1_0);
+ s.set_rand_us2_0(pack_i2(rand_us2_0));
+ s.set_rand_us3_0(pack_i3(rand_us3_0));
+ s.set_rand_us4_0(pack_i4(rand_us4_0));
+ s.set_rand_us1_1(rand_us1_1);
+ s.set_rand_us2_1(pack_i2(rand_us2_1));
+ s.set_rand_us3_1(pack_i3(rand_us3_1));
+ s.set_rand_us4_1(pack_i4(rand_us4_1));
+ s.set_rand_si1_0(rand_si1_0);
+ s.set_rand_si2_0(pack_i2(rand_si2_0));
+ s.set_rand_si3_0(pack_i3(rand_si3_0));
+ s.set_rand_si4_0(pack_i4(rand_si4_0));
+ s.set_rand_si1_1(rand_si1_1);
+ s.set_rand_si2_1(pack_i2(rand_si2_1));
+ s.set_rand_si3_1(pack_i3(rand_si3_1));
+ s.set_rand_si4_1(pack_i4(rand_si4_1));
+ s.set_rand_ui1_0(rand_ui1_0);
+ s.set_rand_ui2_0(pack_l2(rand_ui2_0));
+ s.set_rand_ui3_0(pack_l3(rand_ui3_0));
+ s.set_rand_ui4_0(pack_l4(rand_ui4_0));
+ s.set_rand_ui1_1(rand_ui1_1);
+ s.set_rand_ui2_1(pack_l2(rand_ui2_1));
+ s.set_rand_ui3_1(pack_l3(rand_ui3_1));
+ s.set_rand_ui4_1(pack_l4(rand_ui4_1));
+ s.set_rand_sl1_0(rand_sl1_0);
+ s.set_rand_sl2_0(pack_l2(rand_sl2_0));
+ s.set_rand_sl3_0(pack_l3(rand_sl3_0));
+ s.set_rand_sl4_0(pack_l4(rand_sl4_0));
+ s.set_rand_sl1_1(rand_sl1_1);
+ s.set_rand_sl2_1(pack_l2(rand_sl2_1));
+ s.set_rand_sl3_1(pack_l3(rand_sl3_1));
+ s.set_rand_sl4_1(pack_l4(rand_sl4_1));
+ s.set_rand_uc1_0(rand_uc1_0);
+ s.set_rand_uc2_0(pack_s2(rand_uc2_0));
+ s.set_rand_uc3_0(pack_s3(rand_uc3_0));
+ s.set_rand_uc4_0(pack_s4(rand_uc4_0));
+ s.set_rand_sc1_0(rand_sc1_0);
+ s.set_rand_sc2_0(pack_b2(rand_sc2_0));
+ s.set_rand_sc3_0(pack_b3(rand_sc3_0));
+ s.set_rand_sc4_0(pack_b4(rand_sc4_0));
+ s.set_rand_sc1_1(rand_sc1_1);
+ s.set_rand_sc2_1(pack_b2(rand_sc2_1));
+ s.set_rand_sc3_1(pack_b3(rand_sc3_1));
+ s.set_rand_sc4_1(pack_b4(rand_sc4_1));
+ // TODO: set unsigned long vectors
+
+ // Set results for min
+ s.set_min_rand_f1_f1(min(rand_f1_0, rand_f1_1));
+ s.set_min_rand_f2_f2(pack_f2(min(rand_f2_0, rand_f2_1)));
+ s.set_min_rand_f3_f3(pack_f3(min(rand_f3_0, rand_f3_1)));
+ s.set_min_rand_f4_f4(pack_f4(min(rand_f4_0, rand_f4_1)));
+ s.set_min_rand_uc1_uc1(min(rand_uc1_0, rand_uc1_1));
+ s.set_min_rand_uc2_uc2(pack_s2(min(rand_uc2_0, rand_uc2_1)));
+ s.set_min_rand_uc3_uc3(pack_s3(min(rand_uc3_0, rand_uc3_1)));
+ s.set_min_rand_uc4_uc4(pack_s4(min(rand_uc4_0, rand_uc4_1)));
+ s.set_min_rand_ss1_ss1(min(rand_ss1_0, rand_ss1_1));
+ s.set_min_rand_ss2_ss2(pack_s2(min(rand_ss2_0, rand_ss2_1)));
+ s.set_min_rand_ss3_ss3(pack_s3(min(rand_ss3_0, rand_ss3_1)));
+ s.set_min_rand_ss4_ss4(pack_s4(min(rand_ss4_0, rand_ss4_1)));
+ s.set_min_rand_us1_us1(min(rand_us1_0, rand_us1_1));
+ s.set_min_rand_us2_us2(pack_i2(min(rand_us2_0, rand_us2_1)));
+ s.set_min_rand_us3_us3(pack_i3(min(rand_us3_0, rand_us3_1)));
+ s.set_min_rand_us4_us4(pack_i4(min(rand_us4_0, rand_us4_1)));
+ s.set_min_rand_si1_si1(min(rand_si1_0, rand_si1_1));
+ s.set_min_rand_si2_si2(pack_i2(min(rand_si2_0, rand_si2_1)));
+ s.set_min_rand_si3_si3(pack_i3(min(rand_si3_0, rand_si3_1)));
+ s.set_min_rand_si4_si4(pack_i4(min(rand_si4_0, rand_si4_1)));
+ s.set_min_rand_ui1_ui1(min(rand_ui1_0, rand_ui1_1));
+ s.set_min_rand_ui2_ui2(pack_l2(min(rand_ui2_0, rand_ui2_1)));
+ s.set_min_rand_ui3_ui3(pack_l3(min(rand_ui3_0, rand_ui3_1)));
+ s.set_min_rand_ui4_ui4(pack_l4(min(rand_ui4_0, rand_ui4_1)));
+ s.set_min_rand_sl1_sl1(min(rand_sl1_0, rand_sl1_1));
+ s.set_min_rand_sl2_sl2(pack_l2(min(rand_sl2_0, rand_sl2_1)));
+ s.set_min_rand_sl3_sl3(pack_l3(min(rand_sl3_0, rand_sl3_1)));
+ s.set_min_rand_sl4_sl4(pack_l4(min(rand_sl4_0, rand_sl4_1)));
+ s.set_min_rand_sc1_sc1(min(rand_sc1_0, rand_sc1_1));
+ s.set_min_rand_sc2_sc2(pack_b2(min(rand_sc2_0, rand_sc2_1)));
+ s.set_min_rand_sc3_sc3(pack_b3(min(rand_sc3_0, rand_sc3_1)));
+ s.set_min_rand_sc4_sc4(pack_b4(min(rand_sc4_0, rand_sc4_1)));
+ // TODO: set results for unsigned long min
+
+ // Set results for max
+ s.set_max_rand_f1_f1(max(rand_f1_0, rand_f1_1));
+ s.set_max_rand_f2_f2(pack_f2(max(rand_f2_0, rand_f2_1)));
+ s.set_max_rand_f3_f3(pack_f3(max(rand_f3_0, rand_f3_1)));
+ s.set_max_rand_f4_f4(pack_f4(max(rand_f4_0, rand_f4_1)));
+ s.set_max_rand_uc1_uc1(max(rand_uc1_0, rand_uc1_1));
+ s.set_max_rand_uc2_uc2(pack_s2(max(rand_uc2_0, rand_uc2_1)));
+ s.set_max_rand_uc3_uc3(pack_s3(max(rand_uc3_0, rand_uc3_1)));
+ s.set_max_rand_uc4_uc4(pack_s4(max(rand_uc4_0, rand_uc4_1)));
+ s.set_max_rand_ss1_ss1(max(rand_ss1_0, rand_ss1_1));
+ s.set_max_rand_ss2_ss2(pack_s2(max(rand_ss2_0, rand_ss2_1)));
+ s.set_max_rand_ss3_ss3(pack_s3(max(rand_ss3_0, rand_ss3_1)));
+ s.set_max_rand_ss4_ss4(pack_s4(max(rand_ss4_0, rand_ss4_1)));
+ s.set_max_rand_us1_us1(max(rand_us1_0, rand_us1_1));
+ s.set_max_rand_us2_us2(pack_i2(max(rand_us2_0, rand_us2_1)));
+ s.set_max_rand_us3_us3(pack_i3(max(rand_us3_0, rand_us3_1)));
+ s.set_max_rand_us4_us4(pack_i4(max(rand_us4_0, rand_us4_1)));
+ s.set_max_rand_si1_si1(max(rand_si1_0, rand_si1_1));
+ s.set_max_rand_si2_si2(pack_i2(max(rand_si2_0, rand_si2_1)));
+ s.set_max_rand_si3_si3(pack_i3(max(rand_si3_0, rand_si3_1)));
+ s.set_max_rand_si4_si4(pack_i4(max(rand_si4_0, rand_si4_1)));
+ s.set_max_rand_ui1_ui1(max(rand_ui1_0, rand_ui1_1));
+ s.set_max_rand_ui2_ui2(pack_l2(max(rand_ui2_0, rand_ui2_1)));
+ s.set_max_rand_ui3_ui3(pack_l3(max(rand_ui3_0, rand_ui3_1)));
+ s.set_max_rand_ui4_ui4(pack_l4(max(rand_ui4_0, rand_ui4_1)));
+ s.set_max_rand_sl1_sl1(max(rand_sl1_0, rand_sl1_1));
+ s.set_max_rand_sl2_sl2(pack_l2(max(rand_sl2_0, rand_sl2_1)));
+ s.set_max_rand_sl3_sl3(pack_l3(max(rand_sl3_0, rand_sl3_1)));
+ s.set_max_rand_sl4_sl4(pack_l4(max(rand_sl4_0, rand_sl4_1)));
+ s.set_max_rand_sc1_sc1(max(rand_sc1_0, rand_sc1_1));
+ s.set_max_rand_sc2_sc2(pack_b2(max(rand_sc2_0, rand_sc2_1)));
+ s.set_max_rand_sc3_sc3(pack_b3(max(rand_sc3_0, rand_sc3_1)));
+ s.set_max_rand_sc4_sc4(pack_b4(max(rand_sc4_0, rand_sc4_1)));
+
+ // TODO: set results for unsigned long max
+
+ // Set results for fmin
+ s.set_fmin_rand_f1_f1(fmin(rand_f1_0, rand_f1_1));
+ s.set_fmin_rand_f2_f2(pack_f2(fmin(rand_f2_0, rand_f2_1)));
+ s.set_fmin_rand_f3_f3(pack_f3(fmin(rand_f3_0, rand_f3_1)));
+ s.set_fmin_rand_f4_f4(pack_f4(fmin(rand_f4_0, rand_f4_1)));
+ s.set_fmin_rand_f2_f1(pack_f2(fmin(rand_f2_0, rand_f1_1)));
+ s.set_fmin_rand_f3_f1(pack_f3(fmin(rand_f3_0, rand_f1_1)));
+ s.set_fmin_rand_f4_f1(pack_f4(fmin(rand_f4_0, rand_f1_1)));
+
+ // Set results for fmax
+ s.set_fmax_rand_f1_f1(fmax(rand_f1_0, rand_f1_1));
+ s.set_fmax_rand_f2_f2(pack_f2(fmax(rand_f2_0, rand_f2_1)));
+ s.set_fmax_rand_f3_f3(pack_f3(fmax(rand_f3_0, rand_f3_1)));
+ s.set_fmax_rand_f4_f4(pack_f4(fmax(rand_f4_0, rand_f4_1)));
+ s.set_fmax_rand_f2_f1(pack_f2(fmax(rand_f2_0, rand_f1_1)));
+ s.set_fmax_rand_f3_f1(pack_f3(fmax(rand_f3_0, rand_f1_1)));
+ s.set_fmax_rand_f4_f1(pack_f4(fmax(rand_f4_0, rand_f1_1)));
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_math_agree s = new ScriptC_math_agree(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeValues(s);
+ s.invoke_math_agree_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_conformance.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_conformance.java
new file mode 100644
index 0000000..dc58088
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_math_conformance.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_math_conformance extends UnitTest {
+ private Resources mRes;
+
+ protected UT_math_conformance(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Math Conformance", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_math_conformance s =
+ new ScriptC_math_conformance(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_math_conformance_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ passTest();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_min.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_min.java
new file mode 100644
index 0000000..57fa515
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_min.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_min extends UnitTest {
+ private Resources mRes;
+
+ protected UT_min(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Min (relaxed)", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_min s = new ScriptC_min(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_min_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_noroot.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_noroot.java
new file mode 100644
index 0000000..0f897c8
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_noroot.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011-2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_noroot extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+
+ protected UT_noroot(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ForEach (no root)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_noroot s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ typeBuilder.setX(X).setY(Y);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_noroot s = new ScriptC_noroot(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
+ s.invoke_noroot_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_primitives.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_primitives.java
new file mode 100644
index 0000000..e0ebc1b
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_primitives.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_primitives extends UnitTest {
+ private Resources mRes;
+
+ protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Primitives", ctx);
+ mRes = res;
+ }
+
+ private boolean initializeGlobals(ScriptC_primitives s) {
+ float pF = s.get_floatTest();
+ if (pF != 1.99f) {
+ return false;
+ }
+ s.set_floatTest(2.99f);
+
+ double pD = s.get_doubleTest();
+ if (pD != 2.05) {
+ return false;
+ }
+ s.set_doubleTest(3.05);
+
+ byte pC = s.get_charTest();
+ if (pC != -8) {
+ return false;
+ }
+ s.set_charTest((byte)-16);
+
+ short pS = s.get_shortTest();
+ if (pS != -16) {
+ return false;
+ }
+ s.set_shortTest((short)-32);
+
+ int pI = s.get_intTest();
+ if (pI != -32) {
+ return false;
+ }
+ s.set_intTest(-64);
+
+ long pL = s.get_longTest();
+ if (pL != 17179869184l) {
+ return false;
+ }
+ s.set_longTest(17179869185l);
+
+ long puL = s.get_ulongTest();
+ if (puL != 4611686018427387904L) {
+ return false;
+ }
+ s.set_ulongTest(4611686018427387903L);
+
+
+ long pLL = s.get_longlongTest();
+ if (pLL != 68719476736L) {
+ return false;
+ }
+ s.set_longlongTest(68719476735L);
+
+ long pu64 = s.get_uint64_tTest();
+ if (pu64 != 117179869184l) {
+ return false;
+ }
+ s.set_uint64_tTest(117179869185l);
+
+ return true;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_primitives s = new ScriptC_primitives(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ if (!initializeGlobals(s)) {
+ failTest();
+ } else {
+ s.invoke_primitives_test(0, 0);
+ pRS.finish();
+ waitForMessage();
+ }
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_refcount.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_refcount.java
new file mode 100644
index 0000000..d61a7a0
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_refcount.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_refcount extends UnitTest {
+ private Resources mRes;
+
+ protected UT_refcount(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Refcount", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_refcount s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 500;
+ int Y = 700;
+ typeBuilder.setX(X).setY(Y);
+ Allocation A = Allocation.createTyped(RS, typeBuilder.create());
+ s.set_globalA(A);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ pRS.setMessageHandler(mRsMessage);
+ ScriptC_refcount s = new ScriptC_refcount(pRS);
+ initializeGlobals(pRS, s);
+ s.invoke_refcount_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rsdebug.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rsdebug.java
new file mode 100644
index 0000000..4a2e295
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rsdebug.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_rsdebug extends UnitTest {
+ private Resources mRes;
+
+ protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "rsDebug", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_rsdebug s = new ScriptC_rsdebug(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_test_rsdebug(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstime.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstime.java
new file mode 100644
index 0000000..b6b9447
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstime.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_rstime extends UnitTest {
+ private Resources mRes;
+
+ protected UT_rstime(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "rsTime", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_rstime s = new ScriptC_rstime(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.setTimeZone("America/Los_Angeles");
+ s.invoke_test_rstime(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstypes.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstypes.java
new file mode 100644
index 0000000..2c13734
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_rstypes.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_rstypes extends UnitTest {
+ private Resources mRes;
+
+ protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "rsTypes", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_rstypes s = new ScriptC_rstypes(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_test_rstypes(0, 0);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_sampler.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_sampler.java
new file mode 100644
index 0000000..61f4aad
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_sampler.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_sampler extends UnitTest {
+ private Resources mRes;
+
+ Sampler minification;
+ Sampler magnification;
+ Sampler wrapS;
+ Sampler wrapT;
+ Sampler anisotropy;
+
+ protected UT_sampler(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Sampler", ctx);
+ mRes = res;
+ }
+
+ private Sampler.Builder getDefaultBuilder(RenderScript RS) {
+ Sampler.Builder b = new Sampler.Builder(RS);
+ b.setMinification(Sampler.Value.NEAREST);
+ b.setMagnification(Sampler.Value.NEAREST);
+ b.setWrapS(Sampler.Value.CLAMP);
+ b.setWrapT(Sampler.Value.CLAMP);
+ b.setAnisotropy(1.0f);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_sampler s) {
+ Sampler.Builder b = getDefaultBuilder(RS);
+ b.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
+ minification = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setMagnification(Sampler.Value.LINEAR);
+ magnification = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setWrapS(Sampler.Value.WRAP);
+ wrapS = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setWrapT(Sampler.Value.WRAP);
+ wrapT = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setAnisotropy(8.0f);
+ anisotropy = b.create();
+
+ s.set_minification(minification);
+ s.set_magnification(magnification);
+ s.set_wrapS(wrapS);
+ s.set_wrapT(wrapT);
+ s.set_anisotropy(anisotropy);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_sampler s = new ScriptC_sampler(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_sampler_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+ _RS_ASSERT("minification.getMagnification() == Sampler.Value.NEAREST",
+ minification.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR",
+ minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR);
+ _RS_ASSERT("minification.getWrapS() == Sampler.Value.CLAMP",
+ minification.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("minification.getWrapT() == Sampler.Value.CLAMP",
+ minification.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("minification.getAnisotropy() == 1.0f",
+ minification.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("magnification.getMagnification() == Sampler.Value.LINEAR",
+ magnification.getMagnification() == Sampler.Value.LINEAR);
+ _RS_ASSERT("magnification.getMinification() == Sampler.Value.NEAREST",
+ magnification.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("magnification.getWrapS() == Sampler.Value.CLAMP",
+ magnification.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("magnification.getWrapT() == Sampler.Value.CLAMP",
+ magnification.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("magnification.getAnisotropy() == 1.0f",
+ magnification.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("wrapS.getMagnification() == Sampler.Value.NEAREST",
+ wrapS.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapS.getMinification() == Sampler.Value.NEAREST",
+ wrapS.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapS.getWrapS() == Sampler.Value.WRAP",
+ wrapS.getWrapS() == Sampler.Value.WRAP);
+ _RS_ASSERT("wrapS.getWrapT() == Sampler.Value.CLAMP",
+ wrapS.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("wrapS.getAnisotropy() == 1.0f",
+ wrapS.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("wrapT.getMagnification() == Sampler.Value.NEAREST",
+ wrapT.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapT.getMinification() == Sampler.Value.NEAREST",
+ wrapT.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapT.getWrapS() == Sampler.Value.CLAMP",
+ wrapT.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("wrapT.getWrapT() == Sampler.Value.WRAP",
+ wrapT.getWrapT() == Sampler.Value.WRAP);
+ _RS_ASSERT("wrapT.getAnisotropy() == 1.0f",
+ wrapT.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("anisotropy.getMagnification() == Sampler.Value.NEAREST",
+ anisotropy.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("anisotropy.getMinification() == Sampler.Value.NEAREST",
+ anisotropy.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("anisotropy.getWrapS() == Sampler.Value.CLAMP",
+ anisotropy.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("anisotropy.getWrapT() == Sampler.Value.CLAMP",
+ anisotropy.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("anisotropy.getAnisotropy() == 1.0f",
+ anisotropy.getAnisotropy() == 8.0f);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_struct.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_struct.java
new file mode 100644
index 0000000..053112f
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_struct.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_struct extends UnitTest {
+ private Resources mRes;
+
+ protected UT_struct(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Struct", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_struct s = new ScriptC_struct(pRS);
+ pRS.setMessageHandler(mRsMessage);
+
+ ScriptField_Point2 p = new ScriptField_Point2(pRS, 1);
+ ScriptField_Point2.Item i = new ScriptField_Point2.Item();
+ int val = 100;
+ i.x = val;
+ i.y = val;
+ p.set(i, 0, true);
+ s.bind_point2(p);
+ s.invoke_struct_test(val);
+ pRS.finish();
+ waitForMessage();
+
+ val = 200;
+ p.set_x(0, val, true);
+ p.set_y(0, val, true);
+ s.invoke_struct_test(val);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_unsigned.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_unsigned.java
new file mode 100644
index 0000000..adb17100
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_unsigned.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_unsigned extends UnitTest {
+ private Resources mRes;
+
+ protected UT_unsigned(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Unsigned", ctx);
+ mRes = res;
+ }
+
+ private boolean initializeGlobals(ScriptC_unsigned s) {
+ short pUC = s.get_uc();
+ if (pUC != 5) {
+ return false;
+ }
+ s.set_uc((short)129);
+
+ long pUI = s.get_ui();
+ if (pUI != 37) {
+ return false;
+ }
+ s.set_ui(0x7fffffff);
+
+ return true;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_unsigned s = new ScriptC_unsigned(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ if (!initializeGlobals(s)) {
+ failTest();
+ } else {
+ s.invoke_unsigned_test();
+ pRS.finish();
+ waitForMessage();
+ }
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_vector.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_vector.java
new file mode 100644
index 0000000..47b7a6a
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UT_vector.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.v8.renderscript.*;
+
+public class UT_vector extends UnitTest {
+ private Resources mRes;
+
+ protected UT_vector(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Vector", ctx);
+ mRes = res;
+ }
+
+ private boolean initializeGlobals(ScriptC_vector s) {
+ Float2 F2 = s.get_f2();
+ if (F2.x != 1.0f || F2.y != 2.0f) {
+ return false;
+ }
+ F2.x = 2.99f;
+ F2.y = 3.99f;
+ s.set_f2(F2);
+
+ Float3 F3 = s.get_f3();
+ if (F3.x != 1.0f || F3.y != 2.0f || F3.z != 3.0f) {
+ return false;
+ }
+ F3.x = 2.99f;
+ F3.y = 3.99f;
+ F3.z = 4.99f;
+ s.set_f3(F3);
+
+ Float4 F4 = s.get_f4();
+ if (F4.x != 1.0f || F4.y != 2.0f || F4.z != 3.0f || F4.w != 4.0f) {
+ return false;
+ }
+ F4.x = 2.99f;
+ F4.y = 3.99f;
+ F4.z = 4.99f;
+ F4.w = 5.99f;
+ s.set_f4(F4);
+
+ Double2 D2 = s.get_d2();
+ if (D2.x != 1.0 || D2.y != 2.0) {
+ return false;
+ }
+ D2.x = 2.99;
+ D2.y = 3.99;
+ s.set_d2(D2);
+
+ Double3 D3 = s.get_d3();
+ if (D3.x != 1.0 || D3.y != 2.0 || D3.z != 3.0) {
+ return false;
+ }
+ D3.x = 2.99;
+ D3.y = 3.99;
+ D3.z = 4.99;
+ s.set_d3(D3);
+
+ Double4 D4 = s.get_d4();
+ if (D4.x != 1.0 || D4.y != 2.0 || D4.z != 3.0 || D4.w != 4.0) {
+ return false;
+ }
+ D4.x = 2.99;
+ D4.y = 3.99;
+ D4.z = 4.99;
+ D4.w = 5.99;
+ s.set_d4(D4);
+
+ Byte2 B2 = s.get_i8_2();
+ if (B2.x != 1 || B2.y != 2) {
+ return false;
+ }
+ B2.x = 2;
+ B2.y = 3;
+ s.set_i8_2(B2);
+
+ Byte3 B3 = s.get_i8_3();
+ if (B3.x != 1 || B3.y != 2 || B3.z != 3) {
+ return false;
+ }
+ B3.x = 2;
+ B3.y = 3;
+ B3.z = 4;
+ s.set_i8_3(B3);
+
+ Byte4 B4 = s.get_i8_4();
+ if (B4.x != 1 || B4.y != 2 || B4.z != 3 || B4.w != 4) {
+ return false;
+ }
+ B4.x = 2;
+ B4.y = 3;
+ B4.z = 4;
+ B4.w = 5;
+ s.set_i8_4(B4);
+
+ Short2 S2 = s.get_u8_2();
+ if (S2.x != 1 || S2.y != 2) {
+ return false;
+ }
+ S2.x = 2;
+ S2.y = 3;
+ s.set_u8_2(S2);
+
+ Short3 S3 = s.get_u8_3();
+ if (S3.x != 1 || S3.y != 2 || S3.z != 3) {
+ return false;
+ }
+ S3.x = 2;
+ S3.y = 3;
+ S3.z = 4;
+ s.set_u8_3(S3);
+
+ Short4 S4 = s.get_u8_4();
+ if (S4.x != 1 || S4.y != 2 || S4.z != 3 || S4.w != 4) {
+ return false;
+ }
+ S4.x = 2;
+ S4.y = 3;
+ S4.z = 4;
+ S4.w = 5;
+ s.set_u8_4(S4);
+
+ S2 = s.get_i16_2();
+ if (S2.x != 1 || S2.y != 2) {
+ return false;
+ }
+ S2.x = 2;
+ S2.y = 3;
+ s.set_i16_2(S2);
+
+ S3 = s.get_i16_3();
+ if (S3.x != 1 || S3.y != 2 || S3.z != 3) {
+ return false;
+ }
+ S3.x = 2;
+ S3.y = 3;
+ S3.z = 4;
+ s.set_i16_3(S3);
+
+ S4 = s.get_i16_4();
+ if (S4.x != 1 || S4.y != 2 || S4.z != 3 || S4.w != 4) {
+ return false;
+ }
+ S4.x = 2;
+ S4.y = 3;
+ S4.z = 4;
+ S4.w = 5;
+ s.set_i16_4(S4);
+
+ Int2 I2 = s.get_u16_2();
+ if (I2.x != 1 || I2.y != 2) {
+ return false;
+ }
+ I2.x = 2;
+ I2.y = 3;
+ s.set_u16_2(I2);
+
+ Int3 I3 = s.get_u16_3();
+ if (I3.x != 1 || I3.y != 2 || I3.z != 3) {
+ return false;
+ }
+ I3.x = 2;
+ I3.y = 3;
+ I3.z = 4;
+ s.set_u16_3(I3);
+
+ Int4 I4 = s.get_u16_4();
+ if (I4.x != 1 || I4.y != 2 || I4.z != 3 || I4.w != 4) {
+ return false;
+ }
+ I4.x = 2;
+ I4.y = 3;
+ I4.z = 4;
+ I4.w = 5;
+ s.set_u16_4(I4);
+
+ I2 = s.get_i32_2();
+ if (I2.x != 1 || I2.y != 2) {
+ return false;
+ }
+ I2.x = 2;
+ I2.y = 3;
+ s.set_i32_2(I2);
+
+ I3 = s.get_i32_3();
+ if (I3.x != 1 || I3.y != 2 || I3.z != 3) {
+ return false;
+ }
+ I3.x = 2;
+ I3.y = 3;
+ I3.z = 4;
+ s.set_i32_3(I3);
+
+ I4 = s.get_i32_4();
+ if (I4.x != 1 || I4.y != 2 || I4.z != 3 || I4.w != 4) {
+ return false;
+ }
+ I4.x = 2;
+ I4.y = 3;
+ I4.z = 4;
+ I4.w = 5;
+ s.set_i32_4(I4);
+
+ Long2 L2 = s.get_u32_2();
+ if (L2.x != 1 || L2.y != 2) {
+ return false;
+ }
+ L2.x = 2;
+ L2.y = 3;
+ s.set_u32_2(L2);
+
+ Long3 L3 = s.get_u32_3();
+ if (L3.x != 1 || L3.y != 2 || L3.z != 3) {
+ return false;
+ }
+ L3.x = 2;
+ L3.y = 3;
+ L3.z = 4;
+ s.set_u32_3(L3);
+
+ Long4 L4 = s.get_u32_4();
+ if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) {
+ return false;
+ }
+ L4.x = 2;
+ L4.y = 3;
+ L4.z = 4;
+ L4.w = 5;
+ s.set_u32_4(L4);
+
+ L2 = s.get_i64_2();
+ if (L2.x != 1 || L2.y != 2) {
+ return false;
+ }
+ L2.x = 2;
+ L2.y = 3;
+ s.set_i64_2(L2);
+
+ L3 = s.get_i64_3();
+ if (L3.x != 1 || L3.y != 2 || L3.z != 3) {
+ return false;
+ }
+ L3.x = 2;
+ L3.y = 3;
+ L3.z = 4;
+ s.set_i64_3(L3);
+
+ L4 = s.get_i64_4();
+ if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) {
+ return false;
+ }
+ L4.x = 2;
+ L4.y = 3;
+ L4.z = 4;
+ L4.w = 5;
+ s.set_i64_4(L4);
+
+ L2 = s.get_u64_2();
+ if (L2.x != 1 || L2.y != 2) {
+ return false;
+ }
+ L2.x = 2;
+ L2.y = 3;
+ s.set_u64_2(L2);
+
+ L3 = s.get_u64_3();
+ if (L3.x != 1 || L3.y != 2 || L3.z != 3) {
+ return false;
+ }
+ L3.x = 2;
+ L3.y = 3;
+ L3.z = 4;
+ s.set_u64_3(L3);
+
+ L4 = s.get_u64_4();
+ if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) {
+ return false;
+ }
+ L4.x = 2;
+ L4.y = 3;
+ L4.z = 4;
+ L4.w = 5;
+ s.set_u64_4(L4);
+
+ return true;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_vector s = new ScriptC_vector(pRS);
+ pRS.setMessageHandler(mRsMessage);
+ if (!initializeGlobals(s)) {
+ failTest();
+ } else {
+ s.invoke_vector_test();
+ pRS.finish();
+ waitForMessage();
+ }
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UnitTest.java
new file mode 100644
index 0000000..a95584f
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/UnitTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2013 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 com.android.rs.test;
+import android.content.Context;
+import android.util.Log;
+import android.support.v8.renderscript.RenderScript.RSMessageHandler;
+
+public class UnitTest extends Thread {
+ public String name;
+ private int result;
+ private ScriptField_ListAllocs_s.Item mItem;
+ private RSTestCore mRSTC;
+ private boolean msgHandled;
+ protected Context mCtx;
+
+ /* These constants must match those in shared.rsh */
+ public static final int RS_MSG_TEST_PASSED = 100;
+ public static final int RS_MSG_TEST_FAILED = 101;
+
+ private static int numTests = 0;
+ public int testID;
+
+ protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) {
+ super();
+ mRSTC = rstc;
+ name = n;
+ msgHandled = false;
+ mCtx = ctx;
+ result = initResult;
+ testID = numTests++;
+ }
+
+ protected UnitTest(RSTestCore rstc, String n, Context ctx) {
+ this(rstc, n, 0, ctx);
+ }
+
+ protected UnitTest(RSTestCore rstc, Context ctx) {
+ this (rstc, "<Unknown>", ctx);
+ }
+
+ protected UnitTest(Context ctx) {
+ this (null, ctx);
+ }
+
+ protected void _RS_ASSERT(String message, boolean b) {
+ if(b == false) {
+ Log.e(name, message + " FAILED");
+ failTest();
+ }
+ }
+
+ private void updateUI() {
+ if (mItem != null) {
+ mItem.result = result;
+ msgHandled = true;
+ try {
+ mRSTC.refreshTestResults();
+ }
+ catch (IllegalStateException e) {
+ /* Ignore the case where our message receiver has been
+ disconnected. This happens when we leave the application
+ before it finishes running all of the unit tests. */
+ }
+ }
+ }
+
+ protected RSMessageHandler mRsMessage = new RSMessageHandler() {
+ public void run() {
+ if (result == 0) {
+ switch (mID) {
+ case RS_MSG_TEST_PASSED:
+ result = 1;
+ break;
+ case RS_MSG_TEST_FAILED:
+ result = -1;
+ break;
+ default:
+ RSTest.log("Unit test got unexpected message");
+ return;
+ }
+ }
+
+ updateUI();
+ }
+ };
+
+ public void waitForMessage() {
+ while (!msgHandled) {
+ yield();
+ }
+ }
+
+ public int getResult() {
+ return result;
+ }
+
+ public void failTest() {
+ result = -1;
+ updateUI();
+ }
+
+ public void passTest() {
+ if (result != -1) {
+ result = 1;
+ }
+ updateUI();
+ }
+
+ public String toString() {
+ String out = name;
+ if (result == 1) {
+ out += " - PASSED";
+ }
+ else if (result == -1) {
+ out += " - FAILED";
+ }
+ return out;
+ }
+
+ public void setItem(ScriptField_ListAllocs_s.Item item) {
+ mItem = item;
+ }
+
+ public void run() {
+ /* This method needs to be implemented for each subclass */
+ if (mRSTC != null) {
+ mRSTC.refreshTestResults();
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/alloc.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/alloc.rs
new file mode 100644
index 0000000..3116e5a
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/alloc.rs
@@ -0,0 +1,94 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+int dimZ;
+
+rs_allocation aFaces;
+rs_allocation aLOD;
+rs_allocation aFacesLOD;
+
+static bool test_alloc_dims() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ a[i + j * dimX] = i + j * dimX;
+ }
+ }
+
+ rs_allocation alloc = rsGetAllocation(a);
+ _RS_ASSERT(rsAllocationGetDimX(alloc) == dimX);
+ _RS_ASSERT(rsAllocationGetDimY(alloc) == dimY);
+ _RS_ASSERT(rsAllocationGetDimZ(alloc) == dimZ);
+
+ // Test 2D addressing
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ rsDebug("Verifying ", i + j * dimX);
+ const void *p = rsGetElementAt(alloc, i, j);
+ int val = *(const int *)p;
+ _RS_ASSERT(val == (i + j * dimX));
+ }
+ }
+
+ // Test 1D addressing
+ for (i = 0; i < dimX * dimY; i++) {
+ rsDebug("Verifying ", i);
+ const void *p = rsGetElementAt(alloc, i);
+ int val = *(const int *)p;
+ _RS_ASSERT(val == i);
+ }
+
+ // Test 3D addressing
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ rsDebug("Verifying ", i + j * dimX);
+ const void *p = rsGetElementAt(alloc, i, j, 0);
+ int val = *(const int *)p;
+ _RS_ASSERT(val == (i + j * dimX));
+ }
+ }
+
+ _RS_ASSERT(rsAllocationGetDimX(aFaces) == dimX);
+ _RS_ASSERT(rsAllocationGetDimY(aFaces) == dimY);
+ _RS_ASSERT(rsAllocationGetDimZ(aFaces) == dimZ);
+ _RS_ASSERT(rsAllocationGetDimFaces(aFaces) != 0);
+ _RS_ASSERT(rsAllocationGetDimLOD(aFaces) == 0);
+
+ _RS_ASSERT(rsAllocationGetDimX(aLOD) == dimX);
+ _RS_ASSERT(rsAllocationGetDimY(aLOD) == dimY);
+ _RS_ASSERT(rsAllocationGetDimZ(aLOD) == dimZ);
+ _RS_ASSERT(rsAllocationGetDimFaces(aLOD) == 0);
+ _RS_ASSERT(rsAllocationGetDimLOD(aLOD) != 0);
+
+ _RS_ASSERT(rsAllocationGetDimX(aFacesLOD) == dimX);
+ _RS_ASSERT(rsAllocationGetDimY(aFacesLOD) == dimY);
+ _RS_ASSERT(rsAllocationGetDimZ(aFacesLOD) == dimZ);
+ _RS_ASSERT(rsAllocationGetDimFaces(aFacesLOD) != 0);
+ _RS_ASSERT(rsAllocationGetDimLOD(aFacesLOD) != 0);
+
+ if (failed) {
+ rsDebug("test_alloc_dims FAILED", 0);
+ }
+ else {
+ rsDebug("test_alloc_dims PASSED", 0);
+ }
+
+ return failed;
+}
+
+void alloc_test() {
+ bool failed = false;
+ failed |= test_alloc_dims();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_alloc.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_alloc.rs
new file mode 100644
index 0000000..74ffdb1
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_alloc.rs
@@ -0,0 +1,21 @@
+#include "shared.rsh"
+
+const int dimX = 20;
+rs_allocation a[dimX];
+
+void array_alloc_test() {
+ bool failed = false;
+
+ for (int i = 0; i < dimX; i++) {
+ rsDebug("i: ", i);
+ _RS_ASSERT(rsAllocationGetDimX(a[i]) == 1);
+ }
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_init.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_init.rs
new file mode 100644
index 0000000..842249a
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/array_init.rs
@@ -0,0 +1,58 @@
+#include "shared.rsh"
+
+// Testing constant array initialization
+float fa[4] = {1.0, 9.9999f};
+double da[2] = {7.0, 8.88888};
+char ca[4] = {'a', 7, 'b', 'c'};
+short sa[4] = {1, 1, 2, 3};
+int ia[4] = {5, 8};
+long la[2] = {13, 21};
+long long lla[4] = {34};
+bool ba[3] = {true, false};
+
+void array_init_test() {
+ bool failed = false;
+
+ _RS_ASSERT(fa[0] == 1.0);
+ _RS_ASSERT(fa[1] == 9.9999f);
+ _RS_ASSERT(fa[2] == 0);
+ _RS_ASSERT(fa[3] == 0);
+
+ _RS_ASSERT(da[0] == 7.0);
+ _RS_ASSERT(da[1] == 8.88888);
+
+ _RS_ASSERT(ca[0] == 'a');
+ _RS_ASSERT(ca[1] == 7);
+ _RS_ASSERT(ca[2] == 'b');
+ _RS_ASSERT(ca[3] == 'c');
+
+ _RS_ASSERT(sa[0] == 1);
+ _RS_ASSERT(sa[1] == 1);
+ _RS_ASSERT(sa[2] == 2);
+ _RS_ASSERT(sa[3] == 3);
+
+ _RS_ASSERT(ia[0] == 5);
+ _RS_ASSERT(ia[1] == 8);
+ _RS_ASSERT(ia[2] == 0);
+ _RS_ASSERT(ia[3] == 0);
+
+ _RS_ASSERT(la[0] == 13);
+ _RS_ASSERT(la[1] == 21);
+
+ _RS_ASSERT(lla[0] == 34);
+ _RS_ASSERT(lla[1] == 0);
+ _RS_ASSERT(lla[2] == 0);
+ _RS_ASSERT(lla[3] == 0);
+
+ _RS_ASSERT(ba[0] == true);
+ _RS_ASSERT(ba[1] == false);
+ _RS_ASSERT(ba[2] == false);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/atomic.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/atomic.rs
new file mode 100644
index 0000000..f0a5041
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/atomic.rs
@@ -0,0 +1,77 @@
+#include "shared.rsh"
+
+// Testing atomic operations
+static bool testUMax(uint32_t dst, uint32_t src) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst > src ? dst : src);
+ uint32_t ret = rsAtomicMax(&dst, src);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool testUMin(uint32_t dst, uint32_t src) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst < src ? dst : src);
+ uint32_t ret = rsAtomicMin(&dst, src);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool testUCas(uint32_t dst, uint32_t cmp, uint32_t swp) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst == cmp ? swp : dst);
+ uint32_t ret = rsAtomicCas(&dst, cmp, swp);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool test_atomics() {
+ bool failed = false;
+
+ failed |= testUMax(5, 6);
+ failed |= testUMax(6, 5);
+ failed |= testUMax(5, 0xf0000006);
+ failed |= testUMax(0xf0000006, 5);
+
+ failed |= testUMin(5, 6);
+ failed |= testUMin(6, 5);
+ failed |= testUMin(5, 0xf0000006);
+ failed |= testUMin(0xf0000006, 5);
+
+ failed |= testUCas(4, 4, 5);
+ failed |= testUCas(4, 5, 5);
+ failed |= testUCas(5, 5, 4);
+ failed |= testUCas(5, 4, 4);
+ failed |= testUCas(0xf0000004, 0xf0000004, 0xf0000005);
+ failed |= testUCas(0xf0000004, 0xf0000005, 0xf0000005);
+ failed |= testUCas(0xf0000005, 0xf0000005, 0xf0000004);
+ failed |= testUCas(0xf0000005, 0xf0000004, 0xf0000004);
+
+ if (failed) {
+ rsDebug("test_atomics FAILED", 0);
+ }
+ else {
+ rsDebug("test_atomics PASSED", 0);
+ }
+
+ return failed;
+}
+
+void atomic_test() {
+ bool failed = false;
+ failed |= test_atomics();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/bug_char.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/bug_char.rs
new file mode 100644
index 0000000..dcd7b72
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/bug_char.rs
@@ -0,0 +1,47 @@
+#include "shared.rsh"
+
+char rand_sc1_0, rand_sc1_1;
+char2 rand_sc2_0, rand_sc2_1;
+
+char min_rand_sc1_sc1;
+char2 min_rand_sc2_sc2;
+
+static bool test_bug_char() {
+ bool failed = false;
+
+ rsDebug("rand_sc2_0.x: ", rand_sc2_0.x);
+ rsDebug("rand_sc2_0.y: ", rand_sc2_0.y);
+ rsDebug("rand_sc2_1.x: ", rand_sc2_1.x);
+ rsDebug("rand_sc2_1.y: ", rand_sc2_1.y);
+ char temp_sc1;
+ char2 temp_sc2;
+
+ temp_sc1 = min( rand_sc1_0, rand_sc1_1 );
+ if (temp_sc1 != min_rand_sc1_sc1) {
+ rsDebug("temp_sc1", temp_sc1);
+ failed = true;
+ }
+ rsDebug("broken", 'y');
+
+ temp_sc2 = min( rand_sc2_0, rand_sc2_1 );
+ if (temp_sc2.x != min_rand_sc2_sc2.x
+ || temp_sc2.y != min_rand_sc2_sc2.y) {
+ failed = true;
+ }
+
+
+ return failed;
+}
+
+void bug_char_test() {
+ bool failed = false;
+ failed |= test_bug_char();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp.rs
new file mode 100644
index 0000000..28b00bd
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp.rs
@@ -0,0 +1,56 @@
+#include "shared.rsh"
+
+static bool test_clamp_vector() {
+ bool failed = false;
+
+ float2 src2 = { 2.0f, 2.0f};
+ float2 min2 = { 0.5f, -3.0f};
+ float2 max2 = { 1.0f, 9.0f};
+
+ float2 res2 = clamp(src2, min2, max2);
+ _RS_ASSERT(res2.x == 1.0f);
+ _RS_ASSERT(res2.y == 2.0f);
+
+
+ float3 src3 = { 2.0f, 2.0f, 1.0f};
+ float3 min3 = { 0.5f, -3.0f, 3.0f};
+ float3 max3 = { 1.0f, 9.0f, 4.0f};
+
+ float3 res3 = clamp(src3, min3, max3);
+ _RS_ASSERT(res3.x == 1.0f);
+ _RS_ASSERT(res3.y == 2.0f);
+ _RS_ASSERT(res3.z == 3.0f);
+
+
+ float4 src4 = { 2.0f, 2.0f, 1.0f, 4.0f };
+ float4 min4 = { 0.5f, -3.0f, 3.0f, 4.0f };
+ float4 max4 = { 1.0f, 9.0f, 4.0f, 4.0f };
+
+ float4 res4 = clamp(src4, min4, max4);
+ _RS_ASSERT(res4.x == 1.0f);
+ _RS_ASSERT(res4.y == 2.0f);
+ _RS_ASSERT(res4.z == 3.0f);
+ _RS_ASSERT(res4.w == 4.0f);
+
+ if (failed) {
+ rsDebug("test_clamp_vector FAILED", 0);
+ }
+ else {
+ rsDebug("test_clamp_vector PASSED", 0);
+ }
+
+ return failed;
+}
+
+void clamp_test() {
+ bool failed = false;
+ failed |= test_clamp_vector();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp_relaxed.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp_relaxed.rs
new file mode 100644
index 0000000..71c65ae
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/clamp_relaxed.rs
@@ -0,0 +1,2 @@
+#include "clamp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/constant.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/constant.rs
new file mode 100644
index 0000000..732eaef
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/constant.rs
@@ -0,0 +1,19 @@
+#include "shared.rsh"
+
+const float floatTest = 1.99f;
+const double doubleTest = 2.05;
+const char charTest = -8;
+const short shortTest = -16;
+const int intTest = -32;
+const long longTest = 17179869184l; // 1 << 34
+const long long longlongTest = 68719476736l; // 1 << 36
+
+const uchar ucharTest = 8;
+const ushort ushortTest = 16;
+const uint uintTest = 32;
+const ulong ulongTest = 4611686018427387904L;
+const int64_t int64_tTest = -17179869184l; // - 1 << 34
+const uint64_t uint64_tTest = 117179869184l;
+
+const bool boolTest = true;
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert.rs
new file mode 100644
index 0000000..e314f2b
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+
+float4 f4 = { 2.0f, 4.0f, 6.0f, 8.0f };
+
+char4 i8_4 = { -1, -2, -3, 4 };
+
+static bool test_convert() {
+ bool failed = false;
+
+ f4 = convert_float4(i8_4);
+ _RS_ASSERT(f4.x == -1.0f);
+ _RS_ASSERT(f4.y == -2.0f);
+ _RS_ASSERT(f4.z == -3.0f);
+ _RS_ASSERT(f4.w == 4.0f);
+
+ if (failed) {
+ rsDebug("test_convert FAILED", 0);
+ }
+ else {
+ rsDebug("test_convert PASSED", 0);
+ }
+
+ return failed;
+}
+
+void convert_test() {
+ bool failed = false;
+ failed |= test_convert();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert_relaxed.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert_relaxed.rs
new file mode 100644
index 0000000..81abb9b
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/convert_relaxed.rs
@@ -0,0 +1,2 @@
+#include "convert.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/copy_test.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/copy_test.rs
new file mode 100644
index 0000000..f4243eb
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/copy_test.rs
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "shared.rsh"
+
+void sendResult(bool pass) {
+ if (pass) {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+}
+
+
+float2 __attribute((kernel)) copyFloat2(float2 i) {
+ return i;
+}
+
+float3 __attribute((kernel)) copyFloat3(float3 i) {
+ return i;
+}
+
+float4 __attribute((kernel)) copyFloat4(float4 i) {
+ return i;
+}
+
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/element.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/element.rs
new file mode 100644
index 0000000..1f24775
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/element.rs
@@ -0,0 +1,156 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_element simpleElem;
+rs_element complexElem;
+typedef struct ComplexStruct {
+ float subElem0;
+ float subElem1;
+ int subElem2;
+ float arrayElem0[2];
+ int arrayElem1[5];
+ char subElem3;
+ float subElem4;
+ float2 subElem5;
+ float3 subElem6;
+ float4 subElem_7;
+} ComplexStruct_t;
+
+ComplexStruct_t *complexStruct;
+
+static const char *subElemNames[] = {
+ "subElem0",
+ "subElem1",
+ "subElem2",
+ "arrayElem0",
+ "arrayElem1",
+ "subElem3",
+ "subElem4",
+ "subElem5",
+ "subElem6",
+ "subElem_7",
+};
+
+static uint32_t subElemNamesSizes[] = {
+ 8,
+ 8,
+ 8,
+ 10,
+ 10,
+ 8,
+ 8,
+ 8,
+ 8,
+ 9,
+};
+
+static uint32_t subElemArraySizes[] = {
+ 1,
+ 1,
+ 1,
+ 2,
+ 5,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+static void resetStruct() {
+ uint8_t *bytePtr = (uint8_t*)complexStruct;
+ uint32_t sizeOfStruct = sizeof(*complexStruct);
+ for(uint32_t i = 0; i < sizeOfStruct; i ++) {
+ bytePtr[i] = 0;
+ }
+}
+
+static bool equals(const char *name0, const char * name1, uint32_t len) {
+ for (uint32_t i = 0; i < len; i ++) {
+ if (name0[i] != name1[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool test_element_getters() {
+ bool failed = false;
+
+ uint32_t subElemOffsets[10];
+ uint32_t index = 0;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem0 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem1 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem2 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem0 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem1 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem3 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem4 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem5 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem6 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem_7 - (uint32_t)complexStruct;
+
+ uint32_t subElemCount = rsElementGetSubElementCount(simpleElem);
+ _RS_ASSERT(subElemCount == 0);
+ _RS_ASSERT(rsElementGetDataType(simpleElem) == RS_TYPE_FLOAT_32);
+ _RS_ASSERT(rsElementGetVectorSize(simpleElem) == 3);
+
+ subElemCount = rsElementGetSubElementCount(complexElem);
+ _RS_ASSERT(subElemCount == 10);
+ _RS_ASSERT(rsElementGetDataType(complexElem) == RS_TYPE_NONE);
+ _RS_ASSERT(rsElementGetVectorSize(complexElem) == 1);
+ _RS_ASSERT(rsElementGetBytesSize(complexElem) == sizeof(*complexStruct));
+
+ char buffer[64];
+ for (uint32_t i = 0; i < subElemCount; i ++) {
+ rs_element subElem = rsElementGetSubElement(complexElem, i);
+ _RS_ASSERT(rsIsObject(subElem));
+
+ _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, i) == subElemNamesSizes[i] + 1);
+
+ uint32_t written = rsElementGetSubElementName(complexElem, i, buffer, 64);
+ _RS_ASSERT(written == subElemNamesSizes[i]);
+ _RS_ASSERT(equals(buffer, subElemNames[i], written));
+
+ _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, i) == subElemArraySizes[i]);
+ _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, i) == subElemOffsets[i]);
+ }
+
+ // Tests error checking
+ rs_element subElem = rsElementGetSubElement(complexElem, subElemCount);
+ _RS_ASSERT(!rsIsObject(subElem));
+
+ _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, subElemCount) == 0);
+
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, subElemCount, buffer, 64) == 0);
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, NULL, 64) == 0);
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, buffer, 0) == 0);
+ uint32_t written = rsElementGetSubElementName(complexElem, 0, buffer, 5);
+ _RS_ASSERT(written == 4);
+ _RS_ASSERT(buffer[4] == '\0');
+
+ _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, subElemCount) == 0);
+ _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, subElemCount) == 0);
+
+ if (failed) {
+ rsDebug("test_element_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_element_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void element_test() {
+ bool failed = false;
+ failed |= test_element_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach.rs
new file mode 100644
index 0000000..ac527b5
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach.rs
@@ -0,0 +1,74 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void root(int *out, uint32_t x, uint32_t y) {
+ *out = x + y * dimX;
+}
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ _RS_ASSERT(*in == (x + y * dimX));
+ *out = 99 + x + y * dimX;
+ _RS_ASSERT(*out == (99 + x + y * dimX));
+}
+
+static bool test_root_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_root_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_root_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+static bool test_foo_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void foreach_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach_bounds.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach_bounds.rs
new file mode 100644
index 0000000..ddf17f8
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/foreach_bounds.rs
@@ -0,0 +1,71 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+int xStart = 0;
+int xEnd = 0;
+int yStart = 0;
+int yEnd = 0;
+
+rs_script s;
+rs_allocation ain;
+rs_allocation aout;
+
+void root(int *out, uint32_t x, uint32_t y) {
+ *out = x + y * dimX;
+}
+
+int __attribute__((kernel)) zero() {
+ return 0;
+}
+
+static bool test_root_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ rsDebug("i: ", i);
+ rsDebug("j: ", j);
+ rsDebug("a[j][i]: ", a[i + j * dimX]);
+ if (i < xStart || i >= xEnd || j < yStart || j >= yEnd) {
+ _RS_ASSERT(a[i + j * dimX] == 0);
+ } else {
+ _RS_ASSERT(a[i + j * dimX] == (i + j * dimX));
+ }
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_root_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_root_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void foreach_bounds_test() {
+ static bool failed = false;
+
+ rs_script_call_t rssc = {0};
+ rssc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
+ rssc.xStart = xStart;
+ rssc.xEnd = xEnd;
+ rssc.yStart = yStart;
+ rssc.yEnd = yEnd;
+
+ rsForEach(s, ain, aout, NULL, 0, &rssc);
+
+ failed |= test_root_output();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/fp_mad.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/fp_mad.rs
new file mode 100644
index 0000000..b6f2b2a6
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/fp_mad.rs
@@ -0,0 +1,174 @@
+#include "shared.rsh"
+
+const int TEST_COUNT = 1;
+
+static float data_f1[1025];
+static float4 data_f4[1025];
+
+static void test_mad4(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~1 billion ops
+ for (int ct=0; ct < 1000 * (1000 / 80); ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f4[i] = (data_f4[i] * 0.02f +
+ data_f4[i+1] * 0.04f +
+ data_f4[i+2] * 0.05f +
+ data_f4[i+3] * 0.1f +
+ data_f4[i+4] * 0.2f +
+ data_f4[i+5] * 0.2f +
+ data_f4[i+6] * 0.1f +
+ data_f4[i+7] * 0.05f +
+ data_f4[i+8] * 0.04f +
+ data_f4[i+9] * 0.02f + 1.f);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_mad4 M ops", 1000.f / time);
+}
+
+static void test_mad(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~1 billion ops
+ for (int ct=0; ct < 1000 * (1000 / 20); ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f1[i] = (data_f1[i] * 0.02f +
+ data_f1[i+1] * 0.04f +
+ data_f1[i+2] * 0.05f +
+ data_f1[i+3] * 0.1f +
+ data_f1[i+4] * 0.2f +
+ data_f1[i+5] * 0.2f +
+ data_f1[i+6] * 0.1f +
+ data_f1[i+7] * 0.05f +
+ data_f1[i+8] * 0.04f +
+ data_f1[i+9] * 0.02f + 1.f);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_mad M ops", 1000.f / time);
+}
+
+static void test_norm(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~10 M ops
+ for (int ct=0; ct < 1000 * 10; ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f4[i] = normalize(data_f4[i]);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_norm M ops", 10.f / time);
+}
+
+static void test_sincos4(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~10 M ops
+ for (int ct=0; ct < 1000 * 10 / 4; ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f4[i] = sin(data_f4[i]) * cos(data_f4[i]);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_sincos4 M ops", 10.f / time);
+}
+
+static void test_sincos(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~10 M ops
+ for (int ct=0; ct < 1000 * 10; ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f1[i] = sin(data_f1[i]) * cos(data_f1[i]);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_sincos M ops", 10.f / time);
+}
+
+static void test_clamp(uint32_t index) {
+ start();
+
+ // Do ~100 M ops
+ for (int ct=0; ct < 1000 * 100; ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_clamp M ops", 100.f / time);
+
+ start();
+ // Do ~100 M ops
+ for (int ct=0; ct < 1000 * 100; ct++) {
+ for (int i=0; i < (1000); i++) {
+ if (data_f1[i] < -1.f) data_f1[i] = -1.f;
+ if (data_f1[i] > -1.f) data_f1[i] = 1.f;
+ }
+ }
+
+ time = end(index);
+ rsDebug("fp_clamp ref M ops", 100.f / time);
+}
+
+static void test_clamp4(uint32_t index) {
+ start();
+
+ float total = 0;
+ // Do ~100 M ops
+ for (int ct=0; ct < 1000 * 100 /4; ct++) {
+ for (int i=0; i < (1000); i++) {
+ data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
+ }
+ }
+
+ float time = end(index);
+ rsDebug("fp_clamp4 M ops", 100.f / time);
+}
+
+void fp_mad_test(uint32_t index, int test_num) {
+ int x;
+ for (x=0; x < 1025; x++) {
+ data_f1[x] = (x & 0xf) * 0.1f;
+ data_f4[x].x = (x & 0xf) * 0.1f;
+ data_f4[x].y = (x & 0xf0) * 0.1f;
+ data_f4[x].z = (x & 0x33) * 0.1f;
+ data_f4[x].w = (x & 0x77) * 0.1f;
+ }
+
+ test_mad4(index);
+ test_mad(index);
+
+ for (x=0; x < 1025; x++) {
+ data_f1[x] = (x & 0xf) * 0.1f + 1.f;
+ data_f4[x].x = (x & 0xf) * 0.1f + 1.f;
+ data_f4[x].y = (x & 0xf0) * 0.1f + 1.f;
+ data_f4[x].z = (x & 0x33) * 0.1f + 1.f;
+ data_f4[x].w = (x & 0x77) * 0.1f + 1.f;
+ }
+
+ test_norm(index);
+ test_sincos4(index);
+ test_sincos(index);
+ test_clamp4(index);
+ test_clamp(index);
+
+ // TODO Actually verify test result accuracy
+ rsDebug("fp_mad_test PASSED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+}
+
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/int4.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/int4.rs
new file mode 100644
index 0000000..c791cab
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/int4.rs
@@ -0,0 +1,29 @@
+#include "shared.rsh"
+#pragma rs_fp_relaxed
+
+uchar4 u4 = 4;
+int4 gi4 = {2, 2, 2, 2};
+
+void int4_test() {
+ bool failed = false;
+ int4 i4 = {u4.x, u4.y, u4.z, u4.w};
+ i4 *= gi4;
+
+ rsDebug("i4.x", i4.x);
+ rsDebug("i4.y", i4.y);
+ rsDebug("i4.z", i4.z);
+ rsDebug("i4.w", i4.w);
+
+ _RS_ASSERT(i4.x == 8);
+ _RS_ASSERT(i4.y == 8);
+ _RS_ASSERT(i4.z == 8);
+ _RS_ASSERT(i4.w == 8);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel.rs
new file mode 100644
index 0000000..d6c9df3
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel.rs
@@ -0,0 +1,47 @@
+#include "shared.rsh"
+
+int *ain;
+int *aout;
+int dimX;
+static bool failed = false;
+
+void init_vars(int *out) {
+ *out = 7;
+}
+
+
+int __attribute__((kernel)) root(int ain, uint32_t x) {
+ _RS_ASSERT(ain == 7);
+ return ain + x;
+}
+
+static bool test_root_output() {
+ bool failed = false;
+ int i;
+
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(aout[i] == (i + ain[i]));
+ }
+
+ if (failed) {
+ rsDebug("test_root_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_root_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void kernel_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel_struct.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel_struct.rs
new file mode 100644
index 0000000..62c30ae
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/kernel_struct.rs
@@ -0,0 +1,66 @@
+#include "shared.rsh"
+
+struct simpleStruct {
+ int i1;
+ char ignored1;
+ float f1;
+ int i2;
+ char ignored2;
+ float f2;
+};
+
+struct simpleStruct *ain;
+struct simpleStruct *aout;
+int dimX;
+static bool failed = false;
+
+void init_vars(struct simpleStruct *out, uint32_t x) {
+ out->i1 = 0;
+ out->f1 = 0.f;
+ out->i2 = 1;
+ out->f2 = 1.0f;
+}
+
+struct simpleStruct __attribute__((kernel))
+ root(struct simpleStruct in, uint32_t x) {
+ struct simpleStruct s;
+ s.i1 = in.i1 + x;
+ s.f1 = in.f1 + x;
+ s.i2 = in.i2 + x;
+ s.f2 = in.f2 + x;
+ return s;
+}
+
+static bool test_root_output() {
+ bool failed = false;
+ int i;
+
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(aout[i].i1 == (i + ain[i].i1));
+ _RS_ASSERT(aout[i].f1 == (i + ain[i].f1));
+ _RS_ASSERT(aout[i].i2 == (i + ain[i].i2));
+ _RS_ASSERT(aout[i].f2 == (i + ain[i].f2));
+ }
+
+ if (failed) {
+ rsDebug("test_root_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_root_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void kernel_struct_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math.rs
new file mode 100644
index 0000000..aae29a4
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math.rs
@@ -0,0 +1,436 @@
+#include "shared.rsh"
+
+// Testing math library
+
+volatile float f1;
+volatile float2 f2;
+volatile float3 f3;
+volatile float4 f4;
+
+volatile int i1;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
+
+volatile uint ui1;
+volatile uint2 ui2;
+volatile uint3 ui3;
+volatile uint4 ui4;
+
+volatile short s1;
+volatile short2 s2;
+volatile short3 s3;
+volatile short4 s4;
+
+volatile ushort us1;
+volatile ushort2 us2;
+volatile ushort3 us3;
+volatile ushort4 us4;
+
+volatile char c1;
+volatile char2 c2;
+volatile char3 c3;
+volatile char4 c4;
+
+volatile uchar uc1;
+volatile uchar2 uc2;
+volatile uchar3 uc3;
+volatile uchar4 uc4;
+
+#define DECL_INT(prefix) \
+volatile char prefix##_c_1 = 1; \
+volatile char2 prefix##_c_2 = 1; \
+volatile char3 prefix##_c_3 = 1; \
+volatile char4 prefix##_c_4 = 1; \
+volatile uchar prefix##_uc_1 = 1; \
+volatile uchar2 prefix##_uc_2 = 1; \
+volatile uchar3 prefix##_uc_3 = 1; \
+volatile uchar4 prefix##_uc_4 = 1; \
+volatile short prefix##_s_1 = 1; \
+volatile short2 prefix##_s_2 = 1; \
+volatile short3 prefix##_s_3 = 1; \
+volatile short4 prefix##_s_4 = 1; \
+volatile ushort prefix##_us_1 = 1; \
+volatile ushort2 prefix##_us_2 = 1; \
+volatile ushort3 prefix##_us_3 = 1; \
+volatile ushort4 prefix##_us_4 = 1; \
+volatile int prefix##_i_1 = 1; \
+volatile int2 prefix##_i_2 = 1; \
+volatile int3 prefix##_i_3 = 1; \
+volatile int4 prefix##_i_4 = 1; \
+volatile uint prefix##_ui_1 = 1; \
+volatile uint2 prefix##_ui_2 = 1; \
+volatile uint3 prefix##_ui_3 = 1; \
+volatile uint4 prefix##_ui_4 = 1; \
+volatile long prefix##_l_1 = 1; \
+volatile ulong prefix##_ul_1 = 1;
+
+DECL_INT(res)
+DECL_INT(src1)
+DECL_INT(src2)
+
+#define TEST_INT_OP_TYPE(op, type) \
+rsDebug("Testing " #op " for " #type "1", i++); \
+res_##type##_1 = src1_##type##_1 op src2_##type##_1; \
+rsDebug("Testing " #op " for " #type "2", i++); \
+res_##type##_2 = src1_##type##_2 op src2_##type##_2; \
+rsDebug("Testing " #op " for " #type "3", i++); \
+res_##type##_3 = src1_##type##_3 op src2_##type##_3; \
+rsDebug("Testing " #op " for " #type "4", i++); \
+res_##type##_4 = src1_##type##_4 op src2_##type##_4;
+
+#define TEST_INT_OP(op) \
+TEST_INT_OP_TYPE(op, c) \
+TEST_INT_OP_TYPE(op, uc) \
+TEST_INT_OP_TYPE(op, s) \
+TEST_INT_OP_TYPE(op, us) \
+TEST_INT_OP_TYPE(op, i) \
+TEST_INT_OP_TYPE(op, ui) \
+rsDebug("Testing " #op " for l1", i++); \
+res_l_1 = src1_l_1 op src2_l_1; \
+rsDebug("Testing " #op " for ul1", i++); \
+res_ul_1 = src1_ul_1 op src2_ul_1;
+
+#define TEST_XN_FUNC_YN(typeout, fnc, typein) \
+ res_##typeout##_1 = fnc(src1_##typein##_1); \
+ res_##typeout##_2 = fnc(src1_##typein##_2); \
+ res_##typeout##_3 = fnc(src1_##typein##_3); \
+ res_##typeout##_4 = fnc(src1_##typein##_4);
+
+#define TEST_XN_FUNC_XN_XN(type, fnc) \
+ res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \
+ res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \
+ res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \
+ res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4);
+
+#define TEST_X_FUNC_X_X_X(type, fnc) \
+ res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1);
+
+#define TEST_IN_FUNC_IN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ TEST_XN_FUNC_YN(uc, fnc, uc) \
+ TEST_XN_FUNC_YN(c, fnc, c) \
+ TEST_XN_FUNC_YN(us, fnc, us) \
+ TEST_XN_FUNC_YN(s, fnc, s) \
+ TEST_XN_FUNC_YN(ui, fnc, ui) \
+ TEST_XN_FUNC_YN(i, fnc, i)
+
+#define TEST_UIN_FUNC_IN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ TEST_XN_FUNC_YN(uc, fnc, c) \
+ TEST_XN_FUNC_YN(us, fnc, s) \
+ TEST_XN_FUNC_YN(ui, fnc, i) \
+
+#define TEST_IN_FUNC_IN_IN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ TEST_XN_FUNC_XN_XN(uc, fnc) \
+ TEST_XN_FUNC_XN_XN(c, fnc) \
+ TEST_XN_FUNC_XN_XN(us, fnc) \
+ TEST_XN_FUNC_XN_XN(s, fnc) \
+ TEST_XN_FUNC_XN_XN(ui, fnc) \
+ TEST_XN_FUNC_XN_XN(i, fnc)
+
+#define TEST_I_FUNC_I_I_I(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ TEST_X_FUNC_X_X_X(uc, fnc) \
+ TEST_X_FUNC_X_X_X(c, fnc) \
+ TEST_X_FUNC_X_X_X(us, fnc) \
+ TEST_X_FUNC_X_X_X(s, fnc) \
+ TEST_X_FUNC_X_X_X(ui, fnc) \
+ TEST_X_FUNC_X_X_X(i, fnc)
+
+#define TEST_FN_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1); \
+ f2 = fnc(f2); \
+ f3 = fnc(f3); \
+ f4 = fnc(f4);
+
+#define TEST_FN_FUNC_FN_PFN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, (float*) &f1); \
+ f2 = fnc(f2, (float2*) &f2); \
+ f3 = fnc(f3, (float3*) &f3); \
+ f4 = fnc(f4, (float4*) &f4);
+
+#define TEST_FN_FUNC_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f2); \
+ f3 = fnc(f3, f3); \
+ f4 = fnc(f4, f4);
+
+#define TEST_F34_FUNC_F34_F34(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f3 = fnc(f3, f3); \
+ f4 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_F(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f1); \
+ f3 = fnc(f3, f1); \
+ f4 = fnc(f4, f1);
+
+#define TEST_F_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1); \
+ f1 = fnc(f2); \
+ f1 = fnc(f3); \
+ f1 = fnc(f4);
+
+#define TEST_F_FUNC_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f1 = fnc(f2, f2); \
+ f1 = fnc(f3, f3); \
+ f1 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_IN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i2); \
+ f3 = fnc(f3, i3); \
+ f4 = fnc(f4, i4);
+
+#define TEST_FN_FUNC_FN_I(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i1); \
+ f3 = fnc(f3, i1); \
+ f4 = fnc(f4, i1);
+
+#define TEST_FN_FUNC_FN_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, f1); \
+ f2 = fnc(f2, f2, f2); \
+ f3 = fnc(f3, f3, f3); \
+ f4 = fnc(f4, f4, f4);
+
+#define TEST_FN_FUNC_FN_FN_F(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, f1); \
+ f2 = fnc(f2, f1, f1); \
+ f3 = fnc(f3, f1, f1); \
+ f4 = fnc(f4, f1, f1);
+
+#define TEST_FN_FUNC_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, (int*) &i1); \
+ f2 = fnc(f2, (int2*) &i2); \
+ f3 = fnc(f3, (int3*) &i3); \
+ f4 = fnc(f4, (int4*) &i4);
+
+#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, (int*) &i1); \
+ f2 = fnc(f2, f2, (int2*) &i2); \
+ f3 = fnc(f3, f3, (int3*) &i3); \
+ f4 = fnc(f4, f4, (int4*) &i4);
+
+#define TEST_IN_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ i1 = fnc(f1); \
+ i2 = fnc(f2); \
+ i3 = fnc(f3); \
+ i4 = fnc(f4);
+
+static bool test_fp_math(uint32_t index) {
+ bool failed = false;
+ start();
+
+ TEST_FN_FUNC_FN(acos);
+ TEST_FN_FUNC_FN(acosh);
+ TEST_FN_FUNC_FN(acospi);
+ TEST_FN_FUNC_FN(asin);
+ TEST_FN_FUNC_FN(asinh);
+ TEST_FN_FUNC_FN(asinpi);
+ TEST_FN_FUNC_FN(atan);
+ TEST_FN_FUNC_FN_FN(atan2);
+ TEST_FN_FUNC_FN(atanh);
+ TEST_FN_FUNC_FN(atanpi);
+ TEST_FN_FUNC_FN_FN(atan2pi);
+ TEST_FN_FUNC_FN(cbrt);
+ TEST_FN_FUNC_FN(ceil);
+ TEST_FN_FUNC_FN_FN_FN(clamp);
+ TEST_FN_FUNC_FN_FN_F(clamp);
+ TEST_FN_FUNC_FN_FN(copysign);
+ TEST_FN_FUNC_FN(cos);
+ TEST_FN_FUNC_FN(cosh);
+ TEST_FN_FUNC_FN(cospi);
+ TEST_F34_FUNC_F34_F34(cross);
+ TEST_FN_FUNC_FN(degrees);
+ TEST_F_FUNC_FN_FN(distance);
+ TEST_F_FUNC_FN_FN(dot);
+ TEST_FN_FUNC_FN(erfc);
+ TEST_FN_FUNC_FN(erf);
+ TEST_FN_FUNC_FN(exp);
+ TEST_FN_FUNC_FN(exp2);
+ TEST_FN_FUNC_FN(exp10);
+ TEST_FN_FUNC_FN(expm1);
+ TEST_FN_FUNC_FN(fabs);
+ TEST_FN_FUNC_FN_FN(fdim);
+ TEST_FN_FUNC_FN(floor);
+ TEST_FN_FUNC_FN_FN_FN(fma);
+ TEST_FN_FUNC_FN_FN(fmax);
+ TEST_FN_FUNC_FN_F(fmax);
+ TEST_FN_FUNC_FN_FN(fmin);
+ TEST_FN_FUNC_FN_F(fmin);
+ TEST_FN_FUNC_FN_FN(fmod);
+ TEST_FN_FUNC_FN_PFN(fract);
+ TEST_FN_FUNC_FN_PIN(frexp);
+ TEST_FN_FUNC_FN_FN(hypot);
+ TEST_IN_FUNC_FN(ilogb);
+ TEST_FN_FUNC_FN_IN(ldexp);
+ TEST_FN_FUNC_FN_I(ldexp);
+ TEST_F_FUNC_FN(length);
+ TEST_FN_FUNC_FN(lgamma);
+ TEST_FN_FUNC_FN_PIN(lgamma);
+ TEST_FN_FUNC_FN(log);
+ TEST_FN_FUNC_FN(log2);
+ TEST_FN_FUNC_FN(log10);
+ TEST_FN_FUNC_FN(log1p);
+ TEST_FN_FUNC_FN(logb);
+ TEST_FN_FUNC_FN_FN_FN(mad);
+ TEST_FN_FUNC_FN_FN(max);
+ TEST_FN_FUNC_FN_F(max);
+ TEST_FN_FUNC_FN_FN(min);
+ TEST_FN_FUNC_FN_F(min);
+ TEST_FN_FUNC_FN_FN_FN(mix);
+ TEST_FN_FUNC_FN_FN_F(mix);
+ TEST_FN_FUNC_FN_PFN(modf);
+ // nan
+ TEST_FN_FUNC_FN_FN(nextafter);
+ TEST_FN_FUNC_FN(normalize);
+ TEST_FN_FUNC_FN_FN(pow);
+ TEST_FN_FUNC_FN_IN(pown);
+ TEST_FN_FUNC_FN_FN(powr);
+ TEST_FN_FUNC_FN(radians);
+ TEST_FN_FUNC_FN_FN(remainder);
+ TEST_FN_FUNC_FN_FN_PIN(remquo);
+ TEST_FN_FUNC_FN(rint);
+ TEST_FN_FUNC_FN_IN(rootn);
+ TEST_FN_FUNC_FN(round);
+ TEST_FN_FUNC_FN(rsqrt);
+ TEST_FN_FUNC_FN(sign);
+ TEST_FN_FUNC_FN(sin);
+ TEST_FN_FUNC_FN_PFN(sincos);
+ TEST_FN_FUNC_FN(sinh);
+ TEST_FN_FUNC_FN(sinpi);
+ TEST_FN_FUNC_FN(sqrt);
+ TEST_FN_FUNC_FN_FN(step);
+ TEST_FN_FUNC_FN_F(step);
+ TEST_FN_FUNC_FN(tan);
+ TEST_FN_FUNC_FN(tanh);
+ TEST_FN_FUNC_FN(tanpi);
+ TEST_FN_FUNC_FN(tgamma);
+ TEST_FN_FUNC_FN(trunc);
+
+ float time = end(index);
+
+ if (failed) {
+ rsDebug("test_fp_math FAILED", time);
+ }
+ else {
+ rsDebug("test_fp_math PASSED", time);
+ }
+
+ return failed;
+}
+
+static bool test_int_math(uint32_t index) {
+ bool failed = false;
+ start();
+
+ TEST_UIN_FUNC_IN(abs);
+ TEST_IN_FUNC_IN(clz);
+ TEST_IN_FUNC_IN_IN(min);
+ TEST_IN_FUNC_IN_IN(max);
+ TEST_I_FUNC_I_I_I(rsClamp);
+
+ float time = end(index);
+
+ if (failed) {
+ rsDebug("test_int_math FAILED", time);
+ }
+ else {
+ rsDebug("test_int_math PASSED", time);
+ }
+
+ return failed;
+}
+
+static bool test_basic_operators() {
+ bool failed = false;
+ int i = 0;
+
+ TEST_INT_OP(+);
+ TEST_INT_OP(-);
+ TEST_INT_OP(*);
+ TEST_INT_OP(/);
+ TEST_INT_OP(%);
+ TEST_INT_OP(<<);
+ TEST_INT_OP(>>);
+
+ if (failed) {
+ rsDebug("test_basic_operators FAILED", 0);
+ }
+ else {
+ rsDebug("test_basic_operators PASSED", 0);
+ }
+
+ return failed;
+}
+
+#define TEST_CVT(to, from, type) \
+rsDebug("Testing convert from " #from " to " #to, 0); \
+to##1 = from##1; \
+to##2 = convert_##type##2(from##2); \
+to##3 = convert_##type##3(from##3); \
+to##4 = convert_##type##4(from##4);
+
+#define TEST_CVT_MATRIX(to, type) \
+TEST_CVT(to, c, type); \
+TEST_CVT(to, uc, type); \
+TEST_CVT(to, s, type); \
+TEST_CVT(to, us, type); \
+TEST_CVT(to, i, type); \
+TEST_CVT(to, ui, type); \
+TEST_CVT(to, f, type); \
+
+static bool test_convert() {
+ bool failed = false;
+
+ TEST_CVT_MATRIX(c, char);
+ TEST_CVT_MATRIX(uc, uchar);
+ TEST_CVT_MATRIX(s, short);
+ TEST_CVT_MATRIX(us, ushort);
+ TEST_CVT_MATRIX(i, int);
+ TEST_CVT_MATRIX(ui, uint);
+ TEST_CVT_MATRIX(f, float);
+
+ if (failed) {
+ rsDebug("test_convert FAILED", 0);
+ }
+ else {
+ rsDebug("test_convert PASSED", 0);
+ }
+
+ return failed;
+}
+
+void math_test(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= test_convert();
+ failed |= test_fp_math(index);
+ failed |= test_int_math(index);
+ failed |= test_basic_operators();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_agree.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_agree.rs
new file mode 100644
index 0000000..5bfbb2b
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_agree.rs
@@ -0,0 +1,409 @@
+#include "shared.rsh"
+//#pragma rs_fp_relaxed
+
+volatile float x = 0.0f;
+volatile float y = 0.0f;
+volatile float result_add = 0.0f;
+volatile float result_sub = 0.0f;
+volatile float result_mul = 0.0f;
+volatile float result_div = 0.0f;
+
+#define DECLARE_INPUT_SET(type, abbrev) \
+volatile type rand_##abbrev##1_0, rand_##abbrev##1_1; \
+volatile type##2 rand_##abbrev##2_0, rand_##abbrev##2_1; \
+volatile type##3 rand_##abbrev##3_0, rand_##abbrev##3_1; \
+volatile type##4 rand_##abbrev##4_0, rand_##abbrev##4_1;
+
+#define DECLARE_ALL_INPUT_SETS() \
+DECLARE_INPUT_SET(float, f); \
+DECLARE_INPUT_SET(char, sc); \
+DECLARE_INPUT_SET(uchar, uc); \
+DECLARE_INPUT_SET(short, ss); \
+DECLARE_INPUT_SET(ushort, us); \
+DECLARE_INPUT_SET(int, si); \
+DECLARE_INPUT_SET(uint, ui); \
+DECLARE_INPUT_SET(long, sl); \
+DECLARE_INPUT_SET(ulong, ul);
+
+DECLARE_ALL_INPUT_SETS();
+
+#define DECLARE_REFERENCE_SET_VEC_VEC(type, abbrev, func) \
+volatile type func##_rand_##abbrev##1_##abbrev##1; \
+volatile type##2 func##_rand_##abbrev##2_##abbrev##2; \
+volatile type##3 func##_rand_##abbrev##3_##abbrev##3; \
+volatile type##4 func##_rand_##abbrev##4_##abbrev##4;
+#define DECLARE_REFERENCE_SET_VEC_SCL(type, abbrev, func) \
+volatile type##2 func##_rand_##abbrev##2_##abbrev##1; \
+volatile type##3 func##_rand_##abbrev##3_##abbrev##1; \
+volatile type##4 func##_rand_##abbrev##4_##abbrev##1;
+
+#define DECLARE_ALL_REFERENCE_SETS_VEC_VEC(func) \
+DECLARE_REFERENCE_SET_VEC_VEC(float, f, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(char, sc, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(uchar, uc, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(short, ss, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(ushort, us, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(int, si, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(uint, ui, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(long, sl, func); \
+DECLARE_REFERENCE_SET_VEC_VEC(ulong, ul, func);
+
+DECLARE_ALL_REFERENCE_SETS_VEC_VEC(min);
+DECLARE_ALL_REFERENCE_SETS_VEC_VEC(max);
+DECLARE_REFERENCE_SET_VEC_VEC(float, f, fmin);
+DECLARE_REFERENCE_SET_VEC_SCL(float, f, fmin);
+DECLARE_REFERENCE_SET_VEC_VEC(float, f, fmax);
+DECLARE_REFERENCE_SET_VEC_SCL(float, f, fmax);
+
+static void fail_f1(float v1, float v2, float actual, float expected, char *op_name) {
+ int dist = float_dist(actual, expected);
+ rsDebug("float operation did not match!", op_name);
+ rsDebug("v1", v1);
+ rsDebug("v2", v2);
+ rsDebug("Dalvik result", expected);
+ rsDebug("Renderscript result", actual);
+ rsDebug("ULP difference", dist);
+}
+
+static void fail_f2(float2 v1, float2 v2, float2 actual, float2 expected, char *op_name) {
+ int2 dist;
+ dist.x = float_dist(actual.x, expected.x);
+ dist.y = float_dist(actual.y, expected.y);
+ rsDebug("float2 operation did not match!", op_name);
+ rsDebug("v1.x", v1.x);
+ rsDebug("v1.y", v1.y);
+ rsDebug("v2.x", v2.x);
+ rsDebug("v2.y", v2.y);
+ rsDebug("Dalvik result .x", expected.x);
+ rsDebug("Dalvik result .y", expected.y);
+ rsDebug("Renderscript result .x", actual.x);
+ rsDebug("Renderscript result .y", actual.y);
+ rsDebug("ULP difference .x", dist.x);
+ rsDebug("ULP difference .y", dist.y);
+}
+
+static void fail_f3(float3 v1, float3 v2, float3 actual, float3 expected, char *op_name) {
+ int3 dist;
+ dist.x = float_dist(actual.x, expected.x);
+ dist.y = float_dist(actual.y, expected.y);
+ dist.z = float_dist(actual.z, expected.z);
+ rsDebug("float3 operation did not match!", op_name);
+ rsDebug("v1.x", v1.x);
+ rsDebug("v1.y", v1.y);
+ rsDebug("v1.z", v1.z);
+ rsDebug("v2.x", v2.x);
+ rsDebug("v2.y", v2.y);
+ rsDebug("v2.z", v2.z);
+ rsDebug("Dalvik result .x", expected.x);
+ rsDebug("Dalvik result .y", expected.y);
+ rsDebug("Dalvik result .z", expected.z);
+ rsDebug("Renderscript result .x", actual.x);
+ rsDebug("Renderscript result .y", actual.y);
+ rsDebug("Renderscript result .z", actual.z);
+ rsDebug("ULP difference .x", dist.x);
+ rsDebug("ULP difference .y", dist.y);
+ rsDebug("ULP difference .z", dist.z);
+}
+
+static void fail_f4(float4 v1, float4 v2, float4 actual, float4 expected, char *op_name) {
+ int4 dist;
+ dist.x = float_dist(actual.x, expected.x);
+ dist.y = float_dist(actual.y, expected.y);
+ dist.z = float_dist(actual.z, expected.z);
+ dist.w = float_dist(actual.w, expected.w);
+ rsDebug("float4 operation did not match!", op_name);
+ rsDebug("v1.x", v1.x);
+ rsDebug("v1.y", v1.y);
+ rsDebug("v1.z", v1.z);
+ rsDebug("v1.w", v1.w);
+ rsDebug("v2.x", v2.x);
+ rsDebug("v2.y", v2.y);
+ rsDebug("v2.z", v2.z);
+ rsDebug("v2.w", v2.w);
+ rsDebug("Dalvik result .x", expected.x);
+ rsDebug("Dalvik result .y", expected.y);
+ rsDebug("Dalvik result .z", expected.z);
+ rsDebug("Dalvik result .w", expected.w);
+ rsDebug("Renderscript result .x", actual.x);
+ rsDebug("Renderscript result .y", actual.y);
+ rsDebug("Renderscript result .z", actual.z);
+ rsDebug("Renderscript result .w", actual.w);
+ rsDebug("ULP difference .x", dist.x);
+ rsDebug("ULP difference .y", dist.y);
+ rsDebug("ULP difference .z", dist.z);
+ rsDebug("ULP difference .w", dist.w);
+}
+
+static bool f1_almost_equal(float a, float b) {
+ return float_almost_equal(a, b);
+}
+
+static bool f2_almost_equal(float2 a, float2 b) {
+ return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y);
+}
+
+
+static bool f3_almost_equal(float3 a, float3 b) {
+ return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y)
+ && float_almost_equal(a.z, b.z);
+}
+
+static bool f4_almost_equal(float4 a, float4 b) {
+ return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y)
+ && float_almost_equal(a.z, b.z) && float_almost_equal(a.w, b.w);
+}
+
+#define TEST_BASIC_FLOAT_OP(op, opName) \
+temp_f1 = x op y; \
+if (! float_almost_equal(temp_f1, result_##opName)) { \
+ fail_f1(x, y , temp_f1, result_##opName, #opName); \
+ failed = true; \
+}
+
+#define TEST_FN_FN(func, size) \
+temp_f##size = func(rand_f##size##_0, rand_f##size##_1); \
+if (! f##size##_almost_equal(temp_f##size , func##_rand_f##size##_f##size)) { \
+ fail_f##size (x, y , temp_f##size, func##_rand_f##size##_f##size, #func); \
+ failed = true; \
+}
+#define TEST_FN_F(func, size) \
+temp_f##size = func(rand_f##size##_0, rand_f1_1); \
+if (! f##size##_almost_equal(temp_f##size , func##_rand_f##size##_f1)) { \
+ fail_f##size (x, y , temp_f##size, func##_rand_f##size##_f1 , #func); \
+ failed = true; \
+}
+
+#define TEST_FN_FN_ALL(func) \
+TEST_FN_FN(func, 1) \
+TEST_FN_FN(func, 2) \
+TEST_FN_FN(func, 3) \
+TEST_FN_FN(func, 4)
+#define TEST_FN_F_ALL(func) \
+TEST_FN_F(func, 2) \
+TEST_FN_F(func, 3) \
+TEST_FN_F(func, 4)
+
+#define TEST_VEC1_VEC1(func, type) \
+temp_##type##1 = func( rand_##type##1_0, rand_##type##1_1 ); \
+if (temp_##type##1 != func##_rand_##type##1_##type##1) { \
+ rsDebug(#func " " #type "1 operation did not match!", 0); \
+ rsDebug("v1", rand_##type##1_0); \
+ rsDebug("v2", rand_##type##1_1); \
+ rsDebug("Dalvik result", func##_rand_##type##1_##type##1); \
+ rsDebug("Renderscript result", temp_##type##1); \
+ failed = true; \
+}
+#define TEST_VEC2_VEC2(func, type) \
+temp_##type##2 = func( rand_##type##2_0, rand_##type##2_1 ); \
+if (temp_##type##2 .x != func##_rand_##type##2_##type##2 .x \
+ || temp_##type##2 .y != func##_rand_##type##2_##type##2 .y) { \
+ rsDebug(#func " " #type "2 operation did not match!", 0); \
+ rsDebug("v1.x", rand_##type##2_0 .x); \
+ rsDebug("v1.y", rand_##type##2_0 .y); \
+ rsDebug("v2.x", rand_##type##2_1 .x); \
+ rsDebug("v2.y", rand_##type##2_1 .y); \
+ rsDebug("Dalvik result .x", func##_rand_##type##2_##type##2 .x); \
+ rsDebug("Dalvik result .y", func##_rand_##type##2_##type##2 .y); \
+ rsDebug("Renderscript result .x", temp_##type##2 .x); \
+ rsDebug("Renderscript result .y", temp_##type##2 .y); \
+ failed = true; \
+}
+#define TEST_VEC3_VEC3(func, type) \
+temp_##type##3 = func( rand_##type##3_0, rand_##type##3_1 ); \
+if (temp_##type##3 .x != func##_rand_##type##3_##type##3 .x \
+ || temp_##type##3 .y != func##_rand_##type##3_##type##3 .y \
+ || temp_##type##3 .z != func##_rand_##type##3_##type##3 .z) { \
+ rsDebug(#func " " #type "3 operation did not match!", 0); \
+ rsDebug("v1.x", rand_##type##3_0 .x); \
+ rsDebug("v1.y", rand_##type##3_0 .y); \
+ rsDebug("v1.z", rand_##type##3_0 .z); \
+ rsDebug("v2.x", rand_##type##3_1 .x); \
+ rsDebug("v2.y", rand_##type##3_1 .y); \
+ rsDebug("v2.z", rand_##type##3_1 .z); \
+ rsDebug("Dalvik result .x", func##_rand_##type##3_##type##3 .x); \
+ rsDebug("Dalvik result .y", func##_rand_##type##3_##type##3 .y); \
+ rsDebug("Dalvik result .z", func##_rand_##type##3_##type##3 .z); \
+ rsDebug("Renderscript result .x", temp_##type##3 .x); \
+ rsDebug("Renderscript result .y", temp_##type##3 .y); \
+ rsDebug("Renderscript result .z", temp_##type##3 .z); \
+ failed = true; \
+}
+#define TEST_VEC4_VEC4(func, type) \
+temp_##type##4 = func( rand_##type##4_0, rand_##type##4_1 ); \
+if (temp_##type##4 .x != func##_rand_##type##4_##type##4 .x \
+ || temp_##type##4 .y != func##_rand_##type##4_##type##4 .y \
+ || temp_##type##4 .z != func##_rand_##type##4_##type##4 .z \
+ || temp_##type##4 .w != func##_rand_##type##4_##type##4 .w) { \
+ rsDebug(#func " " #type "4 operation did not match!", 0); \
+ rsDebug("v1.x", rand_##type##4_0 .x); \
+ rsDebug("v1.y", rand_##type##4_0 .y); \
+ rsDebug("v1.z", rand_##type##4_0 .z); \
+ rsDebug("v1.w", rand_##type##4_0 .w); \
+ rsDebug("v2.x", rand_##type##4_1 .x); \
+ rsDebug("v2.y", rand_##type##4_1 .y); \
+ rsDebug("v2.z", rand_##type##4_1 .z); \
+ rsDebug("v2.w", rand_##type##4_1 .w); \
+ rsDebug("Dalvik result .x", func##_rand_##type##4_##type##4 .x); \
+ rsDebug("Dalvik result .y", func##_rand_##type##4_##type##4 .y); \
+ rsDebug("Dalvik result .z", func##_rand_##type##4_##type##4 .z); \
+ rsDebug("Dalvik result .w", func##_rand_##type##4_##type##4 .w); \
+ rsDebug("Renderscript result .x", temp_##type##4 .x); \
+ rsDebug("Renderscript result .y", temp_##type##4 .y); \
+ rsDebug("Renderscript result .z", temp_##type##4 .z); \
+ rsDebug("Renderscript result .w", temp_##type##4 .w); \
+ failed = true; \
+}
+
+#define TEST_SC1_SC1(func) TEST_VEC1_VEC1(func, sc)
+#define TEST_SC2_SC2(func) TEST_VEC2_VEC2(func, sc)
+#define TEST_SC3_SC3(func) TEST_VEC3_VEC3(func, sc)
+#define TEST_SC4_SC4(func) TEST_VEC4_VEC4(func, sc)
+
+#define TEST_UC1_UC1(func) TEST_VEC1_VEC1(func, uc)
+#define TEST_UC2_UC2(func) TEST_VEC2_VEC2(func, uc)
+#define TEST_UC3_UC3(func) TEST_VEC3_VEC3(func, uc)
+#define TEST_UC4_UC4(func) TEST_VEC4_VEC4(func, uc)
+
+#define TEST_SS1_SS1(func) TEST_VEC1_VEC1(func, ss)
+#define TEST_SS2_SS2(func) TEST_VEC2_VEC2(func, ss)
+#define TEST_SS3_SS3(func) TEST_VEC3_VEC3(func, ss)
+#define TEST_SS4_SS4(func) TEST_VEC4_VEC4(func, ss)
+
+#define TEST_US1_US1(func) TEST_VEC1_VEC1(func, us)
+#define TEST_US2_US2(func) TEST_VEC2_VEC2(func, us)
+#define TEST_US3_US3(func) TEST_VEC3_VEC3(func, us)
+#define TEST_US4_US4(func) TEST_VEC4_VEC4(func, us)
+
+#define TEST_SI1_SI1(func) TEST_VEC1_VEC1(func, si)
+#define TEST_SI2_SI2(func) TEST_VEC2_VEC2(func, si)
+#define TEST_SI3_SI3(func) TEST_VEC3_VEC3(func, si)
+#define TEST_SI4_SI4(func) TEST_VEC4_VEC4(func, si)
+
+#define TEST_UI1_UI1(func) TEST_VEC1_VEC1(func, ui)
+#define TEST_UI2_UI2(func) TEST_VEC2_VEC2(func, ui)
+#define TEST_UI3_UI3(func) TEST_VEC3_VEC3(func, ui)
+#define TEST_UI4_UI4(func) TEST_VEC4_VEC4(func, ui)
+
+#define TEST_SL1_SL1(func) TEST_VEC1_VEC1(func, sl)
+#define TEST_SL2_SL2(func) TEST_VEC2_VEC2(func, sl)
+#define TEST_SL3_SL3(func) TEST_VEC3_VEC3(func, sl)
+#define TEST_SL4_SL4(func) TEST_VEC4_VEC4(func, sl)
+
+#define TEST_UL1_UL1(func) TEST_VEC1_VEC1(func, ul)
+#define TEST_UL2_UL2(func) TEST_VEC2_VEC2(func, ul)
+#define TEST_UL3_UL3(func) TEST_VEC3_VEC3(func, ul)
+#define TEST_UL4_UL4(func) TEST_VEC4_VEC4(func, ul)
+
+#define TEST_SC_SC_ALL(func) \
+TEST_SC1_SC1(func) \
+TEST_SC2_SC2(func) \
+TEST_SC3_SC3(func) \
+TEST_SC4_SC4(func)
+#define TEST_UC_UC_ALL(func) \
+TEST_UC1_UC1(func) \
+TEST_UC2_UC2(func) \
+TEST_UC3_UC3(func) \
+TEST_UC4_UC4(func)
+
+#define TEST_SS_SS_ALL(func) \
+TEST_SS1_SS1(func) \
+TEST_SS2_SS2(func) \
+TEST_SS3_SS3(func) \
+TEST_SS4_SS4(func)
+#define TEST_US_US_ALL(func) \
+TEST_US1_US1(func) \
+TEST_US2_US2(func) \
+TEST_US3_US3(func) \
+TEST_US4_US4(func)
+#define TEST_SI_SI_ALL(func) \
+TEST_SI1_SI1(func) \
+TEST_SI2_SI2(func) \
+TEST_SI3_SI3(func) \
+TEST_SI4_SI4(func)
+#define TEST_UI_UI_ALL(func) \
+TEST_UI1_UI1(func) \
+TEST_UI2_UI2(func) \
+TEST_UI3_UI3(func) \
+TEST_UI4_UI4(func)
+#define TEST_SL_SL_ALL(func) \
+TEST_SL1_SL1(func) \
+TEST_SL2_SL2(func) \
+TEST_SL3_SL3(func) \
+TEST_SL4_SL4(func)
+#define TEST_UL_UL_ALL(func) \
+TEST_UL1_UL1(func) \
+TEST_UL2_UL2(func) \
+TEST_UL3_UL3(func) \
+TEST_UL4_UL4(func)
+
+#define TEST_VEC_VEC_ALL(func) \
+TEST_FN_FN_ALL(func) \
+TEST_SC_SC_ALL(func) \
+TEST_UC_UC_ALL(func) \
+TEST_SS_SS_ALL(func) \
+TEST_US_US_ALL(func) \
+TEST_SI_SI_ALL(func) \
+TEST_UI_UI_ALL(func)
+
+// TODO: add long types to ALL macro
+#if 0
+TEST_SL_SL_ALL(func) \
+TEST_UL_UL_ALL(func)
+#endif
+
+#define DECLARE_TEMP_SET(type, abbrev) \
+volatile type temp_##abbrev##1; \
+volatile type##2 temp_##abbrev##2; \
+volatile type##3 temp_##abbrev##3; \
+volatile type##4 temp_##abbrev##4;
+
+#define DECLARE_ALL_TEMP_SETS() \
+DECLARE_TEMP_SET(float, f); \
+DECLARE_TEMP_SET(char, sc); \
+DECLARE_TEMP_SET(uchar, uc); \
+DECLARE_TEMP_SET(short, ss); \
+DECLARE_TEMP_SET(ushort, us); \
+DECLARE_TEMP_SET(int, si); \
+DECLARE_TEMP_SET(uint, ui); \
+DECLARE_TEMP_SET(long, sl); \
+DECLARE_TEMP_SET(ulong, ul);
+
+static bool test_math_agree() {
+ bool failed = false;
+
+ DECLARE_ALL_TEMP_SETS();
+
+ TEST_BASIC_FLOAT_OP(+, add);
+ TEST_BASIC_FLOAT_OP(-, sub);
+ TEST_BASIC_FLOAT_OP(*, mul);
+ TEST_BASIC_FLOAT_OP(/, div);
+
+ TEST_VEC_VEC_ALL(min);
+ TEST_VEC_VEC_ALL(max);
+ TEST_FN_FN_ALL(fmin);
+ TEST_FN_F_ALL(fmin);
+ TEST_FN_FN_ALL(fmax);
+ TEST_FN_F_ALL(fmax);
+
+ if (failed) {
+ rsDebug("test_math_agree FAILED", 0);
+ }
+ else {
+ rsDebug("test_math_agree PASSED", 0);
+ }
+
+ return failed;
+}
+
+void math_agree_test() {
+ bool failed = false;
+ failed |= test_math_agree();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_conformance.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_conformance.rs
new file mode 100644
index 0000000..2d62f34
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/math_conformance.rs
@@ -0,0 +1,57 @@
+#include "shared.rsh"
+
+// Testing math conformance
+
+static bool test_rootn() {
+ bool failed = false;
+
+ // rootn(x, 0) -> NaN
+ _RS_ASSERT(isnan(rootn(1.0f, 0)));
+
+ // rootn(+/-0, n) -> +/-inf for odd n < 0
+ _RS_ASSERT(isposinf(rootn(0.f, -3)));
+ _RS_ASSERT(isneginf(rootn(-0.f, -3)));
+
+ // rootn(+/-0, n) -> +inf for even n < 0
+ _RS_ASSERT(isposinf(rootn(0.f, -8)));
+ _RS_ASSERT(isposinf(rootn(-0.f, -8)));
+
+ // rootn(+/-0, n) -> +/-0 for odd n > 0
+ _RS_ASSERT(isposzero(rootn(0.f, 3)));
+ _RS_ASSERT(isnegzero(rootn(-0.f, 3)));
+
+ // rootn(+/-0, n) -> +0 for even n > 0
+ _RS_ASSERT(isposzero(rootn(0.f, 8)));
+ _RS_ASSERT(isposzero(rootn(-0.f, 8)));
+
+ // rootn(x, n) -> NaN for x < 0 and even n
+ _RS_ASSERT(isnan(rootn(-10000.f, -4)));
+ _RS_ASSERT(isnan(rootn(-10000.f, 4)));
+
+ // rootn(x, n) -> value for x < 0 and odd n
+ _RS_ASSERT(!isnan(rootn(-10000.f, -3)));
+ _RS_ASSERT(!isnan(rootn(-10000.f, 3)));
+
+ if (failed) {
+ rsDebug("test_rootn FAILED", -1);
+ }
+ else {
+ rsDebug("test_rootn PASSED", 0);
+ }
+
+ return failed;
+}
+
+void math_conformance_test() {
+ bool failed = false;
+ failed |= test_rootn();
+
+ if (failed) {
+ rsDebug("math_conformance_test FAILED", -1);
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsDebug("math_conformance_test PASSED", 0);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/min.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/min.rs
new file mode 100644
index 0000000..4b92763
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/min.rs
@@ -0,0 +1,20 @@
+#include "shared.rsh"
+#pragma rs_fp_relaxed
+
+volatile uchar2 res_uc_2 = 1;
+volatile uchar2 src1_uc_2 = 1;
+volatile uchar2 src2_uc_2 = 1;
+
+void min_test() {
+ bool failed = false;
+
+ res_uc_2 = min(src1_uc_2, src2_uc_2);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/noroot.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/noroot.rs
new file mode 100644
index 0000000..33944aa
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/noroot.rs
@@ -0,0 +1,44 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ *out = 99 + x + y * dimX;
+}
+
+static bool test_foo_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void noroot_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/primitives.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/primitives.rs
new file mode 100644
index 0000000..ce451da
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/primitives.rs
@@ -0,0 +1,61 @@
+#include "shared.rsh"
+
+// Testing primitive types
+float floatTest = 1.99f;
+double doubleTest = 2.05;
+char charTest = -8;
+short shortTest = -16;
+int intTest = -32;
+long longTest = 17179869184l; // 1 << 34
+long long longlongTest = 68719476736l; // 1 << 36
+
+uchar ucharTest = 8;
+ushort ushortTest = 16;
+uint uintTest = 32;
+ulong ulongTest = 4611686018427387904L;
+int64_t int64_tTest = -17179869184l; // - 1 << 34
+uint64_t uint64_tTest = 117179869184l;
+
+static bool test_primitive_types(uint32_t index) {
+ bool failed = false;
+ start();
+
+ _RS_ASSERT(floatTest == 2.99f);
+ _RS_ASSERT(doubleTest == 3.05);
+ _RS_ASSERT(charTest == -16);
+ _RS_ASSERT(shortTest == -32);
+ _RS_ASSERT(intTest == -64);
+ _RS_ASSERT(longTest == 17179869185l);
+ _RS_ASSERT(longlongTest == 68719476735l);
+
+ _RS_ASSERT(ucharTest == 8);
+ _RS_ASSERT(ushortTest == 16);
+ _RS_ASSERT(uintTest == 32);
+ _RS_ASSERT(ulongTest == 4611686018427387903L);
+ _RS_ASSERT(int64_tTest == -17179869184l);
+ _RS_ASSERT(uint64_tTest == 117179869185l);
+
+ float time = end(index);
+
+ if (failed) {
+ rsDebug("test_primitives FAILED", time);
+ }
+ else {
+ rsDebug("test_primitives PASSED", time);
+ }
+
+ return failed;
+}
+
+void primitives_test(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= test_primitive_types(index);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/refcount.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/refcount.rs
new file mode 100644
index 0000000..4ea70e2
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/refcount.rs
@@ -0,0 +1,13 @@
+#include "shared.rsh"
+
+// Testing reference counting of RS object types
+
+rs_allocation globalA;
+static rs_allocation staticGlobalA;
+
+void refcount_test() {
+ staticGlobalA = globalA;
+ rsClearObject(&globalA);
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rsdebug.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rsdebug.rs
new file mode 100644
index 0000000..68ac168
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rsdebug.rs
@@ -0,0 +1,62 @@
+#include "shared.rsh"
+
+// Testing primitive types
+float floatTest = 1.99f;
+float2 float2Test = {2.99f, 12.99f};
+float3 float3Test = {3.99f, 13.99f, 23.99f};
+float4 float4Test = {4.99f, 14.99f, 24.99f, 34.99f};
+double doubleTest = 2.05;
+char charTest = -8;
+short shortTest = -16;
+int intTest = -32;
+long longTest = 17179869184l; // 1 << 34
+long long longlongTest = 68719476736l; // 1 << 36
+
+uchar ucharTest = 8;
+ushort ushortTest = 16;
+uint uintTest = 32;
+ulong ulongTest = 4611686018427387904L;
+int64_t int64_tTest = -17179869184l; // - 1 << 34
+uint64_t uint64_tTest = 117179869184l;
+
+static bool basic_test(uint32_t index) {
+ bool failed = false;
+
+ // This test focuses primarily on compilation-time, not run-time.
+ // For this reason, none of the outputs are actually checked.
+
+ rsDebug("floatTest", floatTest);
+ rsDebug("float2Test", float2Test);
+ rsDebug("float3Test", float3Test);
+ rsDebug("float4Test", float4Test);
+ rsDebug("doubleTest", doubleTest);
+ rsDebug("charTest", charTest);
+ rsDebug("shortTest", shortTest);
+ rsDebug("intTest", intTest);
+ rsDebug("longTest", longTest);
+ rsDebug("longlongTest", longlongTest);
+
+ rsDebug("ucharTest", ucharTest);
+ rsDebug("ushortTest", ushortTest);
+ rsDebug("uintTest", uintTest);
+ rsDebug("ulongTest", ulongTest);
+ rsDebug("int64_tTest", int64_tTest);
+ rsDebug("uint64_tTest", uint64_tTest);
+
+ return failed;
+}
+
+void test_rsdebug(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= basic_test(index);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ rsDebug("rsdebug_test FAILED", -1);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ rsDebug("rsdebug_test PASSED", 0);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstime.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstime.rs
new file mode 100644
index 0000000..7be955d
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstime.rs
@@ -0,0 +1,52 @@
+#include "shared.rsh"
+
+static bool basic_test(uint32_t index) {
+ bool failed = false;
+
+ rs_time_t curTime = rsTime(0);
+ rs_tm tm;
+ rsDebug("curTime", curTime);
+
+ rsLocaltime(&tm, &curTime);
+
+ rsDebug("tm.tm_sec", tm.tm_sec);
+ rsDebug("tm.tm_min", tm.tm_min);
+ rsDebug("tm.tm_hour", tm.tm_hour);
+ rsDebug("tm.tm_mday", tm.tm_mday);
+ rsDebug("tm.tm_mon", tm.tm_mon);
+ rsDebug("tm.tm_year", tm.tm_year);
+ rsDebug("tm.tm_wday", tm.tm_wday);
+ rsDebug("tm.tm_yday", tm.tm_yday);
+ rsDebug("tm.tm_isdst", tm.tm_isdst);
+
+ // Test a specific time (since we set America/Los_Angeles localtime)
+ curTime = 1294438893;
+ rsLocaltime(&tm, &curTime);
+
+ _RS_ASSERT(tm.tm_sec == 33);
+ _RS_ASSERT(tm.tm_min == 21);
+ _RS_ASSERT(tm.tm_hour == 14);
+ _RS_ASSERT(tm.tm_mday == 7);
+ _RS_ASSERT(tm.tm_mon == 0);
+ _RS_ASSERT(tm.tm_year == 111);
+ _RS_ASSERT(tm.tm_wday == 5);
+ _RS_ASSERT(tm.tm_yday == 6);
+ _RS_ASSERT(tm.tm_isdst == 0);
+
+ return failed;
+}
+
+void test_rstime(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= basic_test(index);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ rsDebug("rstime_test FAILED", -1);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ rsDebug("rstime_test PASSED", 0);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstypes.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstypes.rs
new file mode 100644
index 0000000..bec124d
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/rstypes.rs
@@ -0,0 +1,61 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_element elementTest;
+rs_type typeTest;
+rs_allocation allocationTest;
+rs_sampler samplerTest;
+rs_script scriptTest;
+
+rs_matrix4x4 matrix4x4Test;
+rs_matrix3x3 matrix3x3Test;
+rs_matrix2x2 matrix2x2Test;
+
+struct my_struct {
+ int i;
+ rs_allocation banana;
+};
+
+static bool basic_test(uint32_t index) {
+ bool failed = false;
+
+ rs_matrix4x4 matrix4x4TestLocal;
+ rs_matrix3x3 matrix3x3TestLocal;
+ rs_matrix2x2 matrix2x2TestLocal;
+
+ // This test focuses primarily on compilation-time, not run-time.
+ rs_element elementTestLocal;
+ rs_type typeTestLocal;
+ rs_allocation allocationTestLocal;
+ rs_sampler samplerTestLocal;
+ rs_script scriptTestLocal;
+
+ struct my_struct structTest;
+
+ //allocationTestLocal = allocationTest;
+
+ //allocationTest = allocationTestLocal;
+
+ /*for (int i = 0; i < 4; i++) {
+ fontTestLocalArray[i] = fontTestLocal;
+ }*/
+
+ /*fontTest = fontTestLocalArray[3];*/
+
+ return failed;
+}
+
+void test_rstypes(uint32_t index, int test_num) {
+ bool failed = false;
+ failed |= basic_test(index);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ rsDebug("rstypes_test FAILED", -1);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ rsDebug("rstypes_test PASSED", 0);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/sampler.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/sampler.rs
new file mode 100644
index 0000000..ff1c0a7
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/sampler.rs
@@ -0,0 +1,63 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+rs_sampler minification;
+rs_sampler magnification;
+rs_sampler wrapS;
+rs_sampler wrapT;
+rs_sampler anisotropy;
+
+static bool test_sampler_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsSamplerGetMagnification(minification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetMinification(minification) == RS_SAMPLER_LINEAR_MIP_LINEAR);
+ _RS_ASSERT(rsSamplerGetWrapS(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetWrapT(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetAnisotropy(minification) == 1.0f);
+
+ _RS_ASSERT(rsSamplerGetMagnification(magnification) == RS_SAMPLER_LINEAR);
+ _RS_ASSERT(rsSamplerGetMinification(magnification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetWrapS(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetWrapT(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetAnisotropy(magnification) == 1.0f);
+
+ _RS_ASSERT(rsSamplerGetMagnification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetMinification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetWrapS(wrapS) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsSamplerGetWrapT(wrapS) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetAnisotropy(wrapS) == 1.0f);
+
+ _RS_ASSERT(rsSamplerGetMagnification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetMinification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetWrapS(wrapT) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetWrapT(wrapT) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsSamplerGetAnisotropy(wrapT) == 1.0f);
+
+ _RS_ASSERT(rsSamplerGetMagnification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetMinification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsSamplerGetWrapS(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetWrapT(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsSamplerGetAnisotropy(anisotropy) == 8.0f);
+
+ if (failed) {
+ rsDebug("test_sampler_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_sampler_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void sampler_test() {
+ bool failed = false;
+ failed |= test_sampler_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/shared.rsh
new file mode 100644
index 0000000..3adc999
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/shared.rsh
@@ -0,0 +1,114 @@
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.test)
+
+typedef struct TestResult_s {
+ rs_allocation name;
+ bool pass;
+ float score;
+ int64_t time;
+} TestResult;
+//TestResult *g_results;
+
+static int64_t g_time;
+
+static void start(void) {
+ g_time = rsUptimeMillis();
+}
+
+static float end(uint32_t idx) {
+ int64_t t = rsUptimeMillis() - g_time;
+ //g_results[idx].time = t;
+ //rsDebug("test time", (int)t);
+ return ((float)t) / 1000.f;
+}
+
+#define _RS_ASSERT(b) \
+do { \
+ if (!(b)) { \
+ failed = true; \
+ rsDebug(#b " FAILED", 0); \
+ } \
+\
+} while (0)
+
+static const int iposinf = 0x7f800000;
+static const int ineginf = 0xff800000;
+
+static const float posinf() {
+ float f = *((float*)&iposinf);
+ return f;
+}
+
+static const float neginf() {
+ float f = *((float*)&ineginf);
+ return f;
+}
+
+static bool isposinf(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == iposinf);
+}
+
+static bool isneginf(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == ineginf);
+}
+
+static bool isnan(float f) {
+ int i = *((int*)(void*)&f);
+ return (((i & 0x7f800000) == 0x7f800000) && (i & 0x007fffff));
+}
+
+static bool isposzero(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == 0x00000000);
+}
+
+static bool isnegzero(float f) {
+ int i = *((int*)(void*)&f);
+ return (i == 0x80000000);
+}
+
+static bool iszero(float f) {
+ return isposzero(f) || isnegzero(f);
+}
+
+/* Absolute epsilon used for floats. Value is similar to float.h. */
+#ifndef FLT_EPSILON
+#define FLT_EPSILON 1.19e7f
+#endif
+/* Max ULPs while still being considered "equal". Only used when this number
+ of ULPs is of a greater size than FLT_EPSILON. */
+#define FLT_MAX_ULP 1
+
+/* Calculate the difference in ULPs between the two values. (Return zero on
+ perfect equality.) */
+static int float_dist(float f1, float f2) {
+ return *((int *)(&f1)) - *((int *)(&f2));
+}
+
+/* Check if two floats are essentially equal. Will fail with some values
+ due to design. (Validate using FLT_EPSILON or similar if necessary.) */
+static bool float_almost_equal(float f1, float f2) {
+ int *i1 = (int*)(&f1);
+ int *i2 = (int*)(&f2);
+
+ // Check for sign equality
+ if ( ((*i1 >> 31) == 0) != ((*i2 >> 31) == 0) ) {
+ // Handle signed zeroes
+ if (f1 == f2)
+ return true;
+ return false;
+ }
+
+ // Check with ULP distance
+ if (float_dist(f1, f2) > FLT_MAX_ULP)
+ return false;
+ return true;
+}
+
+/* These constants must match those in UnitTest.java */
+static const int RS_MSG_TEST_PASSED = 100;
+static const int RS_MSG_TEST_FAILED = 101;
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/struct.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/struct.rs
new file mode 100644
index 0000000..1cd728e
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/struct.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+
+typedef struct Point2 {
+ int x;
+ int y;
+} Point_2;
+Point_2 *point2;
+
+static bool test_Point_2(int expected) {
+ bool failed = false;
+
+ rsDebug("Point: ", point2[0].x, point2[0].y);
+ _RS_ASSERT(point2[0].x == expected);
+ _RS_ASSERT(point2[0].y == expected);
+
+ if (failed) {
+ rsDebug("test_Point_2 FAILED", 0);
+ }
+ else {
+ rsDebug("test_Point_2 PASSED", 0);
+ }
+
+ return failed;
+}
+
+void struct_test(int expected) {
+ bool failed = false;
+ failed |= test_Point_2(expected);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/test_root.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/test_root.rs
new file mode 100644
index 0000000..6dc83ba
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/test_root.rs
@@ -0,0 +1,23 @@
+// Fountain test script
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.rs.test)
+
+#pragma stateFragment(parent)
+
+#include "rs_graphics.rsh"
+
+
+typedef struct TestResult {
+ rs_allocation name;
+ bool pass;
+ float score;
+} TestResult_t;
+TestResult_t *results;
+
+int root() {
+
+ return 0;
+}
+
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/unsigned.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/unsigned.rs
new file mode 100644
index 0000000..2c056f4
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/unsigned.rs
@@ -0,0 +1,36 @@
+#include "shared.rsh"
+
+// Testing unsigned types for Bug 6764163
+unsigned int ui = 37;
+unsigned char uc = 5;
+
+static bool test_unsigned() {
+ bool failed = false;
+
+ rsDebug("ui", ui);
+ rsDebug("uc", uc);
+ _RS_ASSERT(ui == 0x7fffffff);
+ _RS_ASSERT(uc == 129);
+
+ if (failed) {
+ rsDebug("test_unsigned FAILED", -1);
+ }
+ else {
+ rsDebug("test_unsigned PASSED", 0);
+ }
+
+ return failed;
+}
+
+void unsigned_test() {
+ bool failed = false;
+ failed |= test_unsigned();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/vector.rs b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/vector.rs
new file mode 100644
index 0000000..0430a2f
--- /dev/null
+++ b/tests/RenderScriptTests/RSTest_CompatLib/src/com/android/rs/test/vector.rs
@@ -0,0 +1,198 @@
+#include "shared.rsh"
+
+// Testing vector types
+float2 f2 = { 1.0f, 2.0f };
+float3 f3 = { 1.0f, 2.0f, 3.0f };
+float4 f4 = { 1.0f, 2.0f, 3.0f, 4.0f };
+
+double2 d2 = { 1.0, 2.0 };
+double3 d3 = { 1.0, 2.0, 3.0 };
+double4 d4 = { 1.0, 2.0, 3.0, 4.0 };
+
+char2 i8_2 = { 1, 2 };
+char3 i8_3 = { 1, 2, 3 };
+char4 i8_4 = { 1, 2, 3, 4 };
+
+uchar2 u8_2 = { 1, 2 };
+uchar3 u8_3 = { 1, 2, 3 };
+uchar4 u8_4 = { 1, 2, 3, 4 };
+
+short2 i16_2 = { 1, 2 };
+short3 i16_3 = { 1, 2, 3 };
+short4 i16_4 = { 1, 2, 3, 4 };
+
+ushort2 u16_2 = { 1, 2 };
+ushort3 u16_3 = { 1, 2, 3 };
+ushort4 u16_4 = { 1, 2, 3, 4 };
+
+int2 i32_2 = { 1, 2 };
+int3 i32_3 = { 1, 2, 3 };
+int4 i32_4 = { 1, 2, 3, 4 };
+
+uint2 u32_2 = { 1, 2 };
+uint3 u32_3 = { 1, 2, 3 };
+uint4 u32_4 = { 1, 2, 3, 4 };
+
+long2 i64_2 = { 1, 2 };
+long3 i64_3 = { 1, 2, 3 };
+long4 i64_4 = { 1, 2, 3, 4 };
+
+ulong2 u64_2 = { 1, 2 };
+ulong3 u64_3 = { 1, 2, 3 };
+ulong4 u64_4 = { 1, 2, 3, 4 };
+
+static bool test_vector_types() {
+ bool failed = false;
+
+ rsDebug("Testing F32", 0);
+ _RS_ASSERT(f2.x == 2.99f);
+ _RS_ASSERT(f2.y == 3.99f);
+
+ _RS_ASSERT(f3.x == 2.99f);
+ _RS_ASSERT(f3.y == 3.99f);
+ _RS_ASSERT(f3.z == 4.99f);
+
+ _RS_ASSERT(f4.x == 2.99f);
+ _RS_ASSERT(f4.y == 3.99f);
+ _RS_ASSERT(f4.z == 4.99f);
+ _RS_ASSERT(f4.w == 5.99f);
+
+ rsDebug("Testing F64", 0);
+ _RS_ASSERT(d2.x == 2.99);
+ _RS_ASSERT(d2.y == 3.99);
+
+ _RS_ASSERT(d3.x == 2.99);
+ _RS_ASSERT(d3.y == 3.99);
+ _RS_ASSERT(d3.z == 4.99);
+
+ _RS_ASSERT(d4.x == 2.99);
+ _RS_ASSERT(d4.y == 3.99);
+ _RS_ASSERT(d4.z == 4.99);
+ _RS_ASSERT(d4.w == 5.99);
+
+ rsDebug("Testing I8", 0);
+ _RS_ASSERT(i8_2.x == 2);
+ _RS_ASSERT(i8_2.y == 3);
+
+ _RS_ASSERT(i8_3.x == 2);
+ _RS_ASSERT(i8_3.y == 3);
+ _RS_ASSERT(i8_3.z == 4);
+
+ _RS_ASSERT(i8_4.x == 2);
+ _RS_ASSERT(i8_4.y == 3);
+ _RS_ASSERT(i8_4.z == 4);
+ _RS_ASSERT(i8_4.w == 5);
+
+ rsDebug("Testing U8", 0);
+ _RS_ASSERT(u8_2.x == 2);
+ _RS_ASSERT(u8_2.y == 3);
+
+ _RS_ASSERT(u8_3.x == 2);
+ _RS_ASSERT(u8_3.y == 3);
+ _RS_ASSERT(u8_3.z == 4);
+
+ _RS_ASSERT(u8_4.x == 2);
+ _RS_ASSERT(u8_4.y == 3);
+ _RS_ASSERT(u8_4.z == 4);
+ _RS_ASSERT(u8_4.w == 5);
+
+ rsDebug("Testing I16", 0);
+ _RS_ASSERT(i16_2.x == 2);
+ _RS_ASSERT(i16_2.y == 3);
+
+ _RS_ASSERT(i16_3.x == 2);
+ _RS_ASSERT(i16_3.y == 3);
+ _RS_ASSERT(i16_3.z == 4);
+
+ _RS_ASSERT(i16_4.x == 2);
+ _RS_ASSERT(i16_4.y == 3);
+ _RS_ASSERT(i16_4.z == 4);
+ _RS_ASSERT(i16_4.w == 5);
+
+ rsDebug("Testing U16", 0);
+ _RS_ASSERT(u16_2.x == 2);
+ _RS_ASSERT(u16_2.y == 3);
+
+ _RS_ASSERT(u16_3.x == 2);
+ _RS_ASSERT(u16_3.y == 3);
+ _RS_ASSERT(u16_3.z == 4);
+
+ _RS_ASSERT(u16_4.x == 2);
+ _RS_ASSERT(u16_4.y == 3);
+ _RS_ASSERT(u16_4.z == 4);
+ _RS_ASSERT(u16_4.w == 5);
+
+ rsDebug("Testing I32", 0);
+ _RS_ASSERT(i32_2.x == 2);
+ _RS_ASSERT(i32_2.y == 3);
+
+ _RS_ASSERT(i32_3.x == 2);
+ _RS_ASSERT(i32_3.y == 3);
+ _RS_ASSERT(i32_3.z == 4);
+
+ _RS_ASSERT(i32_4.x == 2);
+ _RS_ASSERT(i32_4.y == 3);
+ _RS_ASSERT(i32_4.z == 4);
+ _RS_ASSERT(i32_4.w == 5);
+
+ rsDebug("Testing U32", 0);
+ _RS_ASSERT(u32_2.x == 2);
+ _RS_ASSERT(u32_2.y == 3);
+
+ _RS_ASSERT(u32_3.x == 2);
+ _RS_ASSERT(u32_3.y == 3);
+ _RS_ASSERT(u32_3.z == 4);
+
+ _RS_ASSERT(u32_4.x == 2);
+ _RS_ASSERT(u32_4.y == 3);
+ _RS_ASSERT(u32_4.z == 4);
+ _RS_ASSERT(u32_4.w == 5);
+
+ rsDebug("Testing I64", 0);
+ _RS_ASSERT(i64_2.x == 2);
+ _RS_ASSERT(i64_2.y == 3);
+
+ _RS_ASSERT(i64_3.x == 2);
+ _RS_ASSERT(i64_3.y == 3);
+ _RS_ASSERT(i64_3.z == 4);
+
+ _RS_ASSERT(i64_4.x == 2);
+ _RS_ASSERT(i64_4.y == 3);
+ _RS_ASSERT(i64_4.z == 4);
+ _RS_ASSERT(i64_4.w == 5);
+
+ rsDebug("Testing U64", 0);
+ _RS_ASSERT(u64_2.x == 2);
+ _RS_ASSERT(u64_2.y == 3);
+
+ _RS_ASSERT(u64_3.x == 2);
+ _RS_ASSERT(u64_3.y == 3);
+ _RS_ASSERT(u64_3.z == 4);
+
+ _RS_ASSERT(u64_4.x == 2);
+ _RS_ASSERT(u64_4.y == 3);
+ _RS_ASSERT(u64_4.z == 4);
+ _RS_ASSERT(u64_4.w == 5);
+
+ if (failed) {
+ rsDebug("test_vector FAILED", 0);
+ }
+ else {
+ rsDebug("test_vector PASSED", 0);
+ }
+
+ return failed;
+}
+
+void vector_test() {
+ bool failed = false;
+ failed |= test_vector_types();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
index aae29a4..edde9d8 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
@@ -278,6 +278,7 @@
TEST_FN_FUNC_FN_F(fmin);
TEST_FN_FUNC_FN_FN(fmod);
TEST_FN_FUNC_FN_PFN(fract);
+ TEST_FN_FUNC_FN(fract);
TEST_FN_FUNC_FN_PIN(frexp);
TEST_FN_FUNC_FN_FN(hypot);
TEST_IN_FUNC_FN(ilogb);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index e2fced6..e682da7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1080,6 +1080,12 @@
}
@Override
+ public String getBasePackageName() {
+ // pass
+ return null;
+ }
+
+ @Override
public ApplicationInfo getApplicationInfo() {
return mApplicationInfo;
}